基于用户的协同过滤(user-based collaborative filtering)
姓名:wagsyang?
日期:星期四, 08. 十二月 2016 03:25下午
簡介
本文是集體智慧編程一書的學習筆記。一個協作型過濾算法通常是對一大群人進行搜索,并從中找出與我們品味相近的一小群人。算法會對這些人所偏愛的其它內容進行考察,并將它們組合起來構造出一個經過排名的推薦列表。
收集偏好
我們要對不同的人和他對某個事物的偏好找一種表達方式,這里的研究對象是某人對它看過的電影的評價,評分由1到5。
#基于用戶的協同過濾 critics={\ 'Lisa Rose':{'lady in 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 water':3.0,'snakes on a plane':3.5,'just my luck':1.5,'superman returns':5.0,'you,me and dupree':3.5,'the night listener':3.0},'Michael Phillips':{'lady in 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,'superman returns':4.0,'the night listener':4.5},'Mick Lasalle':{'lady in water':3.0,'snakes on a plane':4.0,'just my luck':2.0,'superman returns':3.0,'you,me and dupree':2.0,'the night listener':3.0},'Jack Matthews':{'lady in water':3.0,'snakes on a plane':4.0,'superman returns':5.0,'you,me and dupree':3.5,'the night listener':3.0},'Toby':{'snakes on a plane':4.5,'superman returns':4.0,'you,me and dupree':1.0}}尋找相近的用戶
我們已經有了以上的數據,現在我們給你一個人H以及H所看過的電影的評分,怎樣判斷H與以上哪些人相似度最高?度量相似度的準則又是什么?這里我們介紹兩種計算相似度的評價準則。歐幾里德距離和皮爾遜相關度。
歐幾里德距離?
歐幾里德距離就是兩個點的空間距離:
(1)式可以計算出距離值,偏好越相似的人,其距離就越短。我們現在需要一個函數,表示偏好越相近這個函數值就越大。我們可以這樣:
但是萬一當distance=0,(2)就有問題了,我們修正一下,再加一項:
下面我們用pyhton程序表示兩個人基于歐幾里德距離的相似度:
from math import sqrt #歐幾里德距離 def sim_distance(prefs,p1,p2):si={}# find common itemsfor item in prefs[p1]:if item in prefs[p2]: si[item]=1if len(si)==0: return 0#cal the distancesum_of_sqr=sum([pow(prefs[p1][item]-prefs[p2][item],2) for item in si]) return 1/(1+sqrt(sum_of_sqr))皮爾遜相關度?
對于歐幾里德距離的相似度評價標準,如果某個人總是傾向于給出比本來與他有極高相似度的人高(低)的分數,比如:
person1={film1:2.1,film2:3.1 ,film:4.1}?
person2={film1:2.9,film2:3.9 ,film:4.9}
計算出的歐幾里德距離的值是很大的,是不相似的(較person3 =(2.1,2.6,3.6)),計算出這樣的結果是因為person1內心的標準較person2更為嚴(zhuang)苛(bi),每個電影都比其他人給分低。但實際上這兩人是品味相同的。?
所以,直接計算歐式距離確實簡單,但有不足。如果我們用一條直線能夠很好擬合這倆人的數據,就像上面的倆人,這肯定是極好的。因此,我們可以定義一種度量擬合程度的東西。這個東西就是皮爾遜相關度:
關于皮爾遜相關度的定義和推導請參考概率論與數理統計。?
代碼實現:
還有其它相似度的評價準則,比如:Jaccard系數,曼哈頓距離,這里不做介紹。
為相近的人打分
我們知道了如何計算兩個人的相關度,下面我們將所有的人同自己作相關度計算,算出和自己相關度從高到低的排名。這里我們的樣本比較少,就不做排名了,將全部人當作品味相近的那一小群人。
排名結果如下:
| Rose | 0.99 | 3.0 | 2.97 | 2.5 | 2.48 | 3.0 | 2.97 |
| Seymour | 0.38 | 3.0 | 1.14 | 3.0 | 1.14 | 1.5 | 0.57 |
| Puig | 0.89 | 4.5 | 4.02 | ? | ? | 3.0 | 2.68 |
| LaSalle | 0.92 | 3.0 | 2.77 | 3.0 | 2.77 | 2.0 | 1.85 |
| Matthews | 0.66 | 3.0 | 1.99 | 3.0 | 1.99 | ? | ? |
| Total | ? | ? | 12.89 | ? | 8.38 | ? | 8.07 |
| Sim.Sum | ? | ? | 3.84 | ? | 2.95 | ? | 3.18 |
| Total/Sim.Sum | ? | ? | 3.35 | ? | 2.83 | ? | 2.53 |
其中,以S.開頭的值等于和某個人的相似度乘以他對某一電影的評分,這樣,和我們品味相同的人它們的相似度高,自然占的比重就大,這也正是推薦的本意了。其實我們可以直接用Total的值來進行推薦了,但是有一些人沒有看過某個電影,其評分為空,如果我們還按Total值來推薦,勢必會有這種結果:某一個電影很多人都看過,其Total值非常非常大,而一個小眾的電影,很少人看過(但實際它很符合你的口味),其Total值就非常小,這個Total值小的電影就不會被推薦給你,這是你我都不會同意的。因此,考慮到沒被看過的電影的空值項,我們可以將Total值除以看過這部電影的人的相似度之和,即:?
代碼實現如下:#獲得推薦 def get_recommendations(prefs,person,similarity):totals={}simsum={}for other in prefs:#dont compare to myselfif other==person: continuesim=similarity(prefs,person,other)#loop out if there is no similarityif sim<=0 : continuefor item in prefs[other]:#recommend a film I have never watchedif item not in prefs[person]:#value*simtotals.setdefault(item,0)totals[item]+=prefs[other][item]*sim#sum of simsimsum.setdefault(item,0)simsum[item]+=sim#recommand list rankings=[(value/simsum[item],item) for item, value in totals.items()]#recommand list rankings.sort(reverse=True)return rankings
總結
基于用戶的協同過濾推薦思路是這樣的:
我&我看過的電影?根據相似度度量準則>根據相似度度量準則>?臭味相投的人(座次:甲乙丙丁)電影按公式(5)排座次>電影按公式(5)排座次>它們看過的電影(排名:子丑寅卯)推薦哪個?>推薦哪個?>第一個錯不了
版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/wagsyang/article/details/53575818總結
以上是生活随笔為你收集整理的基于用户的协同过滤(user-based collaborative filtering)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在网页中使用个性字体
- 下一篇: threejs 的思维导图