[矩陣分解]基於隱式反饋的矩陣分解ALS(spark實現)

目錄

一、ALS模型

1、模型定義

2、參數求解

3、推薦計算

二、pyspark實現ALS模型

三、矩陣分解模型與協同過濾模型比較


 

一、ALS模型

1、模型定義

用戶u對商品i的偏好:

       其中,在隱式反饋中無法獲取用戶對商品明確的評分,在視頻推薦場景中rui表示爲視頻觀看的時長比例,在商品推薦場景中rui表示爲對商品點擊次數等。

       用戶的隱式反饋屬於One-class問題,把預測用戶行爲看成一個二分類問題,猜用戶會不會做某事,實際上收集到的數據只有明確一類:用戶幹了某事,而用戶明確不幹某事的數據卻沒有明確表達。那些沒有反饋的缺失值,就是取值爲0的評分非常多,導致正負類別樣本非常不均衡,嚴重傾斜,應對這個問題的做法就是負樣本採樣:挑選部分缺失值作爲負類別樣本。

負樣本採樣方法:

  1. 隨機均勻採樣和正類別一樣多。
  2. 按照物品的熱門程度採樣(在實踐中經過了檢驗)。該採樣方法的思想是,一個越熱門的物品,用戶越可能知道它的存在,這種情況下用戶還沒對它有反饋就表明,這很可能是真正的負樣本。

用戶u對商品i偏好度pui的可信度

       用戶隱式反饋的可信度,正比於用戶反饋的次數,反饋次數越多,越確信用戶對物品的喜歡。

損失函數定義爲:

      損失函數包含誤差平方和(偏差)和正則項(方差)兩部分。

2、參數求解

        ALS(alternating-least-squares):如果用戶特徵矩陣或者商品特徵矩陣固定,損失函數爲二次函數,存在全局最優值,所以交替地計算用戶和商品特徵矩陣,每一步保證損失函數達到最優值。(利用最小二乘法交替計算用戶和商品特徵矩陣)

       計算用戶特徵矩陣:

     計算商品特徵矩陣:

     迭代步數默認值爲10.

3、推薦計算

        在得到分解後的矩陣後,每個用戶得到了隱因子向量,用於代表他的興趣,同時每個物品也得到一個隱因子向量,代表它的語義或主題。這兩者是一一對應的,用戶的興趣體現在物品的語義維度上。

        用戶和物品的隱因子向量兩兩相乘,計算點積就可以得到所有的推薦結果了,但是對於用戶數量和物品數量都特別大時,計算複雜度很高。FaceBook提出了兩種方法,計算用戶的推薦結果。

        第一種,利用專門設計的數據結構(ball tree)存儲所有物品的隱因子向量,從而實現通過一個用戶向量可以返回最相似的k個物品。開源有Faiss(FaceBook)、NMSLIB等。

       第二種,將物品的隱因子向量先做聚類,海量的物品會減少爲少量的聚類,然後再逐一計算用戶和每個聚類中心的推薦分數,給用戶推薦物品就變成給用戶推薦物品聚類。得到給用戶推薦的聚類後,再從每個聚類中挑選少許幾個物品作爲最終推薦結果。這樣做的好處除了大大減少計算量之外,還可以控制推薦結果的多樣性,因爲可以控制在每個類別中選擇的物品數量。

二、pyspark實現ALS模型

class pyspark.ml.recommendation.ALS(selfrank=10maxIter=10regParam=0.1numUserBlocks=10numItemBlocks=10implicitPrefs=falsealpha=1.0userCol="user"itemCol="item"seed=NoneratingCol="rating"nonnegative=falsecheckpointInterval=10intermediateStorageLevel="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://jaceklaskowski.gitbooks.io/mastering-apache-spark/content/spark-mllib/spark-mllib-alternating-least-squares.html

https://dataplatform.cloud.ibm.com/exchange/public/entry/view/99b857815e69353c04d95daefb3b91fa

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章