【火爐煉AI】機器學(xué)習(xí)033-構(gòu)建電影推薦系統(tǒng)

【火爐煉AI】機器學(xué)習(xí)033-構(gòu)建電影推薦系統(tǒng)

(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )

電影推薦系統(tǒng)內(nèi)部最關(guān)鍵的部件是推薦引擎腊满,和汽車的發(fā)動機一樣,推薦引擎的作用是產(chǎn)生數(shù)據(jù)動力排惨,提供數(shù)據(jù)計算方案涩堤。從本質(zhì)上說,推薦引擎時一個能預(yù)測用戶興趣點的模型故俐。對于不同的具體項目要求想鹰,推薦引擎也是不一樣的,本文主要介紹專門用于電影推薦系統(tǒng)的推薦引擎構(gòu)建方法药版。

推薦引擎非常重要辑舷,比如在電商網(wǎng)站中,經(jīng)常有龐大的商品目錄槽片,而用戶不太可能查找所有的相關(guān)內(nèi)容何缓,這時候就需要推薦引擎來構(gòu)建合適的推薦系統(tǒng),將用戶可能感興趣的商品推薦到用戶頁面还栓。我們經(jīng)常在購物中看到碌廓,你點擊了筆記本電腦的頁面,系統(tǒng)會給你推薦鼠標剩盒,鍵盤等商品谷婆,其內(nèi)部就是使用了推薦引擎。


1. 尋找數(shù)據(jù)集中的相似用戶

推薦引擎的一個非常重要的任務(wù)是尋找相似的用戶,這樣纪挎,為一位用戶生成的推薦信息也可以推送給與之相似的其他用戶期贫。

下面用代碼來查找與特定用戶相似的其他用戶,用到了上一篇文章中的Pearson 相關(guān)系數(shù)計算函數(shù)廷区。下面代碼的思路是:首先判斷user是否存在dataset中唯灵,然后計算user對所有其他user的相關(guān)系數(shù),放置到一個list中隙轻,然后再對這個list進行逆序排列埠帕,取最前面的K個用戶,即可找到與user最相似的K個用戶玖绿。

def find_similar_users(dataset, user, user_num=3):
    if user not in dataset: # 首先保證user在dataset中
        raise TypeError('User {} not in dataset!'.format(user))
    
    # 對于所有用戶敛瓷,計算其與user的相似度,此處使用Pearson相關(guān)性
    scores=np.array([[other_user,pearson_score(dataset,user,other_user)] for 
                         other_user in dataset if other_user!=user])
    # 相關(guān)性都存放在scores這個二維矩陣中斑匪,故而可以通過排序來尋找相似用戶
    scores_sorted=np.argsort(scores[:,1])[::-1] # 先排序取坐標呐籽,再逆序
    # 獲取最前面的user_num個相似用戶
    top_users=scores_sorted[:user_num]
    return scores[top_users] # 返回這些user的信息

通過導(dǎo)入movie_ratings數(shù)據(jù)后,計算與John Carson最相似的4個用戶蚀瘸,如下:

# 使用電影數(shù)據(jù)來尋找相似用戶
import json
with open("E:\PyProjects\DataSet\FireAI\movie_ratings.json",'r') as file:
    dataset=json.loads(file.read())

user='John Carson'
similar_users=find_similar_users(dataset, user, 4)
print('Users similar to {}---->>>'.format(user))
print('User\t\t\tSimilarity Score\n')
for item in similar_users:
    print('{}\t\t{}'.format(item[0],round(float(item[1]),3)))

-------------------------------------輸---------出--------------------------------

Users similar to John Carson---->>>
User Similarity Score

Michael Henry 0.991
Alex Roberts 0.747
Melissa Jones 0.594
Jillian Hobart 0.567

--------------------------------------------完-------------------------------------


2. 創(chuàng)建電影推薦引擎

假設(shè)我們現(xiàn)在有多個用戶對某幾部電影的評價分數(shù)狡蝶,那么怎么構(gòu)建一個電影推薦引擎?給那些已經(jīng)看過一部分電影的用戶推薦其他沒有看過的但是很相關(guān)的電影贮勃?

這些電影評分數(shù)據(jù)都存放在movie_ratings.json文件中贪惹,這個文件的第一個層是用戶名,第二層是電影名稱和該用戶給該電影的評分寂嘉。給用戶A推薦電影的內(nèi)在邏輯是奏瞬,先找出與用戶A相似度比較高的多個用戶,然后找出這些相似用戶已經(jīng)評分過但是用戶A沒有評分的電影集合泉孩,這些電影表示用戶A沒有看過但是其他相似用戶看過硼端,我們推薦的電影就從這個電影集合中選取,那么怎么選取了寓搬?需要構(gòu)建一個選取標準珍昨,此時我們可以計算電影推薦分數(shù),該分數(shù)用相似度和電影評價分數(shù)相乘得到句喷×偷洌可以認為,相似度越高的用戶脏嚷,其看過的電影越推薦,這些用戶評分越高的電影瞒御,表示質(zhì)量越高父叙,越要推薦給用戶A.

基于以上邏輯,編寫的代碼如下:

# 創(chuàng)建電影推薦引擎
def get_recommendations(dataset,user):
    if user not in dataset: # 首先保證user在dataset中
        raise TypeError('User {} not in dataset!'.format(user))
    
    total_scores={} # 存放的key為電影名稱,value為對該電影的評價乘以相似度
    similarity_sums={} # 存放的key為電影名稱趾唱,value為相似度
    for other_user in dataset:
        if other_user ==user: continue  # 確保是其他用戶而非自身
        similarity_score=pearson_score(dataset,user, other_user) 
