如何在Python中構建一個簡單的推薦系統

在本文中,我們將向讀者介紹推薦系統。我們還將在Python中構建一個簡單的推薦系統。該系統僅作為推薦系統的介紹。我們假設讀者具有pandas和numpy等科學軟件包的經驗。

什麼是推薦系統?

推薦系統是一種簡單的算法,其目的是通過發現數據集中的模式向用戶提供最相關的信息。該算法對項目進行評級,並向用戶顯示它們將給予很高的評級。實施建議的一個示例是,當您訪問亞馬遜並且您注意到某些項目正在向您推薦或Netflix向您推薦某些電影時。音樂流媒體應用程序(如Spotify和Deezer)也會使用它們來推薦您可能喜歡的音樂。

以下是推薦系統如何在電子商務網站環境中工作的非常簡單的說明。

如何在Python中構建一個簡單的推薦系統

兩個用戶從電子商務商店購買相同的商品A和B. 當發生這種情況時,計算這兩個用戶的相似性指數。根據分數,系統可以將項目C推薦給其他用戶,因為它檢測到這兩個用戶在他們購買的項目方面是相似的。

不同類型的推薦引擎

最常見的推薦系統類型是基於內容和協同過濾的推薦系統。在協同過濾中,一組用戶的行為用於向其他用戶提出建議。建議基於其他用戶的偏好。一個簡單的例子是基於他們的朋友喜歡電影的事實向用戶推薦電影。有兩種類型的協作模型Memory-based方法和Model-based 的方法。memory-based 技術的優點是它們是易於實施,所得到的建議通常很容易解釋。它們分為兩個:

  • 基於用戶的協同過濾:在此模型中,基於產品已被類似於用戶的用戶所喜歡的事實向用戶推薦產品。例如,如果德里克和丹尼斯喜歡相同的電影並且出現了德里克喜歡的新電影,那麼我們可以向丹尼斯推薦這部電影,因為德里克和丹尼斯似乎喜歡同樣的電影。
  • 基於項目的協同過濾:這些系統根據用戶之前的評級識別類似項目。例如,如果用戶A,B和C對書籍X和Y給出5星評級,那麼當用戶D購買書籍Y時他們也得到購買書籍X的建議,因為系統根據評級將書籍X和Y識別為相似用戶A,B和C.

Model-based方法基於矩陣分解,並且更好地處理稀疏性。它們是使用數據挖掘,機器學習算法開發的,用於預測用戶對未評級項目的評級。在這種方法中,諸如降維的技術被用於提高準確性。這種基於模型的方法的示例包括決策樹,基於規則的模型,貝葉斯方法和潛在因子模型。

基於內容的系統使用元數據,如流派、製作人、演員、音樂家等來推薦電影或音樂。這樣的建議可以是,比如推薦《無盡的戰爭》(Infinity War),它的主角是凡·迪塞爾(Vin Disiel),因為有人看到並喜歡《狂暴戰士》(Furious)的命運。同樣,你也可以從某些藝術家那裡得到音樂推薦,因為你喜歡他們的音樂。基於內容的系統是基於這樣一種想法:如果你喜歡某樣東西,你很可能會喜歡與之相似的東西。

用於構建推薦系統的數據集

