Spark0 9分布式執行MLlib的協同過濾

2021-06-20 11:58:32 字數 3941 閱讀 1365

協同過濾推薦(collaborative filtering recommendation)是在資訊過濾和資訊系統中正迅速成為一項很受歡迎的技術。與傳統的基於內容過濾直接分析內容進行推薦不同,協同過濾分析使用者興趣,在使用者群中找到指定使用者的相似(興趣)使用者,綜合這些相似使用者對某一資訊的評價,形成系統對該指定使用者對此資訊的喜好程度**。

儘管協同過濾技術在個性化推薦系統中獲得了極大的成功,但隨著站點結構、內容的複雜度和使用者人數的不斷增加,協同過濾技術的一些缺點逐漸暴露出來。

在許多推薦系統中,每個使用者涉及的資訊量相當有限,在一些大的系統如亞馬遜**中,使用者最多不過就評估了上百萬本書的1%~2%。造成評估矩陣資料相當稀疏,難以找到相似使用者集,導致推薦效果大大降低。

「最近鄰居」演算法的計算量隨著使用者和項的增加而大大增加,對於上百萬之巨的數目,通常的演算法將遭遇到嚴重的擴充套件性問題。

通過尋找相近使用者來產生推薦集,在數量較大的情況下,推薦的可信度隨之降低。

當可以對一些專案評分的時候,比如人們可以對一些東西給出1到5星的評價的時候,協同過濾意圖基於乙個個體過去對某些專案的評分和(龐大的)由其他使用者的評價構成的資料庫,來**該使用者對未評價專案的評分。例如: 如果乙個人給披頭四的評分為5(總分5)的話,我們能否**他對席琳狄翁新**的評分呢?

這種情形下, item-based 協同過濾系統[5]

[6] 根據其它專案的評分來**某專案的分值,一般方法為 線性回歸

(). 於是,需要列出x^2個線性回歸方程和2x^2個回歸量,例如:當有1000個專案時,需要列多達1,000,000個線性回歸方程, 以及多達2,000,000個回歸量。除非我們只選擇某些使用者共同評價過的專案對,否則協同過濾會遇到過適

[2](過擬合) 問題。

另外一種更好的方法是使用更簡單一些的式子,比如 :實驗證明當使用一半的回歸量的時候,該式子(稱為slope one)的表現有時優於[2]

線性回歸方程。該簡化方法也不需要那麼多儲存空間和延遲。

item-based 協同過濾只是 協同過濾

的一種形式.其它還有像 user-based 協同過濾一樣研究使用者間的聯絡的過濾系統。但是,考慮到其他使用者數量龐大,item-based協同過濾更可行一些。

人們並不總是能給出評分,當使用者只提供二進位制資料(購買與否)的時候,就無法應用slope one 和其它基於評分的演算法。 二進位制 item-based協同過濾應用的例子之一就是amazon的 item-to-item

專利演算法[7]

,該演算法中用二進位制向量表示使用者-專案購買關係的矩陣,並計算二進位制向量間的cosine相關係數。

有人認為item-to-item演算法甚至比slope one 還簡單,例如:

購買統計樣本

顧客

專案 1

專案 2

專案 3

john 買過

沒買過 買過

mark

沒買過 買過

買過lucy

沒買過 買過

沒買過

, , .

於是,瀏覽專案1的顧客會被推薦買專案3(兩者相關係數最大),而瀏覽專案2的顧客會被推薦買專案3,瀏覽了專案3的會首先被推薦買專案1(再然後是專案2,因為2和3的相關係數小於1和3)。該模型只使用了每對專案間的乙個引數(cosine相關係數)來產生推薦。因此,如果有n個專案,則需要計算和儲存 n(n-1)/2 個cosine相關係數。

為了大大減少過適

(過擬合)的發生,提公升演算法簡化實現,slope one系列易實現的item-based協同過濾

演算法被提了出來。本質上,該方法運用更簡單形式的回歸表示式() 和單一的自由引數,而不是乙個專案評分和另乙個專案評分間的線性回歸 ()。 該自由引數只不過就是兩個專案評分間的平均差值。甚至在某些例項當中,它比線性回歸的方法更準確[2]

