協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

提到ALS相信大家應(yīng)該都不會(huì)覺得陌生,它是協(xié)同過濾的一種,并被集成到Spark的Mllib庫中。本文就ALS的基本原理進(jìn)行講解,并手把手、肩并肩地帶您實(shí)現(xiàn)這一算法。

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

完整實(shí)現(xiàn)代碼請(qǐng)參考:

https://github.com/tushushu/imylu/blob/master/imylu/recommend/als.py
https://github.com/tushushu/imylu/blob/master/examples/als_example.py

1. 原理篇

我們用人話而不是大段的數(shù)學(xué)公式來講講ALS是怎么一回事。

1.1 你聽說過推薦算法么

假如我是豆瓣的CEO,很多豆瓣的用戶在豆瓣電影上都會(huì)對(duì)電影進(jìn)行評(píng)分。那么根據(jù)這個(gè)評(píng)分?jǐn)?shù)據(jù),我們有可能知道這些用戶除了自己評(píng)過分的電影之外還喜歡或討厭哪些電影嗎?這就是一個(gè)典型的推薦問題,解決這一類問題的算法被稱為推薦算法。

1.2 什么是協(xié)同過濾

協(xié)同過濾的英文全稱是Collaborative Filtering,簡(jiǎn)稱CF。注意,這不是一款游戲!從字面上分析,協(xié)同就是尋找共同點(diǎn),過濾就是篩選出優(yōu)質(zhì)的內(nèi)容。

1.3 協(xié)同過濾的分類

一般來說,協(xié)同過濾推薦分為三種類型:

1. 基于用戶(user-based)的協(xié)同過濾,通過計(jì)算用戶和用戶的相似度找到跟用戶A相似的用戶B, C, D…再把這些用戶喜歡的內(nèi)容推薦給A;

2.基于物品(item-based)的協(xié)同過濾,通過計(jì)算物品和物品的相似度找到跟物品1相似的物品2, 3, 4…再把這些物品推薦給看過物品1的用戶們;

3. 基于模型(model based)的協(xié)同過濾。主流的方法可以分為:矩陣分解,關(guān)聯(lián)算法,聚類算法,分類算法,回歸算法,神經(jīng)網(wǎng)絡(luò)。

1.4 矩陣分解

矩陣分解 (decomposition, factorization)是將矩陣拆解為數(shù)個(gè)矩陣的乘積。比如豆瓣電影有m個(gè)用戶,n個(gè)電影。那么用戶對(duì)電影的評(píng)分可以形成一個(gè)m行n列的矩陣R,我們可以找到一個(gè)m行k列的矩陣U,和一個(gè)k行n列的矩陣I,通過U * I來得到矩陣R。

1.5 ALS

如果想通過矩陣分解的方法實(shí)現(xiàn)基于模型的協(xié)同過濾,ALS是一個(gè)不錯(cuò)的選擇,其英文全稱是Alternating Least Square,翻譯過來是交替最小二乘法。假設(shè)用戶為a,物品為b,評(píng)分矩陣為R(m, n),可分解為用戶矩陣U(k, m)和物品矩陣I(k, n),其中m, n, k代表矩陣的維度。前方小段數(shù)學(xué)公式低能預(yù)警:

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

1.6 求解用戶矩陣U和物品矩陣I

矩陣R是已知的,我們隨機(jī)生成用戶矩陣U, 1. 利用1.5中的式5、R和U求出I 2. 利用1.5中的式6、R和I求出U

如此交替地執(zhí)行步驟1和步驟2,直到算法收斂或者迭代次數(shù)超過了最大限制,最終我們用RMSE來評(píng)價(jià)模型的好壞。

2. 實(shí)現(xiàn)篇

本人用全宇宙最簡(jiǎn)單的編程語言——Python實(shí)現(xiàn)了ALS算法,沒有依賴任何第三方庫,便于學(xué)習(xí)和使用。簡(jiǎn)單說明一下實(shí)現(xiàn)過程,更詳細(xì)的注釋請(qǐng)參考本人github上的代碼。

注:代碼中用到的Matrix類是我寫的一個(gè)矩陣類,可以取出矩陣的行或列,計(jì)算矩陣的乘法、轉(zhuǎn)置和逆。代碼鏈接:matrix.py

2.1 創(chuàng)建ALS類

初始化,存儲(chǔ)用戶ID、物品ID、用戶ID與用戶矩陣列號(hào)的對(duì)應(yīng)關(guān)系、物品ID與物品矩陣列號(hào)的對(duì)應(yīng)關(guān)系、用戶已經(jīng)看過哪些物品、評(píng)分矩陣的Shape以及RMSE。

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

2.2 數(shù)據(jù)預(yù)處理

對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行處理,得到用戶ID、物品ID、用戶ID與用戶矩陣列號(hào)的對(duì)應(yīng)關(guān)系、物品ID與物品矩陣列號(hào)的對(duì)應(yīng)關(guān)系、評(píng)分矩陣的Shape、評(píng)分矩陣及評(píng)分矩陣的轉(zhuǎn)置。

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

2.3 用戶矩陣乘以評(píng)分矩陣

實(shí)現(xiàn)稠密矩陣與稀疏矩陣的矩陣乘法,得到用戶矩陣與評(píng)分矩陣的乘積。

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

2.4 物品矩陣乘以評(píng)分矩陣

實(shí)現(xiàn)稠密矩陣與稀疏矩陣的矩陣乘法,得到物品矩陣與評(píng)分矩陣的乘積。

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

2.5 生成隨機(jī)矩陣

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

2.6 計(jì)算RMSE

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

2.7 訓(xùn)練模型

1.數(shù)據(jù)預(yù)處理

2.變量k合法性檢查

3.生成隨機(jī)矩陣U

4.交替計(jì)算矩陣U和矩陣I,并打印RMSE信息,直到迭代次數(shù)達(dá)到max_iter

5.保存最終的RMSE

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

2.8 預(yù)測(cè)一個(gè)用戶

預(yù)測(cè)一個(gè)用戶感興趣的內(nèi)容,剔除用戶已看過的內(nèi)容。然后按感興趣分值排序,取出前n_items個(gè)內(nèi)容。

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

2.9 預(yù)測(cè)多個(gè)用戶

循環(huán)調(diào)用2.8,預(yù)測(cè)多個(gè)用戶感興趣的內(nèi)容。

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

3 效果評(píng)估

3.1 main函數(shù)

使用電影評(píng)分?jǐn)?shù)據(jù)集,訓(xùn)練模型并統(tǒng)計(jì)RMSE。

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

3.2 效果展示

設(shè)置k=3,迭代5次,并展示了前4個(gè)用戶的推薦內(nèi)容,最終RMSE為0.370,運(yùn)行時(shí)間46.5秒,效果還算不錯(cuò)~

協(xié)同過濾?教你用Python實(shí)現(xiàn)協(xié)同過濾

3.3 工具函數(shù)

本人自定義了一些工具函數(shù),可以在github上查看

1.run_time - 測(cè)試函數(shù)運(yùn)行時(shí)間

2.load_movie_ratings - 加載電影評(píng)分?jǐn)?shù)據(jù)

總結(jié)

  • ALS的原理:雞生蛋、蛋生雞
  • ALS的實(shí)現(xiàn):基本上就是矩陣乘法
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容