slopeOne推薦算法:最基礎的推薦算法

#coding=utf8

def loadData():
    items={
        'candy':{'Bob':1.0,'Jane':1.0,'Jo':0.9,'SJo':0.1},
        'dog'  :{'Bob':0.5,'Jo':0.4},
        'cat'  :{'Jane':0.5,'Jo':0.5},
        'war'  :{'Bob':0.1,'Jane':0.2,'Jo':0.1,'SJo':1.0},
        'food' :{'SJo':0.4}
    }
    
    users={
        'Bob':{'candy':1.0,'dog':0.5,'war':0.1},
        'Jane':{'candy':1.0,'cat':0.5,'war':0.2},
        'Jo':{'candy':0.9,'dog':0.4,'cat':0.5,'war':0.1},
        'SJo':{'candy':0.1,'war':1.0,'food':0.4}
    }
    
    return items,users

#***計算物品之間的評分差 
#items:從物品角度,考慮評分 
#users:從用戶角度,考慮評分 
def buildAverageDiffs(items,users,averages): 
    #遍歷每條物品-用戶評分數據 
    for itemId in items: 
        for otherItemId in items: 
            average=0.0 #物品間的評分偏差均值 
            userRatingPairCount=0 #兩件物品均評過分的用戶數 
            if itemId!=otherItemId: #若無不同的物品項 
            # 上條代碼可以改進成如下方式
            # if itemId!=otherItemId and (itemId,otherItemId) not in averages.keys() and (otherItemId,itemId) not in averages.keys(): #若無不同的物品項 
                for userId in users: #遍歷用戶-物品評分數 
                    userRatings=users[userId] #每條數據爲用戶對物品的評分 
                    #當前物品項在用戶的評分數據中,且用戶也對其他物品由評分 
                    if itemId in userRatings and otherItemId in userRatings: 
                        #兩件物品均評過分的用戶數加1 
                        userRatingPairCount+=1 
                        #評分偏差爲每項當前物品評分-其他物品評分求和 
                        average+=(userRatings[otherItemId]-userRatings[itemId]) 
                if(userRatingPairCount!=0):
                    averages[(itemId,otherItemId)]=average/userRatingPairCount
                
#統計量物品共同評分的用戶數
# 物品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

#***預測評分 
#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) 
        #分子 
        if(ratingCount!=0):
            weightedRatingTotal+=(users[targetUserId][i]-averages[(targetItemId,i)])*ratingCount 
        #分母 
        runningRatingCount+=ratingCount 
    #返回預測評分 
    return weightedRatingTotal/runningRatingCount

if __name__=='__main__': 
    items,users = loadData() 
    averages={} 

    #計算物品之間的平均評分差 
    buildAverageDiffs(items,users,averages) 

    #預測評分:用戶2對物品C的評分 
    predictRating=suggestedRating(users,items,averages,'Jo','food') 
    print ('Guess the user will rate the score :'+ str(round(predictRating,2)))
    ```
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章