1. 程式人生 > >《集體智慧程式設計》學習筆記(一)

《集體智慧程式設計》學習筆記(一)

第二章 提供推薦

1、蒐集偏好

先構造一個簡單的資料集:

#使用者對不同電影的評分
critics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,
 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5, 
 'The Night Listener': 3.0},

'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 
 'Just My Luck
': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0, 'You, Me and Dupree': 3.5}, 'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0, 'Superman Returns': 3.5, 'The Night Listener': 4.0}, 'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'The Night Listener'
: 4.5, 'Superman Returns': 4.0, 'You, Me and Dupree': 2.5}, 'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0, 'You, Me and Dupree': 2.0}, 'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5}, 'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0}}

2、相似度評價值

評價值 特點
歐幾里德距離 多維空間中兩點之間的距離,用來衡量二者的相似度。距離越小,相似度越高。
皮爾遜相關度評價 判斷兩組資料與某一直線擬合程度的一種度量。在資料不是很規範的時候(如影評者對影片的評價總是相對於平均水平偏離很大時),會給出更好的結果。相關係數越大,相似度越高。

 

#歐幾里得距離
def disitance_simulation (critics, person1, person2):
    result = [name for name in critics[person1] if name in critics[person2]]
    if 0 == len(result):
        return 0
    #else:
    #    print (result)
    return (1 / (1 + sqrt(sum([pow(critics[person1][name] - critics[person2][name], 2) for name in result]))))
    
#皮爾遜相關度
#找出兩位評論者都曾評價過的物品,然後計算兩者的評分總和與平方和,並求出評分的乘積之和。
#利用上述計算結果計算出皮爾遜相關係數
def pearson_simulation (critics, person1, person2): result = [name for name in critics[person1] if name in critics[person2]] if 0 == len(result): return 0 #else: # print (result) #評分和 sum1 = sum([critics[person1][name] for name in result]) sum2 = sum([critics[person2][name] for name in result]) #平方和 sum1Sq = sum([pow(critics[person1][name], 2) for name in result]) sum2Sq = sum([pow(critics[person2][name], 2) for name in result]) #同一個電影的評分乘積之和 sumM = sum([critics[person1][name] * critics[person2][name] for name in result])
n
= len(result) num = sumM - (sum1 * sum2 / n) den = sqrt((sum1Sq - pow(sum1, 2)/n) * (sum2Sq - pow(sum2, 2)/n)) if 0 == den: return 0 return (num/den)

注:皮爾遜相關度的計算中,如果某人總是傾向於給出比另一個人更高的分值,而兩者的分值之差又始終保持一致,則他們依然可能會存在很好的相關性。畢竟,這個方法認為最相關的時候就是“y=x”直線的時候。

3、提供推薦

①為評論者打分:

#為評論者打分
#計算其他使用者與某一使用者的相似度,並且排序
def sort_simulation (critics, person, simularity):
    result = [(simularity(critics, person, other), other) for other in critics if other != person]
    result.sort()
    result.reverse()
    return result

相似度越大,說明兩個人越具有相近的品味

②推薦物品:通過一個經過加權的評價值來為影片打分,並推薦給對應的影評者

#提供推薦
#根據與其他使用者的相似度,向用戶推薦電影
def get_recommendations(critics, person, simularity):
    sum = {}
    sumS = {}
    #計算出與不同使用者的相似度
    result = sort_simulation(critics, person, simularity) 
    #遍歷每個其他使用者的評分
    for i in range(0, len(result)):
        if 0 > result[i][0]: continue
        for movie in critics[result[i][1]]:
            #找到別人看過並且自己沒有看過的電影
            if movie in critics[result[i][1]] and movie not in critics[person]:
                sum.setdefault(movie, 0)
                #相似度*評分
                sum[movie] = sum[movie] + result[i][0] * critics[result[i][1]][movie]
                sumS.setdefault(movie, 0)
                #相似度之和
                sumS[movie] += result[i][0]
    #建立歸一化的表
    rank = [(sum[movie]/sumS[movie], movie) for movie in sum]
    rank.sort()
    rank.reverse()
    return (rank)

③匹配商品:通過將資料集中的人員和物品對換,構建新的資料集即可。

#將人名和電影名轉換
def tranfer_name(critics):
    result = {}
    for name in critics:
        for movie in critics[name]:
            result.setdefault(movie, {})
            result[movie][name] = critics[name][movie]
    return result

4、基於使用者進行過濾還是基於物品進行過濾?

協作型過濾:對一大群人進行搜尋並給出與我們相近的人的排名列表。

密集資料集:在涉及電影的例子中,由於每個評論者幾乎對他看過的每部影片都做過評價,所以資料集是密集的。

稀疏資料集:而每部電影並不會被所有的使用者評價,只有看過的使用者才會評價,這就形成了一個稀疏資料集。

基於使用者進行過濾和基於物品進行過濾最顯著的區別:物品間的比較不會像使用者間的比較那麼頻繁變化。

在擁有大量資料集的情況下,基於物品的協作型過濾能夠得出更好的結論,而且它允許我們將大量計算任務預先執行,從而使需要給予推薦的使用者能夠快速地得到他們所要的結果。

對於稀疏資料集,基於物品的過濾方法通常要優於基於使用者的過濾方法,而對於密集資料集而言,兩者的效果則幾乎是一樣的。

 

對商品推薦的一個通俗的解釋:

基於使用者的協同過濾基本思想非常簡單,就是找到志同道合的朋友,並把朋友感興趣的而使用者沒有接觸過的商品推薦給使用者。

但是這有一個問題,由於新使用者的註冊量非常高,基於使用者的協同過濾推薦需要計算新使用者和之前的使用者之間的相似度,這會將資料稀疏,延展性差等問題暴露的非常明顯。

所以基於商品的協同過濾方法被提出,相較於使用者之間的相似度,商品之間的相似度相對是靜態的,當新使用者註冊並有了一些自己感興趣的商品資訊時,無需再進行計算,直接根據之前儲存的商品之間的相似度,將使用者可能感興趣的商品推薦給使用者。

參考:

https://www.cnblogs.com/xiaoYu3328/p/5173854.html

https://blog.csdn.net/u014473918/article/details/79771558