#         print('other user: ', other_user, 'similarity: ', similarity_score)
        if similarity_score<=0: continue # 如果相似度太小則忽略
        
        # 找到還未被該用戶評分,但是卻被other_user評分過的電影
        # 這部分電影表示相似的other_ser已經(jīng)看過但是user沒有看過的電影涌乳,
        # 推薦的電影肯定來自于這部分
        user_not_rating_movies=[]
        for movie in dataset[other_user]: # other_user評分過的電影
#             if movie not in dataset[user] or dataset[user][movie]==0: 
            if movie not in dataset[user]: 

                # 但是user沒有評分過,或者user評分為0(是不是系統(tǒng)認為沒有評分那評分就是0))
                user_not_rating_movies.append(movie)
#         print(user_not_rating_movies)
        # 計算這些user沒有評分過的電影的推薦分數(shù)甜癞,
        # 推薦分數(shù)此處用該電影的評價乘以相似度表示
        for movie in user_not_rating_movies:
            recommend_score=dataset[other_user][movie]*similarity_score
            total_scores.update({movie: recommend_score})
            similarity_sums.update({movie: similarity_score})
#         print('other user: ', other_user, 'total_scores: ', total_scores)
    # 判斷total_scores夕晓,如果推薦的總數(shù)為0,表示所有電影都被user評價過悠咱,則不推薦
    if len(total_scores) ==0: return [[0,'No Recommendations']]
    
    # 計算每個電影的推薦等級
    movie_ranks=np.array([[rec_score/similarity_sums[movie],movie] for 
                         movie, rec_score in total_scores.items()])
    # 對第一列進行逆序排列
    movie_ranks_desc=movie_ranks[np.argsort(movie_ranks[:,0])[::-1]]
#     print(movie_ranks_desc)
    return movie_ranks_desc

最后計算一下幾個用戶的推薦的電影列表蒸辆,如下:

import json
with open("E:\PyProjects\DataSet\FireAI\movie_ratings.json",'r') as file:
    dataset=json.loads(file.read())

user='John Carson'
movie_ranks=get_recommendations(dataset,user)
print('Recommended movies to {}---->>>'.format(user))
for idx, recommend in enumerate(movie_ranks):
    print('{}: {}-->recommend score: {}'.format(idx, recommend[1], recommend[0]))

user='Michael Henry'
movie_ranks=get_recommendations(dataset,user)
print('Recommended movies to {}---->>>'.format(user))
for idx, recommend in enumerate(movie_ranks):
    print('{}: {}-->recommend score: {}'.format(idx, recommend[1], recommend[0]))

-------------------------------------輸---------出--------------------------------

Recommended movies to John Carson---->>>
0: No Recommendations-->recommend score: 0
Recommended movies to Michael Henry---->>>
0: Jerry Maguire-->recommend score: 3.0
1: Inception-->recommend score: 3.0
2: Anger Management-->recommend score: 2.0

--------------------------------------------完-------------------------------------

########################小**********結(jié)###############################

1,構(gòu)建電影推薦系統(tǒng)一般有幾個步驟:先找出相似用戶析既,然后找出相似用戶看過的電影而用戶A沒有看過的電影躬贡,最后對這些電影建立一種推薦分數(shù),其分數(shù)越高的越值得推薦眼坏,最后對這些分數(shù)逆序排列拂玻,即可得到推薦列表。

2宰译,關(guān)鍵是要搞清楚推薦邏輯檐蚜,并建立推薦算法,這些算法可能會隨實際應(yīng)用場景不同而不同沿侈。

#################################################################


注:本部分代碼已經(jīng)全部上傳到(我的github)上闯第,歡迎下載。

參考資料:

1, Python機器學(xué)習(xí)經(jīng)典實例肋坚,Prateek Joshi著乡括,陶俊杰,陳小莉譯

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末智厌,一起剝皮案震驚了整個濱河市诲泌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铣鹏,老刑警劉巖敷扫,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異诚卸,居然都是意外死亡葵第,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門合溺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卒密,“玉大人,你說我怎么就攤上這事棠赛∠妫” “怎么了膛腐?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鼎俘。 經(jīng)常有香客問我哲身,道長,這世上最難降的妖魔是什么贸伐? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任勘天,我火速辦了婚禮,結(jié)果婚禮上捉邢,老公的妹妹穿的比我還像新娘脯丝。我一直安慰自己,他們只是感情好歌逢,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布巾钉。 她就那樣靜靜地躺著,像睡著了一般秘案。 火紅的嫁衣襯著肌膚如雪砰苍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天阱高,我揣著相機與錄音赚导,去河邊找鬼。 笑死赤惊,一個胖子當著我的面吹牛吼旧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播未舟,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼圈暗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了裕膀?” 一聲冷哼從身側(cè)響起员串,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昼扛,沒想到半個月后寸齐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡抄谐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年渺鹦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛹含。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡毅厚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出浦箱,到底是詐尸還是另有隱情吸耿,我是刑警寧澤殴边,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站珍语,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏竖幔。R本人自食惡果不足惜板乙,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拳氢。 院中可真熱鬧募逞,春花似錦、人聲如沸馋评。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽留特。三九已至纠脾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蜕青,已是汗流浹背苟蹈。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留右核,地道東北人慧脱。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像贺喝,于是被迫代替她去往敵國和親菱鸥。 傳聞我的和親對象是個殘疾皇子根资,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容