用戶的購買行爲很容易能夠用二分圖(二部圖)來表示。而且利用圖的算法進行推薦。基於鄰域的模型也能夠成爲基於圖的模型,由於基於鄰域的模型都是基於圖的模型的簡單狀況。咱們能夠用二元組\((u,i)\)來表示用戶\(u\)對物品\(i\)有過購買行爲,這樣的話數據集能夠用一個二分圖來表示。我這裏嘗試畫一個二分圖(有點醜,不要介意哈):python
左邊是用戶節點,右邊是物品節點。連線表明用戶對物品有過購買行爲。算法
咱們把個性化推薦算法放在二分圖當中,給用戶推薦物品就轉變成了度量用戶節點和商品節點的相關性,相關性越高的物品在推薦列表當中的權重就越大。通常來講頂點相關性取決於三個方面:學習
相關性高的一對頂點通常具備以下特徵:spa
基於上面3個主要因素,研究人員設計了不少計算圖中頂點之間相關性的方法。下一節將介紹一種基於隨機遊走的PersonalRank算法。設計
假設要給用戶\(u\)進行個性化推薦,能夠從用戶\(u\)對應的節點\(v_u\)開始在用戶物品二分圖上進行隨機遊走。遊走到任何一個節點時,首先按照機率\(\alpha\)決定是繼續遊走,仍是中止此次遊走並從\(v_u\)節點開始從新遊走。若是決定繼續遊走,那麼就從當前節點指向的節點中按照均勻分佈隨機選擇一個節點做爲遊走下次通過的節點。這樣,通過不少次隨機遊走後,每一個物品節點被訪問到的機率會收斂到一個數。最終的推薦列表中物品的權重就是物品節點的訪問機率。code
用代碼來表示:視頻
def PersonalRank(G, alpha, root): rank = dict() rank = {x:0 for x in G.keys()} rank[root] = 1 for k in range(20): tmp = {x:0 for x in G.keys()} for i, ri in G.items(): for j, wij in ri.items(): if j not in tmp: tmp[j] = 0 tmp[j] += 0.6 * rank[i] / (1.0 * len(ri)) if j == root: tmp[j] += 1 - alpha rank = tmp return rank
雖然PersonalRank算法能夠經過隨機遊走進行比較好的理論解釋,但該算法在時間複雜度上有明顯的缺點。由於在爲每一個用戶進行推薦時,都須要在整個用戶物品二分圖上進行迭代,直到整個圖上的每一個頂點的PR值收斂。這一過程的時間複雜度很是高,不只沒法在線提供實時推薦,甚至離線生成推薦結果也很耗時。爲了解決PersonalRank每次都須要在全圖迭代並所以形成時間複雜度很高的問題,這裏給出 兩種解決方案。第一種很容易想到,就是減小迭代次數,在收斂以前就中止。這樣會影響最終的 精度,但通常來講影響不會特別大。另外一種方法就是從矩陣論出發,從新設計算法。深度學習
咱們將PR算法設計成矩陣的形式,令\(M\)爲二分圖的轉移機率矩陣,即it
那麼迭代公式修改成:io
咱們解一下這個方程
這裏的\((1-\alpha M^T)\)是稀疏矩陣,對其快速求逆便可。
最近這兩天出去過節了,斷更了幾天,我又開始繼續更新這個系列了。這個系列後續可能就比較快的更新完,再說一個好消息,更新完這個系列以後,王喆編著的《深度學習推薦系統》以及相關的實踐課程視頻我也買了,將繼續更新《深度學習推薦系統》以及實踐視頻課的讀書筆記,你們能夠關注一下,敬請期待。