,而且該演算法只需要一半(甚至更少)的儲存量。

:

1.     user a 對 item i 評分為1 對itemj.評分為1.5

2.     user b 對 item i 評分為2.

3.     你認為 user b 會給 item j 打幾分?

4.     slope one 的答案是:2.5 (1.5-1+2=2.5).

舉個更實際的例子,考慮下表:

評分資料庫樣本

顧客

專案 1

專案 2

專案 3

john 5

3 2mark 3

4未評分

lucy

未評分 2

5 在本例中,專案2和1之間的平均評分差值為(2+(-1))/2=0.5. 因此,item1的評分平均比item2高0.5。同樣的,專案3和1之間的平均評分差值為3。因此,如果我們試圖根據lucy 對專案2的評分來**她對專案1的評分的時候,我們可以得到 2+0.5 = 2.5。同樣,如果我們想要根據她對專案3的評分來**她對專案1的評分的話,我們得到 5+3=8.

如果乙個使用者已經評價了一些專案,可以這樣做出**:簡單地把各個專案的**通過加權平均值結合起來。當使用者兩個專案都評價過的時候,權值就高。在上面的例子中,專案1和專案2都評價了的使用者數為2,專案1和專案3 都評價了的使用者數為1,因此權重分別為2和1. 我們可以這樣**lucy對專案1的評價:

於是,對「n」個專案,想要實現 slope one,只需要計算並儲存「n」對評分間的平均差值和評價數目即可。

mllib目前支援基於協同過濾的模型,在這個模型裡,使用者和產品被一組的可以用來**缺失的專案的潛在因子來描述。特別是,我們實現交替最小二乘(als)演算法來學習這些潛在的因子。實現在mllib以下引數:

numblocks是用於並行化計算的資料分塊(自動配置(設定為1))。

rank是在我們的模型中潛在因子的數量。

iterations是迭代的數量。

lambda是在als指定了正則化引數。

implicitprefs指定是否使用顯式反饋als變數或乙個用於隱式反饋資料

α是乙個引數適用於隱式反饋的als變數,這個變數管理著偏好觀測的基線信心 

在接下來的例子中我們將要裝載乙個評級資料。每一行包含乙個使用者、乙個產品和乙個評級。我們使用預設als.train()方法,這個方法假設評級是明確的。我們通過**評級的均方誤差的來評估推薦模型評級的好壞。

import org.apache.spark.sparkcontext

import org.apache.spark.mllib.recommendation.als

import org.apache.spark.mllib.recommendation.rating

def main(args: array[string]) )

// build the recommendation model using als

val numiterations = 20

val model = als.train(ratings, 1, 20, 0.01)

// evaluate the model on rating data

val usersproducts = ratings.map

val predictions = model.predict(usersproducts).map

val ratesandpreds = ratings.map.join(predictions)

val mse = ratesandpreds.map.reduce(_ + _)/ratesandpreds.count

println("mean squared error = " + mse)

}}

spark分布式環境搭建(2)分布式環境準備

ps 我已經複製好了 開啟三颱機器,它們的環境都是一樣的 是複製得到的集群 目標 修改三颱機器的hostname修改三颱機器的ip修改三颱機器的hosts三颱機器做免密登入 vim etc hostname 修改三颱機器的網路 vim etc sysconfig network scripts if...

分布式 2分布式事務

分布式 1概述cap和base 分布式 2分布式事務 分布式 3分布式一致性演算法 分布式 4集群 分布式 5服務限流演算法 分布式 6分布式id 分布式 7效能壓測 分布式 8日誌鏈路跟蹤 分布式 9分布式鎖 redis鎖的幾種實現 參考 分布式系統間各種問題 宕機 網路不穩定 本地事務無法滿足需...

spark分布式執行xgboost

coding utf 8 import os os.environ pyspark submit args jars data pycharm zhanglong pysparkxgboostnew xgboost4j spark 0.90.jar,data pycharm zhanglong py...