推薦算法之 slope one 算法


 

1.示例引入

多個吃貨在某美團的某家飯館點餐,如下兩道菜:

可樂雞翅:

紅燒肉:

顧客吃過后,會有相關的星級評分。假設評分如下:
評分 可樂雞翅 紅燒肉
小明 4 5
小紅 4 3
小偉 2 3
小芳 3 ?
問題:請猜測一下小芳可能會給“紅燒肉”打多少分?
思路:把兩道菜的平均差值求出來,可樂雞翅減去紅燒肉的平均偏差:[(4-5)+(4-3)+(2-3)]/3=-0.333。一個新客戶比如小芳,只吃了可樂雞翅評分為3分,那么可以猜測她對紅燒肉的評分為:3-(-0.333)=3.333

這就是slope one 算法的基本思路,非常非常的簡單。

2.slope one 算法思想

Slope One 算法是由 Daniel Lemire 教授在 2005 年提出的一個Item-Based 的協同過濾推薦算法。和其它類似算法相比, 它的最大優點在於算法很簡單, 易於實現, 執行效率高, 同時推薦的准確性相對較高。
Slope One算法是基於不同物品之間的評分差的線性算法,預測用戶對物品評分的個性化算法。主要兩步:
Step1:計算物品之間的評分差的均值,記為物品間的評分偏差(兩物品同時被評分);

Step2:根據物品間的評分偏差和用戶的歷史評分,預測用戶對未評分的物品的評分。

Step3:將預測評分排序,取topN對應的物品推薦給用戶。

舉例:
假設有100個人對物品A和物品B打分了,R(AB)表示這100個人對A和B打分的平均偏差;有1000個人對物品B和物品C打分了, R(CB)表示這1000個人對C和B打分的平均偏差;


3.python實現

def loadData():
    items={'A':{1:5,2:3},
           'B':{1:3,2:4,3:2},
           'C':{1:2,3:5}}
    users={1:{'A':5,'B':3,'C':2},
           2:{'A':3,'B':4},
           3:{'B':2,'C':5}}
    return items,users

3.2物品間評分偏差

#***計算物品之間的評分差
#items:從物品角度,考慮評分
#users:從用戶角度,考慮評分

    for itemId in items:
        for otherItemId in items:
            average=0.0 #物品間的評分偏差均值
            userRatingPairCount=0 #兩件物品均評過分的用戶數
            if itemId!=otherItemId: #若無不同的物品項
                for userId in users: #遍歷用戶-物品評分數
                    userRatings=users[userId] #每條數據為用戶對物品的評分
                    #當前物品項在用戶的評分數據中,且用戶也對其他物品由評分
                    if itemId in userRatings and otherItemId in userRatings:
                        #兩件物品均評過分的用戶數加1
                        userRatingPairCount+=1
                        #評分偏差為每項當前物品評分-其他物品評分求和
                        average+=(userRatings[otherItemId]-userRatings[itemId])
                averages[(itemId,otherItemId)]=average/userRatingPairCount

3.3預估評分

#***預測評分
#users:用戶對物品的評分數據
#items:物品由哪些用戶評分的數據
#averages:計算的評分偏差
#targetUserId:被推薦的用戶
#targetItemId:被推薦的物品

def suggestedRating(users,items,averages,targetUserId,targetItemId):
runningRatingCount=0 #預測評分的分母
weightedRatingTotal=0.0 #分子
for i in users[targetUserId]:
#物品i和物品targetItemId共同評分的用戶數
ratingCount=userWhoRatedBoth(users,i,targetItemId)
#分子
weightedRatingTotal+=(users[targetUserId][i]-averages[(targetItemId,i)])\
*ratingCount
#分母
runningRatingCount+=ratingCount
#返回預測評分
return weightedRatingTotal/runningRatingCount

統計兩物品共同評分的用戶數

# 物品itemId1與itemId2共同有多少用戶評分

def userWhoRatedBoth(users,itemId1,itemId2):
    count=0
    #用戶-物品評分數據
    for userId in users:
        #用戶對物品itemId1與itemId2都評過分則計數加1
        if itemId1 in users[userId] and itemId2 in users[userId]:
            count+=1
    return count

3.4測試結果:

if __name__=='__main__':
    items,users=loadData()
    averages={}
    #計算物品之間的評分差
    buildAverageDiffs(items,users,averages)
    #預測評分:用戶2對物品C的評分
    predictRating=suggestedRating(users,items,averages,2,'C')
    print 'Guess the user will rate the score :',predictRating

結果:用戶2對物品C的預測分值為
Guess the user will rate the score : 3.33333333333

4.slopeOne使用場景

該算法適用於物品更新不頻繁,數量相對較穩定並且物品數目明顯小於用戶數的場景。依賴用戶的用戶行為日志和物品偏好的相關內容。
優點:
1.算法簡單,易於實現,執行效率高;
2.可以發現用戶潛在的興趣愛好;
缺點:
依賴用戶行為,存在冷啟動問題和稀疏性問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM