初探推薦算法

聲明:以下是學習《集體編程智慧》的筆記普舆,代碼使用python編寫恬口。
需要有python自定義函數(shù)的知識,以及事先了解皮爾森相關系數(shù)的公式

網(wǎng)上總是有人吐槽:“XX的算法很可笑奔害,老是給我推薦我不想要的東西”楷兽。作為非計算機專業(yè)的普通人,一直不太明白何謂“算法”华临。比如豆瓣是怎么給我推薦我喜歡的電影的。就目前我的理解端考,就是通過某些數(shù)學公式雅潭,把我的興趣跟別人的興趣作比較,得出一個關聯(lián)度却特。而書中講述了如何用代碼實現(xiàn)扶供。

一個例子

書中給到一個很簡單的例子,大概是說每個用戶裂明,對每部電影的評分椿浓,構成一個字典,即由“用戶——電影名——評分”構成的字典闽晦。

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}}

所以我們對其建立一個名為recommendations.py的文件扳碍,執(zhí)行:

from recommendations import critics
critics['Lisa Rose']['Lady in the Water']

就會得到2.5的結果。(跟翻字典一樣仙蛉,找到聲母笋敞、韻母就會得出對應的字)


如何考察兩個人的口味?這里就要把文字描述落地到圖表了:

尋找相近的用戶1——歐幾里得距離評價

python.png

上圖簡單展示了如何判斷兩個人的相似度——Toby和LaSalle的相似度就比和Seymour的相似度更大(坐標距離可見)荠瘪,計算距離我們用各自橫豎坐標差值平方和的開方(好拗口)表示:

from math import sqrt
sqrt(pow(4.5-4,2)+pow(1-2,2))

結果為1.118033988749895
當然夯巷,數(shù)字越小,距離越近哀墓,相關度越大趁餐。
但為了好記憶,我們希望數(shù)字越大篮绰,相關度越大后雷,就這么處理:

1/(1+sqrt(pow(4.5-4,2)+pow(1-2,2)))

分母加1是為了避免距離為零的時候出現(xiàn)錯誤。

尋找相近的用戶2——皮爾森相關度評價

(此段需要皮爾森相關函數(shù)的知識)
原因:皮爾森相關度評價的出現(xiàn)是源于對數(shù)據(jù)不規(guī)范時的考慮——如果影評者對影片的評論總是相對于平均水平偏離很大時(比如苛刻的影評者普遍給低分)——依然能給出合理的相關度評論阶牍。
方法:判斷兩組數(shù)據(jù)與某一直線的擬合程度
注意:皮爾森相關度是基于對物品距離的計算

python2.png

上圖是相關度不盡相同的情況喷面,而下圖是相關度趨于一致的情況

python3.png

這里Jack總是傾向比Lisa給出更高分值,但不影響我們判斷他倆有相似偏好(因為他們有趨同性)
在recommendations.py文件下def sim_pearson走孽,用于 判斷倆人的相似度


def sim_distance(prefs,person1,person2): 
  # 得到shared_items的列表
  si={}
  for item in prefs[person1]: 
    if item in prefs[person2]: si[item]=1

  # 如果兩者沒有共同之處惧辈,則返回0
  if len(si)==0: return 0

  # 計算所有差值的平方和
  sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2) 
                      for item in prefs[person1] if item in prefs[person2]])

  return 1/(1+sum_of_squares)

執(zhí)行

print recommendations.sim_pearson(recommendations.critics,'Lisa Rose','Gene Seymour')

得到0.396059017191


推薦相似的人

而我們日常更常出現(xiàn)的需求是:知道一個人的愛好,向其推薦有共同喜好的人或可能會喜好的物磕瓷。
在recommendations.py文件下def topMatches盒齿,用于給待推薦的人打分

# 從反映偏好的字典中返回最為匹配者
# 返回結果的個數(shù)和相似度函數(shù)均為可選參數(shù)
def topMatches(prefs,person,n=5,similarity=sim_pearson):
  scores=[(similarity(prefs,person,other),other) 
                  for other in prefs if other!=person]
  scores.sort()
  scores.reverse()
  return scores[0:n]

# 利用所有他人評價值的加權平均念逞,為某人提供建議
# of every other user's rankings
def getRecommendations(prefs,person,similarity=sim_pearson):
  totals={}
  simSums={}
  for other in prefs:
    # 不和自己做比較
    if other==person: continue
    sim=similarity(prefs,person,other)

    # 忽略評價值為零或小于零的情況
    if sim<=0: continue
    for item in prefs[other]:
        
      #只對自己還未曾看過的影片進行評價
      if item not in prefs[person] or prefs[person][item]==0:
        # 相似度*評價值
        totals.setdefault(item,0)
        totals[item]+=prefs[other][item]*sim
        #相似度之和
        simSums.setdefault(item,0)
        simSums[item]+=sim

  # 建立規(guī)范化列表
  rankings=[(total/simSums[item],item) for item,total in totals.items()]

  # 返回經(jīng)過排序的列表
  rankings.sort()
  rankings.reverse()
  return rankings

這里,以找出跟Toby最接近的三個人為例:

import recommendations
recommendations.topMatches(recommendations.critics,'Toby',n=3)

得出

 (0.9244734516419049, 'Mick LaSalle'),
 (0.8934051474415647, 'Claudia Puig')]```

***

####推薦物品
書中用了一個表格來展示這個過程:
![python4.png](http://upload-images.jianshu.io/upload_images/1638110-379fdac8b939bcab.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
比如要為Toby推薦電影边翁,得從他沒看過的電影里找翎承,對這些沒看過的電影,用歐幾里得距離得出其他人跟Toby的相似度(加權)符匾,分別乘以他們對這些電影的評價叨咖,得出電影的得分(S.x列),再進行加總啊胶。
然而有個情況是某個人沒看過某電影甸各,(如Puig沒看過Lady),那Lady的總評分不是相對少了嗎焰坪。
所以我們還要做一個動作是:用總計除以有評論的人的相似度之和(Sim.Sum)(相當于減權)趣倾,就會得到相對公正的結果。

在recommendations.py文件下是這么實現(xiàn)的

利用所有他人評價值的加權平均某饰,為某人提供建議

def getRecommendations(prefs,person,similarity=sim_pearson):
totals={}
simSums={}
for other in prefs:
# 不和自己做比較
if other==person: continue
sim=similarity(prefs,person,other)

# 忽略評價值為零或小于零的情況
if sim<=0: continue
for item in prefs[other]:
    
  #只對自己還未曾看過的影片進行評價
  if item not in prefs[person] or prefs[person][item]==0:
    # 相似度*評價值
    totals.setdefault(item,0)
    totals[item]+=prefs[other][item]*sim
    #相似度之和
    simSums.setdefault(item,0)
    simSums[item]+=sim

建立規(guī)范化列表

rankings=[(total/simSums[item],item) for item,total in totals.items()]

返回經(jīng)過排序的列表

rankings.sort()
rankings.reverse()
return rankings

執(zhí)行

recommendations.getRecommendations(recommendations.critics,'Toby')

得到
```[(3.3477895267131013, 'The Night Listener'),
 (2.8325499182641614, 'Lady in the Water'),
 (2.5309807037655645, 'Just My Luck')]```
嗯儒恋,Toby可能更喜歡'The Night Listener'

以上是基于“人”的推薦,如果我們想知道哪些商品有相似性呢黔漂?
***
####相似商品推薦

只需將人和物進行對調:

把```{'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}} ```
變成```{'Lady in the Water':{'Lisa Rose':2.5,'Gene Seymour':3.0}, 'Snakes on a Plane':{'Lisa Rose':3.5,'Gene Seymour': 3.5} etc}```

在recommendations.py文件下

def transformPrefs(prefs):
result={}
for person in prefs:
for item in prefs[person]:
result.setdefault(item,{})

  # 將物品和人員對調
  result[item][person]=prefs[person][item]

return result

試試:

movies=recommendations.transformPrefs(recommendations.critics)
recommendations.topMatches(movies,'Superman Returns')

得到:
```[(0.6579516949597695, 'You, Me and Dupree'),
 (0.4879500364742689, 'Lady in the Water'),
 (0.11180339887498941, 'Snakes on a Plane'),
 (-0.1798471947990544, 'The Night Listener'),
 (-0.42289003161103106, 'Just My Luck')]```
也可以基于電影得出“喜歡它的人”

recommendations.getRecommendations(movies,'Just My Luck')

```[(4.0, 'Michael Phillips'), (3.0, 'Jack Matthews')]```


>學到哪兒诫尽,寫到哪兒。暫告一段落瘟仿。


>本人最近在求職箱锐,坐標北京,數(shù)據(jù)分析相關劳较,行業(yè)不限驹止,希望看到的簡友幫忙推薦,當然也希望HR能看到
.
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末观蜗,一起剝皮案震驚了整個濱河市臊恋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌墓捻,老刑警劉巖抖仅,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異砖第,居然都是意外死亡撤卢,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門梧兼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來放吩,“玉大人,你說我怎么就攤上這事羽杰《勺希” “怎么了到推?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惕澎。 經(jīng)常有香客問我莉测,道長,這世上最難降的妖魔是什么唧喉? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任捣卤,我火速辦了婚禮,結果婚禮上八孝,老公的妹妹穿的比我還像新娘腌零。我一直安慰自己,他們只是感情好唆阿,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著锈锤,像睡著了一般驯鳖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上久免,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天浅辙,我揣著相機與錄音,去河邊找鬼阎姥。 笑死记舆,一個胖子當著我的面吹牛,可吹牛的內容都是我干的呼巴。 我是一名探鬼主播泽腮,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼衣赶!你這毒婦竟也來了诊赊?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤府瞄,失蹤者是張志新(化名)和其女友劉穎碧磅,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遵馆,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡鲸郊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了货邓。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秆撮。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖逻恐,靈堂內的尸體忽然破棺而出像吻,到底是詐尸還是另有隱情峻黍,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布拨匆,位于F島的核電站姆涩,受9級特大地震影響,放射性物質發(fā)生泄漏惭每。R本人自食惡果不足惜骨饿,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望台腥。 院中可真熱鬧宏赘,春花似錦、人聲如沸黎侈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽峻汉。三九已至贴汪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間休吠,已是汗流浹背扳埂。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瘤礁,地道東北人阳懂。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像柜思,于是被迫代替她去往敵國和親岩调。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內容

  • critics={'Lisa Rose':{'Lady in the Water':2.5, 'Snakes on...
    三盞燈亮一盞閱讀 769評論 1 0
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理酝蜒,服務發(fā)現(xiàn)誊辉,斷路器,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • 1. 機器學習基本概念 1.1 什么是機器學習 機器學習(Machine Learning)是一種基本數(shù)據(jù)的學習亡脑,...
    ZPPenny閱讀 4,328評論 0 10
  • 多少人曾夢想著回到過去霉咨,多少人又曾幻想過未來蛙紫。白駒過隙,時光如梭……我們都在慢慢長大途戒,慢慢改變 長大坑傅?只是簡單的個...
    Real_laying閱讀 717評論 0 0
  • 我們最幸運的事是,我們遇到了一個大的風口喷斋,一個一個正在崛起的時代唁毒,一個復興中的祖國蒜茴。如果你自己有這個能力,或者有這...
    離瀟閱讀 189評論 0 0