不到40行代碼用Python實(shí)現(xiàn)一個(gè)簡(jiǎn)單的推薦系統(tǒng)
什么是推薦系統(tǒng)
維基百科這樣解釋道:推薦系統(tǒng)屬于資訊過(guò)濾的一種應(yīng)用。推薦系統(tǒng)能夠?qū)⒖赡苁芟埠玫馁Y訊或?qū)嵨铮ɡ纾弘娪?、電視?jié)目、音樂(lè)、書(shū)籍、新聞、圖片、網(wǎng)頁(yè))推薦給使用者。
本質(zhì)上是根據(jù)用戶的一些行為數(shù)據(jù)有針對(duì)性的推薦用戶更可能感興趣的內(nèi)容。比如在網(wǎng)易云音樂(lè)聽(tīng)歌,聽(tīng)得越多,它就會(huì)推薦越多符合你喜好的音樂(lè)。
推薦系統(tǒng)是如何工作的呢?有一種思路如下:
用戶 A 聽(tīng)了 收藏了 a,b,c 三首歌。用戶 B 收藏了 a, b 兩首歌,這時(shí)候推薦系統(tǒng)就把 c 推薦給用戶 B。因?yàn)樗惴ㄅ袛嘤脩?A,B 對(duì)音樂(lè)的品味有極大可能一致。
推薦算法分類
最常見(jiàn)的推薦算法分為基于內(nèi)容推薦以及協(xié)同過(guò)濾。協(xié)同過(guò)濾又可以分為基于用戶的協(xié)同過(guò)濾和基于物品的協(xié)同過(guò)濾
基于內(nèi)容推薦是直接判斷所推薦內(nèi)容本身的相關(guān)性,比如文章推薦,算法判斷某篇文章和用戶歷史閱讀文章的相關(guān)性進(jìn)行推薦。
基于用戶的協(xié)同過(guò)濾就是文章開(kāi)頭舉的例子。
基于物品的協(xié)同過(guò)濾:
假設(shè)用戶 A,B,C 都收藏了音樂(lè) a,b。然后用戶 D 收藏了音樂(lè) a,那么這時(shí)候就推薦音樂(lè) b 給他。
動(dòng)手打造自己的推薦系統(tǒng)
這一次我們要做的是一個(gè)簡(jiǎn)單的電影推薦,雖然離工業(yè)應(yīng)用還差十萬(wàn)八千里,但是非常適合新手一窺推薦系統(tǒng)的內(nèi)部原理。數(shù)據(jù)集包含兩個(gè)文件:ratings.csv 和 movies.csv。
# 載入數(shù)據(jù) import pandas as pd import numpy as np df = pd.read_csv('data/ratings.csv') df.head()
ratings.csv 包含四個(gè)維度的數(shù)據(jù):
- userId:打分用戶的 ID
- movieId: 被打分電影的 ID
- rating: 用戶給電影的打分,處于[1,5]
- timestamp: 電影被打分的時(shí)間
要推薦電影還需要有電影的名字,電影名字保存在 movies.csv 中:
movies = pd.read_csv('data/movies.csv') movies.head()
將 ratings.csv 和 movies.csv 的數(shù)據(jù)根據(jù) movieId 合并。
df = pd.merge(df, movie_title, on='movieId') df.head()
我們這次要做的推薦系統(tǒng)的核心思路是:
- 根據(jù)所有用戶評(píng)分判斷所有電影與用戶 a 已觀看的某部電影 A 的相似度
- 給用戶 a 推薦相似度高且評(píng)分高的電影
所以我們要先有所有用戶對(duì)所有電影的評(píng)分的列聯(lián)表:
movie_matrix = df.pivot_table(index = 'userId', columns = 'title' ,values = 'rating') movie_matrix.head()
假設(shè)用戶 A 觀看的電影是 air_force_one (1997),則計(jì)算列聯(lián)表中所有電影與 air_force_one (1997) 的相關(guān)性。
AFO_user_rating = movie_matrix['Air Force One (1997)'] simliar_to_air_force_one = movie_matrix.corrwith(AFO_user_rating)
這樣我們就得到了所有電影與 air_force_one (1997)的相關(guān)性。
但是,直接對(duì)這個(gè)相關(guān)性進(jìn)行排序并推薦最相關(guān)的電影有一個(gè)及其嚴(yán)重的問(wèn)題:
ratings = pd.DataFrame(df.groupby('title')['rating'].mean())#計(jì)算電影平均得分 ratings['number_of_ratings'] = df.groupby('title')['rating'].count() import matplotlib.pyplot as plt %matplotlib inline ratings['number_of_ratings'].hist(bins = 60);
上圖是電影被評(píng)分次數(shù)的直方圖,可以看到大量的電影評(píng)分次數(shù)不足10次。評(píng)分次數(shù)太少的電影很容易就被判斷為高相關(guān)性。所以我們要將這部分的評(píng)分刪掉。
corr_AFO = pd.DataFrame(similar_to_air_force_one, columns = ['Correlation']) corr_AFO.dropna(inplace = True) corr_contact = corr_contact.join(ratings['number_of_ratings'],how = 'left',lsuffix='_left', rsuffix='_right') corr_AFO[corr_AFO['number_of_ratings']>100].sort_values(by = 'Correlation',ascending = False).head()
這樣我們就得到了一個(gè)與 air_force_one (1997) 高相關(guān)的電影列表。但是高相關(guān)有可能評(píng)分低(概率低),再?gòu)牧斜砝锾魩撞科骄梅指叩碾娪巴扑]就好了。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
python異步編程之a(chǎn)syncio低階API的使用詳解
asyncio中低階API的種類很多,涉及到開(kāi)發(fā)的5個(gè)方面,這篇文章主要為大家詳細(xì)介紹了這些低階API的具體使用,感興趣的小伙伴可以學(xué)習(xí)一下2024-01-01python裝飾器簡(jiǎn)介及同時(shí)使用多個(gè)裝飾器的方法
這篇文章主要介紹了python裝飾器簡(jiǎn)介及同時(shí)使用多個(gè)裝飾器的方法,python支持一個(gè)函數(shù)同時(shí)使用多個(gè)裝飾器,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06python opencv對(duì)圖像進(jìn)行旋轉(zhuǎn)且不裁剪圖片的實(shí)現(xiàn)方法
今天小編就為大家分享一篇python opencv對(duì)圖像進(jìn)行旋轉(zhuǎn)且不裁剪圖片的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07Django博客系統(tǒng)注冊(cè)之創(chuàng)建用戶模塊應(yīng)用
本文主要介紹了Django博客系統(tǒng)注冊(cè)之創(chuàng)建用戶模塊應(yīng)用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09python實(shí)現(xiàn)簡(jiǎn)單flappy bird
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡(jiǎn)單flappy bird小游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12python獲取android設(shè)備的GPS信息腳本分享
這篇文章主要介紹了python獲取android設(shè)備的GPS信息腳本分享,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-03-03