基于用户的协同过滤(user-based collaborative filtering)
姓名:wagsyang?
日期:星期四, 08. 十二月 2016 03:25下午
簡(jiǎn)介
本文是集體智慧編程一書(shū)的學(xué)習(xí)筆記。一個(gè)協(xié)作型過(guò)濾算法通常是對(duì)一大群人進(jìn)行搜索,并從中找出與我們品味相近的一小群人。算法會(huì)對(duì)這些人所偏愛(ài)的其它內(nèi)容進(jìn)行考察,并將它們組合起來(lái)構(gòu)造出一個(gè)經(jīng)過(guò)排名的推薦列表。
收集偏好
我們要對(duì)不同的人和他對(duì)某個(gè)事物的偏好找一種表達(dá)方式,這里的研究對(duì)象是某人對(duì)它看過(guò)的電影的評(píng)價(jià),評(píng)分由1到5。
#基于用戶的協(xié)同過(guò)濾 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}}尋找相近的用戶
我們已經(jīng)有了以上的數(shù)據(jù),現(xiàn)在我們給你一個(gè)人H以及H所看過(guò)的電影的評(píng)分,怎樣判斷H與以上哪些人相似度最高?度量相似度的準(zhǔn)則又是什么?這里我們介紹兩種計(jì)算相似度的評(píng)價(jià)準(zhǔn)則。歐幾里德距離和皮爾遜相關(guān)度。
歐幾里德距離?
歐幾里德距離就是兩個(gè)點(diǎn)的空間距離:
(1)式可以計(jì)算出距離值,偏好越相似的人,其距離就越短。我們現(xiàn)在需要一個(gè)函數(shù),表示偏好越相近這個(gè)函數(shù)值就越大。我們可以這樣:
但是萬(wàn)一當(dāng)distance=0,(2)就有問(wèn)題了,我們修正一下,再加一項(xiàng):
下面我們用pyhton程序表示兩個(gè)人基于歐幾里德距離的相似度:
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))皮爾遜相關(guān)度?
對(duì)于歐幾里德距離的相似度評(píng)價(jià)標(biāo)準(zhǔn),如果某個(gè)人總是傾向于給出比本來(lái)與他有極高相似度的人高(低)的分?jǐn)?shù),比如:
person1={film1:2.1,film2:3.1 ,film:4.1}?
person2={film1:2.9,film2:3.9 ,film:4.9}
計(jì)算出的歐幾里德距離的值是很大的,是不相似的(較person3 =(2.1,2.6,3.6)),計(jì)算出這樣的結(jié)果是因?yàn)閜erson1內(nèi)心的標(biāo)準(zhǔn)較person2更為嚴(yán)(zhuang)苛(bi),每個(gè)電影都比其他人給分低。但實(shí)際上這兩人是品味相同的。?
所以,直接計(jì)算歐式距離確實(shí)簡(jiǎn)單,但有不足。如果我們用一條直線能夠很好擬合這倆人的數(shù)據(jù),就像上面的倆人,這肯定是極好的。因此,我們可以定義一種度量擬合程度的東西。這個(gè)東西就是皮爾遜相關(guān)度:
關(guān)于皮爾遜相關(guān)度的定義和推導(dǎo)請(qǐng)參考概率論與數(shù)理統(tǒng)計(jì)。?
代碼實(shí)現(xiàn):
還有其它相似度的評(píng)價(jià)準(zhǔn)則,比如:Jaccard系數(shù),曼哈頓距離,這里不做介紹。
為相近的人打分
我們知道了如何計(jì)算兩個(gè)人的相關(guān)度,下面我們將所有的人同自己作相關(guān)度計(jì)算,算出和自己相關(guān)度從高到低的排名。這里我們的樣本比較少,就不做排名了,將全部人當(dāng)作品味相近的那一小群人。
排名結(jié)果如下:
| 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.開(kāi)頭的值等于和某個(gè)人的相似度乘以他對(duì)某一電影的評(píng)分,這樣,和我們品味相同的人它們的相似度高,自然占的比重就大,這也正是推薦的本意了。其實(shí)我們可以直接用Total的值來(lái)進(jìn)行推薦了,但是有一些人沒(méi)有看過(guò)某個(gè)電影,其評(píng)分為空,如果我們還按Total值來(lái)推薦,勢(shì)必會(huì)有這種結(jié)果:某一個(gè)電影很多人都看過(guò),其Total值非常非常大,而一個(gè)小眾的電影,很少人看過(guò)(但實(shí)際它很符合你的口味),其Total值就非常小,這個(gè)Total值小的電影就不會(huì)被推薦給你,這是你我都不會(huì)同意的。因此,考慮到?jīng)]被看過(guò)的電影的空值項(xiàng),我們可以將Total值除以看過(guò)這部電影的人的相似度之和,即:?
代碼實(shí)現(xiàn)如下:#獲得推薦 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
總結(jié)
基于用戶的協(xié)同過(guò)濾推薦思路是這樣的:
我&我看過(guò)的電影?根據(jù)相似度度量準(zhǔn)則>根據(jù)相似度度量準(zhǔn)則>?臭味相投的人(座次:甲乙丙丁)電影按公式(5)排座次>電影按公式(5)排座次>它們看過(guò)的電影(排名:子丑寅卯)推薦哪個(gè)?>推薦哪個(gè)?>第一個(gè)錯(cuò)不了
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。 https://blog.csdn.net/wagsyang/article/details/53575818總結(jié)
以上是生活随笔為你收集整理的基于用户的协同过滤(user-based collaborative filtering)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在网页中使用个性字体
- 下一篇: threejs 的思维导图