CF演算法簡介及實現
cf演算法全稱“Collaborative Filtering”,即協同過濾演算法。協同過濾演算法是非常強大與成熟(古老)的一套演算法。它廣泛應用於電子商務系統等領域。 協同過濾演算法的出現標誌著推薦系統的產生。
協同過濾簡單來說是利用某興趣相投、擁有共同經驗之群體的喜好來推薦使用者感興趣的資訊,個人通過合作的機制給予資訊相當程度的迴應(如評分)並記錄下來以達到過濾的目的進而幫助別人篩選資訊。
關於協同過濾的一個最經典的例子就是看電影,有時候不知道哪一部電影是我們喜歡的或者評分比較高的,那麼通常的做法就是問問周圍的朋友,看看最近有什麼好的電影推薦。在問的時候,都習慣於問跟自己口味差不 多的朋友,這就是協同過濾的核心思想。
協同過濾演算法又分為基於使用者的協同過濾演算法和基於物品的協同過濾演算法。
協同過濾是在海量資料中挖掘出小部分與你品味類似的使用者,在協同過濾中,這些使用者成為鄰居,然後根據他們喜歡的東西組織成一個排序的目錄推薦給你。所以就有如下兩個核心問題:
(1)如何確定一個使用者是否與你有相似的品味?
(2)如何將鄰居們的喜好組織成一個排序目錄?
問題一:如何確定一個使用者是否與你有相似的品味
這個問題等同於如何計算使用者(物品)相似度。在深度學習的相似性度量中,大體有十一個引數。
在CF演算法中,使用Jaccard係數、皮爾遜相關係數、歐幾里得距離和餘弦距離。在這裡,我選擇的是餘弦距離來度量使用者之間的相似度。
餘弦係數計算公式如下:
其實這個公式程式碼實現起來並不難,難的是能將上圖中的矩陣求出來。
這個矩陣對應的是每一個user的向量同時也對應著每一個item的向量。通過user的向量之間餘弦的計算,我們就可以度量出user之間的相似度了。
理解User-CF典型的就是我想看電影的時候,一定是找我身邊和我相似的人來推薦,我們就是一個相似的群體。
理解Item-CF典型的就是啤酒尿布,在內部兩個沒有關聯關係,但是在使用者行為上它們的餘弦值就非常大(相似度非常高)。
同時,Item-CF也可以通過Item本身內部的屬性出一個多維的向量值,即他們內部的關聯關係,就比如《推薦系統實現》、《演算法導論》兩本書在內部就有很大的相似性。當用戶買《推薦系統實現》這本書的時候,我們可以也有理由去推薦《演算法導論》。如果完全根據使用者行為維度來描述item,就可能出現我買《演算法導論》的時候,會給我推薦《男人裝》(隨便舉的例子)之類的。這有可能引起使用者的極度反感。
問題二:如何將鄰居們的喜好組織成一個排序目錄
目前我們公司團隊使用的是gbdt模型訓練,將鄰居們的喜好傳入模型,訓練得出一個score,根據score值進行排序。
暫時不對這一塊進行整理了,暫時沒有接觸到,有興趣的小夥伴可以自行檢視。
下面我具體介紹一下我使用真實的使用者日誌資料進行使用者cf策略計算的過程。
首先,我通過hadoop對最近十天的日誌資料進行了提取,提取出了使用者看過哪些新聞。資料樣例如下:
其次,我去查找了這些新聞的特徵(也可以直接用新聞作為座標來生成矩陣,這個只是與力度有關,效果好壞後期探索)。
近6000條新聞涉及到的tags總共有2600多個,很大一部分tags是某條新聞專有的,所以只取涉及到的新聞多的tags來形成矩陣。
將user-doc轉為user-tags,生成矩陣如下:
有了矩陣,就可以按照上述的餘弦求解公式來求解了。
函式如下:
def cosine_similarity(vector1, vector2):
dot_product = 0.0
normA = 0.0
normB = 0.0
for a, b in zip(vector1, vector2):
dot_product += a * b
normA += a ** 2
normB += b ** 2
if normA == 0.0 or normB == 0.0:
return 0
else:
return round(dot_product / ((normA ** 0.5) * (normB ** 0.5)) * 100, 2)
傳入的兩個引數,就是各個使用者針對於各個便籤行為的向量。
取其中某一個使用者,通過餘弦值可以得出與他最為相似的一批使用者。具體計算結果如下:
結果乘以100用於展示。