推薦算法&評分預測問題
參考書本: 項亮, 推薦系統實踐. 2012
本文系閱讀筆記
實際系統-topN問題
推薦系統各種研究比賽-評分預測問題。
評分預測問題最基本數據集就是用戶評分數據集。(u,i,r)
用戶u給物品i評了r分。
評分預測問題是如何通過已知的用戶歷史記錄評分預測未知的用戶評分記錄。
離線實驗方法
一般可以用均方根誤差RMSE度量預測的精度:
評分預測的目的就是找到最好的模型最小化測試集的RMSE
【即預測數據的平均誤差最小】
劃分訓練集和測試集的方法:
如果和時間沒有關系--可以隨機
如果和時間有關系--用戶的舊行為為訓練集,新行為為測試集。
Netflix 通過如下方式劃分數據集,首先將每個用戶的評分記錄按照從早到晚進行排序,然后將用戶最后 10%的評分記錄作為測試集,前 90% 的評分記錄作為訓練集。
評分預測方法
平均值
-
全局平均值
它的定義為訓練集中所有評分記錄的評分平均值。
而最終的預測函數可以直接定義為
-
用戶評分平均值
用戶u的評分平均值
定義為用戶u在訓練集中所有評分的平均值。
而最終的預測函數可以直接定義為
-
物品評分平均值
物品i的評分平均值
定義為物品i在訓練集中所有評分的平均值:
而最終的預測函數可以直接定義為
-
用戶分類對物品分類的平均值
假設有兩個分類函數,一個是用戶分類函數
,一個是物品分類函數
。
定義了用戶u所屬的類,
定義了物品i所屬的類。那么,我們可以利用訓練集中同類用戶對同類物品評分的平均值預測用戶對物品的評分,即:
? 如果定義
=0,
=0,那么
就是全局平均值。
? 如果定義=u,
=0,那么
就是用戶評分平均值。
? 如果定義=0,
=i ,那么
就是物品評分平均值。
除了這 3 種特殊的平均值,在用戶評分數據上還可以定義很多不同的分類函數。
? 用戶和物品的平均分 對于一個用戶,可以計算他的評分平均分。然后將所有用戶按照評分平均分從小到大排序,并將用戶按照平均分平均分成 N 類。物品也可以用同樣的方式分類。
? 用戶活躍度和物品流行度 對于一個用戶,將他評分的物品數量定義為他的活躍度。得到用戶活躍度之后,可以將用戶通過活躍度從小到大排序,然后平均分為 N 類。物品的流行度定義為給物品評分的用戶數目,物品也可以按照流行度均勻分成 N 類。[計算類類平均值的方法代碼見書]
在這段代碼中, user_cluster.GetGroup 函數接收一個用戶 ID ,然后根據一定的算法返回用戶的類別。 item_cluster.GetGroup 函數接收一個物品的 ID ,然后根據一定的算法返回物品的類別。 total[gu][gi]/count[gu][gi] 記錄了第 gu 類用戶給第 gi 類物品評分的平均分。上文提到, user_cluster 和 item_cluster 有很多不同的定義方式。
【詳細看書】
基于鄰域的方法
基于用戶的鄰域算法和基于物品的鄰域算法都可以應用到評分預測中。
基于用戶的鄰域算法認為預測一個用戶對一個物品的評分,需要參考和這個用戶興趣相似的用戶對該物品的評分。
基于物品的鄰域算法在預測用戶 u 對物品 i 的評分時,會參考用戶 u 對和物品 i 相似的其他物品的評分。
用到了皮爾遜系數。
隱語義模型和矩陣分解模型
在推薦系統領域,提的最多的就是潛語義模型和矩陣分解模型。其實,這兩個名詞說的是一回事,就是如何通過降維的方法將評分矩陣補全。
用戶的評分行為可以表示成一個評分矩陣 R ,其中 R [ u ][ i ] 就是用戶 u 對物品 i 的評分。但是,用戶不會對所有的物品評分,所以這個矩陣里有很多元素都是空的,這些空的元素稱為缺失值( missing value )。因此,評分預測從某種意義上說就是填空,如果一個用戶對一個物品沒有評過分,那么推薦系統就要預測這個用戶是否是否會對這個物品評分以及會評幾分。
SVD分解
一般認為,如果補全后矩陣的特征值和補全之前矩陣的特征值相差不大,就算是擾動比較小。所以,最早的矩陣分解模型就是從數學上的 SVD (奇異值分解)開始的。
降維分解。
SVD 分解是早期推薦系統研究常用的矩陣分解方法,不過該方法具有以下缺點,因此很難在
實際系統中應用。
? 該方法首先需要用一個簡單的方法補全稀疏評分矩陣。一般來說,推薦系統中的評分矩陣是非常稀疏的,一般都有 95% 以上的元素是缺失的。而一旦補全,評分矩陣就會變成一個稠密矩陣,從而使評分矩陣的存儲需要非常大的空間,這種空間的需求在實際系統中是不可能接受的。
? 該方法依賴的 SVD 分解方法的計算復雜度很高,特別是在稠密的大規模矩陣上更是非常慢。一般來說,這里的 SVD 分解用于 1000 維以上的矩陣就已經非常慢了,而實際系統動輒是上千萬的用戶和幾百萬的物品,所以這一方法無法使用。如果仔細研究關于這一方法的論文可以發現,實驗都是在幾百個用戶、幾百個物品的數據集上進行的。
Simon Funk SVD
Simon Funk 提出的矩陣分解方法后來被 Netflix Prize 的冠軍 Koren 稱為 Latent Factor Model (簡稱為 LFM )
令
那么, Simon Funk 的思想很簡單:可以直接通過訓練集中的觀察值利用最小化 RMSE 學習 P 、 Q 矩陣。
【于是得到損失函數】
為了防止過擬合,再加上正則化。然后利用梯度下降求參數。
是學習速率( learning rate ),它的取值需要通過反復實驗獲得。
【這塊可以看書,和機器學習推導比較像】
LFM 提出之后獲得了很大的成功,后來很多著名的模型都是通過對 LFM 修修補補獲得的,下面的各節將分別介紹一下改進 LFM 的各種方法。這些改進有些是對模型的改進,有些是將新的數據引入到模型當中。
加入偏置項后的LFM
μ:訓練集中所有記錄的評分的全局平均數。在不同網站中,因為網站定位和銷售的物品不同,網站的整體評分分布也會顯示出一些差異。比如有些網站中的用戶就是喜歡打高分,而另一些網站的用戶就是喜歡打低分。而全局平均數可以表示網站本身對用戶評分的影響。
用戶評分相對所有平均分的誤差(有的用戶苛刻有的用戶寬容。)
物體平均分相對均分偏差。物體好壞。
其中要通過機器學習訓練出來。
考慮鄰域影響的LFM SVD++
前面的 LFM 模型中并沒有顯式地考慮用戶的歷史行為對用戶評分預測的影響。為此, Koren在 Netflix Prize 比賽中提出了一個模型,將用戶歷史評分的物品加入到了 LFM 模型中, Koren 將該模型稱為 SVD++ 。
[代碼看書]
SVD++就是加入了很多邊緣信息,在SVD的基礎上引入了隱式反饋。
關于公式推導及更多信息參見:
http://www.lxweimin.com/p/f06860717c9e
https://www.cnblogs.com/Xnice/p/4522671.html
加入時間信息
利用時間信息的方法也主要分成兩種,一種是將時間信息應用到基于鄰域的模型中,另一種是將時間信息應用到矩陣分解模型中。下面將分別介紹這兩種算法。
基于鄰域的模型
因為 Netflix Prize 數據集中用戶數目太大,所以基于用戶的鄰域模型很少被使用,主要是因為存儲用戶相似度矩陣非常困難。因此,本節主要討論如何將時間信息融合到基于物品的鄰域模型中。
也是用一個時間函數。隨時間離現在越遠,物品影響力越小。
【公式太復雜不想敲了,看書吧】
TitemCF
基于矩陣分解的模型
在引入時間信息后,用戶評分矩陣不再是一個二維矩陣,而是變成了一個三維矩陣。不過,我們可以仿照分解二維矩陣的方式對三維矩陣進行分解。
TSVD
【公式見書】
模型融合
模型級聯融合
假設已經有一個預測器,對于每個用戶 — 物品對 (u, i) 都給出預測值,那么可以在這個預測器的基礎上設計下一個預測器
來最小化損失函數:
級聯融合很像 Adaboost 算法。和 Adaboost 算法類似,該方法每次產生一個新模型,按照一定的參數加到舊模型上去,從而使訓練集誤差最小化。不同的是,這里每次生成新模型時并不對樣本集采樣,針對那些預測錯的樣本,而是每次都還是利用全樣本集進行預測,但每次使用的模型都有區別。
一般來說,級聯融合的方法都用于簡單的預測器,比如前面提到的平均值預測器。
模型加權融合
假設我們有 K 個不同的預測器{},本節主要討論如何將它們融合起來獲得最低的預測誤差。
最簡單的融合算法就是線性融合,即最終的預測器是這 K 個預測器的線性加權。
因此,在模型融合時一般采用如下方法。
? 假設數據集已經被分為了訓練集 A 和測試集 B ,那么首先需要將訓練集 A 按照相同的分割方法分為 A1 和 A2 ,其中 A2 的生成方法和 B 的生成方法一致,且大小相似。
? 在 A1 上訓練 K 個不同的預測器,在 A2 上作出預測。因為我們知道 A2 上的真實評分值,所以可以在 A2 上利用最小二乘法, 計算出線性融合系數 。
? 在 A 上訓練 K 個不同的預測器,在 B 上作出預測,并且將這 K 個預測器在 B 上的預測結果按照已經得到的線性融合系數加權融合,以得到最終的預測結果。
除了線性融合,還有很多復雜的融合方法,比如利用人工神經網絡的融合算法。其實,模型融合問題就是一個典型的回歸問題,因此所有的回歸算法都可以用于模型融合。