傳統的基於協同過濾的推薦系統在實時性方面的弊端
面對具有大規模高維稀疏矩陣特征的用戶-項目歷史評分矩陣,傳統的單純的基於協同過濾的推薦系統存在計算量大,擴展性不強,推薦效率低等問題,嚴重影響實時推薦系統的實現,因此本文嘗試在現有基於協同過濾的推薦系統上,引入局部敏感哈希(Local-Sensitive-Hashing, LSH)對其進行改進,局部敏感哈希基於隨機映射機制將高維空間的數據降維,並原空間中距離較近的兩個點在映射后距離仍以極大概率保持接近。這種相似性不是精確保證的,但在實際應用中能夠很大程度滿足實現的需求。
局部敏感哈希
核心思想
局部敏感哈希的核心思想是選擇一種可以將原空間中相似對象以極高概率映射或投影到同一桶中的哈希函數,通過這種映射,大量極大概率不相近的個體被過濾掉,因此在求近鄰用戶群時無需遍歷整個數據集,降低了相似性計算的代價。由於局部敏感哈希本身是一種基於概率的模型,因此在實現時通常會創建多個哈希表,並在求近似近鄰數據集時以所有哈希表返回結果的並集作為最終結果。實踐證明,局部敏感哈希在數據規模與維度較大的稀疏矩陣下具有良好的相似性檢索性能。此外,后文中還將提及,在多方參與的基於協同過濾的推薦系統中,暴露局部敏感哈希生成的索引本身是相對安全的,因為降維后的數據並不直接泄露數據隱私。其主要思想可以通過下圖表示:
數學定義
局部敏感哈希的嚴格定義如下:設某度量空間RdRd下的哈希函數族HH,該函數族是RdRd中點域SS到某個集合域DD的一組哈希函數,任選哈希函數hihi對RdRd內數據點aa和bb進行哈希,若其滿足:
- 若|a−b|≤r1|a−b|≤r1,則Prob[hi(a)=hi(b)]≥p1Prob[hi(a)=hi(b)]≥p1;
- 若|a−b|≥r1|a−b|≥r1,則Prob[hi(a)=hi(b)]≤p2Prob[hi(a)=hi(b)]≤p2。
其中Prob[⋅]Prob[⋅]為概率函數,0<r1≤r20<r1≤r2,0≤p1<p2≤10≤p1<p2≤1,則此哈希函數族稱為(r1,r2,p1,p2)(r1,r2,p1,p2)-位置敏感哈希函數族。
任一用戶-項目評分向量經過位置敏感哈希函數映射到對應桶中,則同一桶中的其他向量組成的集合可被視為近似近鄰目標群。由於局部敏感哈希本身是一種基於概率的模型,因此在實現時通常會創建多個哈希表,因此需要將多個哈希表中的與目標用戶-項目評分向量處於同一統中的全部其他向量取並集作為最終的近似近鄰目標群。
實現方式
在與基於協同過濾的推薦系統相結合的具體實現中,推薦過程分為3個部分:其一,離線建立用戶索引,此過程即對用戶-項目歷史評分矩陣中的每一個用戶或項目向量進行哈希映射,存入哈希表;其二,在線查找相似用戶,此過程即將被推薦的目標向量以相同的哈希函數映射入每個哈希表的某一桶,並將同一桶中的其他向量取出取並集作為近似近鄰目標群;其三,推薦,此過程即以得到的近似近鄰目標群為數據集,運行協同過濾推薦算法,得到推薦結果。由於最終的推薦僅需遍歷得到的近似近鄰目標群,而此群體容量通常比整個數據集的容量小若干個數量級,因此可以極大的提升推薦的實時性。
離線建立索引
具體到局部敏感哈希離線建立索引過程中的哈希函數的選擇,需要基於前文中對於局部敏感哈希函數的定義,並且與所使用的相似度度量方式有關。本文實現使用的是運用較為廣泛的皮爾遜相關系數,因此給出皮爾遜相關系數對應的局部敏感哈希函數事項方式。
以基於用戶的協同過濾推薦系統為例,一個用戶的歷史評分向量可以表示為一個nn維向量u→=(u1,u2,…,un)u→=(u1,u2,…,un),其中uiui為用戶對第ii個項目的評分,此時新建隨機nn維向量v→=(v1,v2,…,vn)v→=(v1,v2,…,vn),其中vnvn為[−1,1][−1,1]內的隨機數。設哈希函數族H=(h1,h2,…,hm)H=(h1,h2,…,hm),其中hihi為:
通過一個哈希函數族HH內的一個哈希函數hihi和一個隨機向量v→v→,一個nn維用戶-項目歷史評分向量被映射為一個二進制值0或1。將哈希函數族內的mm個哈希函數(同一哈希算法對應不同的隨機向量v→v→)按照以上方式應用於用戶-項目歷史評分向量,則可以得到一個mm維二進制向量,即我們通過以上局部敏感哈希操作,將nn維用戶-項目歷史評分向量映射為一個mm維二進制向量(或其表示的整數值),而映射結果相同的原始用戶-項目歷史評分向量有極大可能性相似。如前文所述,由於局部敏感哈希本身是一種基於概率的模型,因此在實現時通常會創建多個哈希表,但每個哈希表的實現方式都是相同的,只是采用隨機向量不同。
偽代碼實現
若用MM表示原始用戶-項目歷史評分矩陣,tt表示建立哈希表數量,則建立離線索引的過程可以用以下Python偽代碼表示:
users_size, items_size = M.shape hashtables = [[[]] for _ in range(int('1' * m) + 1)] for _ in range(t)] random_matrixes = [np.empty((m, item_size)) for _ in range(t)] for i, user_vec in enumerate(M): for j in range(t): v = random_matrixes[i, j] = np.random.uniform(m, items_size, (-1, 1)) index = '' for k in range(m): index += '1' if user_vec.dot(v[k]) > 0 else '0' hashtables[j].append(i)
在線查找相似用戶
在在線查找相似用戶時,不再需要遍歷整個數據集,依次求得全部相似度並排序,而是直接計算其在每個哈希表中對應的桶編號,並將這些桶中的所有用戶-項目歷史評分向量取出作為目標用戶的近似近鄰用戶群。僅需遍歷此近似近鄰用戶群,依次求得與目標的相似度后排序,即可得到真實的“K-最近鄰”用戶群,參與后續的協同過濾推薦計算。
偽代碼實現
若用targetvectargetvec表示待推薦的目標用戶-項目歷史評分向量,此在線查找相似用戶的過程可以用以下Python偽代碼表示為:
sililar_users = set() for i, hashtable in enumerate(hashtables): index = '' for j in range(m): index += '1' if target_vec.dot(random_matrixes[i, j]) > 0 else '0' index = int(index, 2) sililar_users |= hashtable(index)
實驗及分析
運用相似敏感哈希技術改進的基於協同過濾的推薦系統在一定程度上解決了推薦的實時性差的弊端,提高了查找效率,滿足了快速相應的需求,接下來,我們討論如何在保證數據隱私安全的情況下,允許多方共同參與協同過濾推薦,減小基於協同過濾的推薦系統在數據集大小方面的限制。
實驗結果使用基於以下實驗環境:
CPU | RAM | OS | LANG |
---|---|---|---|
i7-4720HQ | 16GB DDR3 | Arch Linux(with Kenel 4.16.8-1) | Python 3.6.5 |
數據集使用MovieLens,該數據集收集了700個用戶對9000部電影的評分記錄。推薦結果質量評估標准使用平均絕對誤差(Mean Absolute Error, MAE),其值越小,代表推薦結果越准確。若用p→p→表示對用戶預測的評分向量中的用戶已有歷史記錄,u→u→表示用戶產生的真實評分向量,tt表示向量長度,則MAEMAE可以表示為:
下表為使用局部敏感哈希改進后的協同過濾推薦系統在不同數據集容量情況下的8次推薦計算過程中平均話費時間對比,單位為微秒,以及平均絕對誤差對比:
Size of Dataset | Time Using LSH(ms) | Time NOT Using LSH(ms) | MAE Using LSH | MAE NOT Using LSH |
---|---|---|---|---|
37 | 334.91176471 | 2804.61764706 | 0.41670966 | 0.31702144 |
74 | 421.44117647 | 5173.89705882 | 0.30188026 | 0.19453976 |
111 | 547.01470588 | 7727.47058824 | 0.2932903 | 0.19527124 |
148 | 624.27941176 | 10202.52941176 | 0.31379263 | 0.19609297 |
185 | 707.44117647 | 12621.91176471 | 0.30687005 | 0.19651358 |
222 | 752. | 15062.51470588 | 0.28993342 | 0.19611309 |
259 | 813.85294118 | 17499.91176471 | 0.28989946 | 0.19616549 |
296 | 891.94117647 | 20082.41176471 | 0.27720024 | 0.1962684 |
333 | 941.32352941 | 22265.94117647 | 0.27661047 | 0.19624015 |
370 | 1010.01470588 | 24715.38235294 | 0.25593213 | 0.15414695 |
407 | 1048.77941176 | 27198.45588235 | 0.26337683 | 0.1539606 |
444 | 1118.32352941 | 29728.79411765 | 0.25759909 | 0.15398098 |
481 | 1210.32352941 | 32366.79411765 | 0.23178155 | 0.15373239 |
518 | 1255.95588235 | 34337.86764706 | 0.23679564 | 0.15389964 |
555 | 1378.19117647 | 37129.05882353 | 0.24840943 | 0.15402475 |
592 | 1425.47058824 | 39571.48529412 | 0.17902636 | 0.1 |
或如下圖:
根據實驗結果可以看出,在使用局部敏感哈希改進基於協同過濾的推薦系統后,計算效率得到了非常顯著的提升,同時推薦質量也沒有因此受到較大的影響。
基於局部敏感哈希的隱私保護
局部敏感哈希不僅能夠避免不必要的計算,提升推薦結果計算效率,同樣可以作為多方參與的基於協同過濾的推薦系統中的一種數據隱私保護方式。降維后的用戶評分數據向量索引本身不包含且不可逆推用戶的實際打分,因此若以最簡單的方式考慮,則可以提出一種僅基於局部敏感哈希的允許多方參與的基於協同過濾的推薦系統實現,即當請求計算推薦結果的目標用戶到達時,根據哈希函數計算出其索引值,並將索引值發送給參與方,參與方依據此索引分別從所有哈希表中取出所有近似近鄰元素,計算其非零評分平均值作為結果返回至請求方,請求方拿到結果后與基於自身的運算結果合並,求出最終結果。
這種方式實現起來非常簡單,本文不再展開敘述,其傳輸過程也僅涉及索引值,安全性能夠保證。但同樣也可以看出,這種實現方式不考慮向量間相似度大小的具體差異,其推薦結果的准確度相對較低。為了實現明確相似度的度量以及以此為基礎的協同過濾推薦系統,下一篇文章考慮引入同態加密。