推薦系統——基於隱因子矩陣分解的協同過濾算法

  在新手接觸推薦系統這個領域時,遇到第一個理解起來比較困難的就是協同過濾法。那麼若是這時候百度的話,獲得最多的是奇異值分解法,即(SVD)。SVD的做用大體是將一個矩陣分解爲三個矩陣相乘的形式。若是運用在推薦系統中,首先咱們將咱們的訓練集表示成矩陣的形式,這裏咱們以movielen數據集爲例。這個數據集包含了用戶對電影的評分。那麼矩陣形式大體爲:python

  movie1  movie2  movie3 moive4
user1 1      
user2 2     3
user3   5 4  
user4 2     4

  其中1~5就是對應用戶對電影的評分。空餘處表示數據集中沒有對應用戶和電影的信息。若是咱們想使用SVD,通常講空餘處都填爲0.假設此矩陣爲V.那麼運用SVD能夠獲得git

                          V = UΣVT github

  可是上面的等號並不能取到,只能是約等於。那麼咱們將獲得的三個矩陣相乘獲得V'(注意與V不一樣)。那麼原來的空白處(也就是0處)可能就再也不爲0,那麼這就是對該user-moive對的預測。這就是SVD的主要原理。由於SVD有不少現成的算法,也不用迭代就可直接獲得,因此使用比較方便。
web

 

  可是咱們會看到,上面方法有一個致命的缺陷,那就是將未知的評分全都設爲0.這實際上是極其不合理的,由於用戶不給某個電影打分並非很不喜歡(0分),而是有可能尚未看過這個電影。這樣就加入了咱們主觀臆斷的信息,最後形成錯誤。解決的方法就是使用隱因子的矩陣分解法。注意矩陣分解法和SVD有類似的地方也有不一樣的地方,下面我就對矩陣分解法進行詳細介紹。
算法

  在矩陣分解法中,有一個假設,就是每個用戶都有一個長度爲k的特徵向量,每一部電影也有一個相同長度的特徵向量(k通常須要用戶指定)。那麼全部用戶的特徵向量排列成一個矩陣 U 的維度爲UserNum * k。其中用戶i對應的向量爲Ui。全部電影的特徵向量排列成一個矩陣M 的維度爲MoiveNum * k。其中電影j對應的向量爲Uj。那麼用戶i對電影j的評分 Vij = <Ui , Mj>(<>表明點乘)。那麼全部用戶和全部電影之間的評分就能夠用兩個矩陣相乘來獲得:
機器學習

                          V' = UMT ide

  注意這裏是V'而不是V。那麼問題來了,咱們如何肯定這個U和M?一個天然的想法就是讓V'和V儘量地相等。那麼這又有一個問題,那就是V(即數據集)有不少地方是沒有評分的,如何判斷和V'是否相等?那麼咱們在這裏只計算有評分處的MSE。這樣既沒有使用額外的信息,又能判斷二者是否接近。那麼天然而然得就引入了咱們的lost function:
學習

      

  這裏Iij表示用戶i對電影j有評分記錄。後面兩項是懲罰因子,目的是防止過擬合。那麼利用梯度降低法,咱們就能夠經過迭代獲得U和M的值。其對U和對M的求到以下:
優化

  到這裏咱們就已經完成了基礎的矩陣分解法。那麼進一步,爲了實現更好的效果,咱們要考慮每一個個體打分的影響,由於有些用戶打分偏高,有些用戶打分偏低。一樣對於電影和全部的評分。因此咱們評分的計算公式應該改成:ui

      Vij = <Ui,Mj> + overall_mean + ai +bj

  其中overall_mean是全部評分的平均值,ai是用戶i打分的平均值,bj是電影j得分的平均值。其中overall_mean認爲是一個常數,而ai和bj都是須要優化的參數。這裏咱們就不給出對他們求導的式子,我直接給出矩陣形式的算法,便於你們具體實現。(INCOMING) (拖了一週左右放上去,這拖延症也是沒sei了 0.0)

 

  我本身寫了一個python版的,有興趣能夠參考 https://github.com/ccienfall/RecommandSystem/blob/master/script/Factorize.py

  在2016Byte Cup國際機器學習競賽的數據集上分別運用SVD和矩陣分解(MF),最後結果是MF的方法能比SVD的效果高20%左右。

  參考文獻:《A Guide to Singular Value Decomp osition for Collaborative Filtering》

相關文章
相關標籤/搜索