目錄
一、ALS模型
1、模型定義
用戶u對商品i的偏好:
其中,在隱式反饋中無法獲取用戶對商品明確的評分,在視頻推薦場景中rui表示爲視頻觀看的時長比例,在商品推薦場景中rui表示爲對商品點擊次數等。
用戶的隱式反饋屬於One-class問題,把預測用戶行爲看成一個二分類問題,猜用戶會不會做某事,實際上收集到的數據只有明確一類:用戶幹了某事,而用戶明確不幹某事的數據卻沒有明確表達。那些沒有反饋的缺失值,就是取值爲0的評分非常多,導致正負類別樣本非常不均衡,嚴重傾斜,應對這個問題的做法就是負樣本採樣:挑選部分缺失值作爲負類別樣本。
負樣本採樣方法:
- 隨機均勻採樣和正類別一樣多。
- 按照物品的熱門程度採樣(在實踐中經過了檢驗)。該採樣方法的思想是,一個越熱門的物品,用戶越可能知道它的存在,這種情況下用戶還沒對它有反饋就表明,這很可能是真正的負樣本。
用戶u對商品i偏好度pui的可信度:
用戶隱式反饋的可信度,正比於用戶反饋的次數,反饋次數越多,越確信用戶對物品的喜歡。
損失函數定義爲:
損失函數包含誤差平方和(偏差)和正則項(方差)兩部分。
2、參數求解
ALS(alternating-least-squares):如果用戶特徵矩陣或者商品特徵矩陣固定,損失函數爲二次函數,存在全局最優值,所以交替地計算用戶和商品特徵矩陣,每一步保證損失函數達到最優值。(利用最小二乘法交替計算用戶和商品特徵矩陣)
計算用戶特徵矩陣:
計算商品特徵矩陣:
迭代步數默認值爲10.
3、推薦計算
在得到分解後的矩陣後,每個用戶得到了隱因子向量,用於代表他的興趣,同時每個物品也得到一個隱因子向量,代表它的語義或主題。這兩者是一一對應的,用戶的興趣體現在物品的語義維度上。
用戶和物品的隱因子向量兩兩相乘,計算點積就可以得到所有的推薦結果了,但是對於用戶數量和物品數量都特別大時,計算複雜度很高。FaceBook提出了兩種方法,計算用戶的推薦結果。
第一種,利用專門設計的數據結構(ball tree)存儲所有物品的隱因子向量,從而實現通過一個用戶向量可以返回最相似的k個物品。開源有Faiss(FaceBook)、NMSLIB等。
第二種,將物品的隱因子向量先做聚類,海量的物品會減少爲少量的聚類,然後再逐一計算用戶和每個聚類中心的推薦分數,給用戶推薦物品就變成給用戶推薦物品聚類。得到給用戶推薦的聚類後,再從每個聚類中挑選少許幾個物品作爲最終推薦結果。這樣做的好處除了大大減少計算量之外,還可以控制推薦結果的多樣性,因爲可以控制在每個類別中選擇的物品數量。
二、pyspark實現ALS模型
class pyspark.ml.recommendation.ALS(self, rank=10, maxIter=10, regParam=0.1, numUserBlocks=10, numItemBlocks=10, implicitPrefs=false, alpha=1.0, userCol="user", itemCol="item", seed=None, ratingCol="rating", nonnegative=false, checkpointInterval=10, intermediateStorageLevel="MEMORY_AND_DISK", finalStorageLevel="MEMORY_AND_DISK", coldStartStrategy="nan")
Rank:模型中隱藏因子數目
maxIter:算法迭代次數
regParam:正則項權重
Alpha:用戶對物品偏好的可信度
implicitPrefs:數據集是隱式反饋還是顯示反饋
Nonnegative:商品推薦分數是否是非負的
利用網格搜索,遍歷最優參數:
(train,test) = sampleData.randomSplit([0.80, 0.20])
evalData = []
for ranks in [10,20,30,50,60]:
for maxIters in [20]:
for regParams in [0.001,0.01,0.1,1]:
for alphas in [0.1,1,10,20,30]:
als = ALS(rank = ranks, maxIter = maxIters, regParam=regParams, alpha = alphas,\
implicitPrefs = True,userCol = 'customers_id', itemCol = 'categories_id', ratingCol = 'pronum',nonnegative=True)
model = als.fit(train)
testPredic = model.transform(test).fillna(0)
testPredicData = testPredic.select('customers_id','categories_id','pronum','label',testPredic.prediction.cast("Double"))
evaluator = BinaryClassificationEvaluator(rawPredictionCol='prediction',labelCol='label')
auc = evaluator.evaluate(testPredicData,{evaluator.metricName: 'areaUnderROC'})
evalData.append([ranks,maxIters,regParams,alphas,auc])
print(ranks,maxIters,regParams,alphas,auc)
三、矩陣分解模型與協同過濾模型比較
|
矩陣分解 |
協同過濾 |
理論基礎 |
是一種學習方法,將用戶商品的稀疏矩陣映射到低維空間(有效信息提取和無效信息摒棄),模型精度更高 |
是一種基於統計的方法,並沒有學習的過程 |
實時推薦 |
用戶有新的行爲,推薦列表不能實時更新 |
用戶有新的行爲,會導致推薦列表的改變 |
冷啓動 |
推薦結果是用戶隱因子和物品隱因子的乘積,無法解決用戶或物品的冷啓動問題 |
userCF解決物品冷啓動問題 itemCF解決用戶冷啓動問題 |
推薦解釋 |
無法解釋,計算出的隱因子很難用自然語言描述 |
ItemCF可以利用用戶的歷史行爲解釋推薦結果 |
參考文獻:
《Collaborative filtering for implicit feedback datasets》
https://time.geekbang.org/column/article/5033
https://spark.apache.org/docs/preview/ml-collaborative-filtering.html
https://dataplatform.cloud.ibm.com/exchange/public/entry/view/99b857815e69353c04d95daefb3b91fa