在本教程中,我們將使用MovieLes數據集(https://grouplens.org/datasets/movielens/)。該數據集由明尼蘇達大學的Grouplens研究小組整理。它包含1,10和20,000萬個評級。Movielens還有一個網站,您可以在其中註冊,撰寫評論並獲取電影推薦。您可以從Dataquest的數據資源中找到更多用於各種數據科學任務的數據集。

構建推薦系統的演練

我們將使用movielens構建一個基於項目相似度的簡單推薦系統。我們需要做的第一件事就是導入pandas和numpy。

import pandas as pd 
import numpy as np
import warnings
warnings.filterwarnings('ignore')

接下來,我們使用panda read_csv()實用程序加載數據集。數據集是製表符分開的,所以我們傳入\t到sep參數。然後使用names參數傳入列名。Python代碼如下:

df = pd.read_csv('u.data', sep='\t', names=['user_id','item_id','rating','titmestamp'])

現在讓我們查看我們正在處理的數據

df.head()

如果我們能看到電影的片名而不是僅僅處理id就好了。讓我們加載影片標題並將其與此數據集合並。

movie_titles = pd.read_csv('Movie_Titles')
movie_titles.head()

由於item_id列是相同的,我們可以在此列上合併這些數據集。

df = pd.merge(df, movie_titles, on='item_id')
df.head()

讓我們看看每列代表什麼:

  • user_id - 評價電影的用戶的ID。
  • item_id - 電影的ID。
  • rating - 用戶給予電影的評級,介於1和5之間。
  • timestamp - 電影評分的時間。
  • title - 電影的標題。

使用describe或info命令我們可以得到我們的數據集的簡要描述。這對於讓我們瞭解我們正在使用的數據集非常重要。

df.describe()

我們可以看出平均評分為3.52,最大值為5.我們還看到數據集有100003條記錄。

現在讓我們創建一個dataframe ,其中包含每部電影的平均評分和評分數。我們將使用這些評級來計算以後的電影之間的相關性。相關性是一種統計指標,表示兩個或多個變量一起波動的程度。具有高相關係數的電影是彼此最相似的電影。在我們的例子中,我們將使用Pearson相關係數。該數字將介於-1和1之間.1表示正線性相關,而-1表示負相關。0表示沒有線性相關。因此,具有零相關性的電影完全不相似。為了創建這個dataframe ,我們使用pandas groupby。我們按照分組對數據集進行title 列分組並計算其平均值以獲得每部電影的平均評分。Python示例如下:

ratings = pd.DataFrame(df.groupby('title')['rating'].mean())
ratings.head()

接下來我們希望看到每部電影的評分數量。我們通過創建一個number_of_ratings列來完成此操作。這很重要,這樣我們就可以看到電影的平均評分與電影獲得的評分數量之間的關係。五星級電影很有可能只被一個人評價。因此,對於該電影具有5星級電影進行分類在統計上是不正確的。因此,在構建推薦系統時,我們需要設置最小額定值的閾值。為了創建這個新列,我們使用pandas groupby實用程序。我們按title列分組,然後使用該count函數計算每部電影獲得的評分數。然後我們使用該head()函數查看新的dataframe 。

ratings['number_of_ratings'] = df.groupby('title')['rating'].count()
ratings.head()

現在讓我們使用pandas來繪製直方圖,以顯示評級的分佈,Python代碼如下:

import matplotlib.pyplot as plt
%matplotlib inline
ratings['rating'].hist(bins=50)

我們可以看到大多數電影的評分在2.5到4之間。接下來,讓我們以類似的方式可視化number_of_ratings列。

ratings['number_of_ratings'].hist(bins=60)

從上面的直方圖中可以清楚地看出,大多數電影的收視率都很低。評分最高的電影是最著名的電影。

現在讓我們檢查電影評級與評分數量之間的關係。我們通過使用seaborn繪製散點圖來做到這一點。Seaborn使我們能夠使用jointplot()函數執行此操作。

import seaborn as sns
sns.jointplot(x='rating', y='number_of_ratings', data=ratings)

從圖中我們可以看出,它們是電影平均評分與評分數量之間的正相關關係。該圖表示電影獲得的評分越高,其獲得的平均評分越高。特別是在為每部電影選擇評級數量的閾值時,這一點很重要。

現在讓我們快速進行並創建一個簡單的基於項目的推薦系統。為了做到這一點,我們需要將數據集轉換為一個矩陣,以電影標題為列,以user_id為索引,以評級為值。通過這樣做,我們將得到一個dataframe,其中列是movie標題,行是user id。每個欄目代表所有用戶對一部電影的評分。如果用戶沒有對某一部電影進行評分,該評分以NAN的形式出現。我們將使用這個矩陣來計算單個電影的評級與矩陣中其他電影的評級之間的相關性。我們使用panda pivot_table實用程序創建電影矩陣。

movie_matrix = df.pivot_table(index='user_id', columns='title', values='rating')
movie_matrix.head()

接下來,讓我們來看看評分最高的電影,並從中選出兩部在這個簡單的推薦系統中使用。我們使用panda sort_values工具,並將ascending設置為false,以便從評分最高的電影中進行排列。然後我們使用head()函數查看前10名。

ratings.sort_values('number_of_ratings', ascending=False).head(10)

假設用戶看過《Air Force One》(1997)和《Contact》(1997)。我們想根據這個觀看歷史向這個用戶推薦電影。我們的目標是尋找與Contact(1997)和Air Force One(1997)相似的電影。我們可以通過計算這兩個電影的評級和數據集中其他電影的評級之間的相關性來實現這一點。第一步是用movie_matrix中的這些電影的評級創建一個dataframe。

AFO_user_rating = movie_matrix['Air Force One (1997)']
contact_user_rating = movie_matrix['Contact (1997)']

現在我們有了dataframes,顯示了user_id和他們給這兩個電影的評級。

AFO_user_rating.head()
contact_user_rating.head()

為了計算兩個dataframe之間的相關性,我們使用pandas corwith函數。Corrwith計算兩個dataframe對象的行或列的成對相關性。讓我們使用此功能來獲得每部電影的評級與Air Force One電影的評級之間的相關性。

similar_to_air_force_one=movie_matrix.corrwith(AFO_user_rating)

我們可以看到Air Force One電影和Til There Was You(1997)之間的相關性是0.867。這表明這兩部電影之間有很強的相似性。

similar_to_air_force_one.head()

讓我們繼續前進並計算Contact(1997)評級與其他電影評級之間的相關性。程序與上面使用的程序相同。

similar_to_contact = movie_matrix.corrwith(contact_user_rating)

我們從計算中發現,Contact(1997)和Til There Was You(1997)之間存在非常強的相關性(0.904)。

similar_to_contact.head()

如前所述,我們的矩陣有很多缺失值,因為並非所有用戶都對所有電影進行了評分。因此,我們刪除這些空值並將相關結果轉換為數據幀,以使結果看起來更具吸引力。Python代碼如下:

corr_contact = pd.DataFrame(similar_to_contact, columns=['Correlation'])
corr_contact.dropna(inplace=True)
corr_contact.head()
corr_AFO = pd.DataFrame(similar_to_air_force_one, columns=['correlation'])
corr_AFO.dropna(inplace=True)
corr_AFO.head()

上面的這兩個dataframes分別向我們展示了與Contact(1997)和Air Force One(1997)電影最相似的電影。然而,我們遇到了一個挑戰,因為有些電影的收視率非常低,最終可能因為一兩個人給他們5星評級而被推薦。我們可以通過設置評級數量的閾值來解決這個問題。從早期的柱狀圖中我們看到評級數量從100急劇下降。因此,我們將此設置為閾值,但是這是一個你可以設置的數字,直到你得到一個合適的選項。

corr_AFO = corr_AFO.join(ratings['number_of_ratings'])
corr_contact = corr_contact.join(ratings['number_of_ratings'])
corr_AFO .head()
corr_contact.head()

我們現在將獲得與Air Force One(1997)最相似的電影,將它們限制為至少有100條評論的電影。然後我們按correlation列對它們進行排序並查看前10個。

corr_AFO[corr_AFO['number_of_ratings'] > 100].sort_values(by='correlation', ascending=False).head(10)

我們注意到Air Force One(1997)與自身有完美的相關性,這並不奇怪。Air Force One(1997)的下一部最相似的電影是Hunt for Red October,The(1990),相關係數為0.554。顯然,通過更改評論數量的閾值,我們可以從之前的方式獲得不同的結果。限制評級數量可以讓我們獲得更好的結果,我們可以自信地向觀看Air Force One(1997)的人推薦上述電影。

現在讓我們對Contact(1997)電影做同樣的事情,看看與它最相關的電影。

corr_contact[corr_contact['number_of_ratings'] > 100].sort_values(by='Correlation', ascending=False).head(10)

我們再一次得到不同的結果。與Contact(1997)最相似的電影是費城(1993),相關係數為0.446,有137個評級。所以,如果有人喜歡Contact(1997),我們可以向他們推薦上述電影。

顯然,這是構建推薦系統的一種非常簡單的方法,並且不符合行業標準。

如何改進推薦系統

可以通過構建Memory-Based 協同過濾的系統來改進該系統。在這種情況下,我們將數據劃分為訓練集和測試集。然後我們使用諸如餘弦相似性的技術來計算電影之間的相似性。另一種方法是構建基於模型的協同過濾系統。這基於矩陣分解。矩陣分解在處理可擴展性和稀疏性方面比前者好。然後,您可以使用諸如均方根誤差(RMSE)等技術來評估模型。

最後

還有其他用於構建推薦系統的技術。深度學習是這樣做的方法之一,尤其是當您擁有大量數據集時。用於構建高級推薦系統的一些算法包括自動編碼器和限制玻爾茲曼機器

相關推薦

推薦中...