熱線電話:13121318867

登錄
首頁精彩閱讀使用python構建一個推薦系統需要幾步?
使用python構建一個推薦系統需要幾步?
2020-05-29
收藏

在我看來,作為一位中國人的我們不管做什么決定都在面臨多種選擇。例如,如果我這個時候想要買一本書,但是我卻不知道我想看什么書、不知道類型、不知道方向,那么這個時候打開各種進行軟件搜索可能會出現各種各樣的結果。我可能會浪費大量時間在互聯網上瀏覽各種并在各個希望淘金的站點中進行拖曳。我可能會尋求其他人的建議。

但是,如果有一個網站或應用程序可以根據我之前閱讀的內容向我推薦書,那么會很好的幫助到我,不用浪費時間在各種網站上自己去找書,我只需登錄網站或者應用程序就好了!它會根據我的口味量身定制的10本書推薦給我

這就是推薦引擎所做的事情,現如今,大多數企業正在利用它的力量。從亞馬遜到網飛(Netflix),從谷歌到Goodreads,毫不夸張的說推薦引擎是機器學習技術中使用最廣泛的應用之一。

在本文中,我們將介紹各種類型的推薦引擎算法以及在Python中創建推薦引擎的基礎知識。我們還將看到這些算法工作背后的數學原理。最后,我們將使用矩陣分解來創建自己的推薦引擎。

1.什么是推薦引擎?

在買東西的時候,如果對產品有任何疑問的時候,人們通常傾向于購買他們的朋友或信任的人推薦給他們的產品。這在曾經是人們主要的購買方式。但是隨著數字時代的到來,這個圈子已經擴大到包括利用某種推薦引擎的網站。

推薦引擎使用不同的算法過濾數據,并向用戶推薦最相關的物品。它首先記錄了客戶的過去行為,并在此基礎上推薦了用戶可能購買的產品。

如果是一個全新的用戶訪問了電子商務網站,則該網站將沒有該用戶的任何歷史記錄。那么在這種情況下,網站如何向用戶推薦產品呢?一種可能的解決方案是推薦網站內最暢銷的產品,即需求量大的產品。另一個可能的解決方案是推薦可以為企業帶來最大利潤的產品。

如果我們可以根據客戶的需求和興趣向他們推薦一些商品,那么它將對用戶的體驗產生積極影響并可能會導致用戶的頻繁訪問。因此,當今的企業正在通過研究用戶的過去行為來構建智能的推薦引擎。

現在,我們對推薦引擎有了一個大體的了解,現在讓我們看一下它是怎么工作的。

2.推薦引擎的工作方式

在深入探討這個主題之前,首先我們先考慮一下如何向用戶推薦商品:

  • 我們可以向用戶推薦在所有用戶中最受歡迎的商品
  • 我們可以根據用戶的偏好(用戶特性)將其分為多個部分,并根據其所屬的部分向他們推薦商品

以上的兩種方法都有其缺點。在第一種情況下,每個用戶最受歡迎的商品都是相同的,因此每個人都會看到相同的推薦。在第二種情況下,隨著用戶數量的增加,用戶特性的數量也會增加。因此,將用戶劃分為不同的部分將是一項非常困難的任務。

這里的主要問題是我們無法根據用戶的特定興趣來定制建議。就像亞馬遜推薦你購買筆記本電腦,只是因為它被大多數購物者購買了。但值得慶幸的是,亞馬遜(或任何其他大公司)都不推薦使用上述方法的產品。他們使用一些個性化的方法來幫助他們更準確地推薦產品。

現在,通過執行以下的步驟來重點介紹推薦引擎的工作方式。

2.1數據收集

這是構建推薦引擎的第一步,也是最關鍵的一步??梢酝ㄟ^兩種方式收集數據:顯式和隱式。 顯式數據是有意提供的信息,即來自用戶的輸入,例如電影分級。隱式數據是不是有意提供的信息,而是從可用數據流(例如搜索歷史,點擊次數,訂單歷史記錄等)中收集的信息。

在上圖中,Netflix正在以用戶對不同電影給出的評分的形式明確地收集數據。

在這里,用戶的訂單歷史記錄是由Amazon記錄的,這是隱式數據收集模式的一個例子。

2.2數據存儲

數據量決定了模型推薦的質量。例如,在電影推薦系統中,用戶對電影的評分越高,對其他用戶的推薦就越好。數據類型在決定必須使用的存儲類型方面起著重要作用。這種類型的存儲可以包括標準SQL數據庫,NoSQL數據庫或某種對象存儲。

2.3過濾數據

在收集和存儲數據之后,我們必須對其進行過濾,以提取出最終推薦所需的相關信息。

有各種各樣的算法可以幫助我們簡化過濾的過程。在下一節中,我們將詳細介紹每種算法。

2.3.1基于內容的過濾

該算法推薦與用戶過去喜歡的產品相似的產品。

例如,如果某人喜歡電影“盜夢空間”,那么這個算法將推薦給他屬于同一類型的電影。但是,該算法如何理解從哪個類型中挑選電影并推薦呢?

**以Netflix為例。**他們以向量的形式保存與每個用戶有關的所有信息。該向量包含用戶過去的行為,即用戶喜歡/不喜歡的電影以及他們給出的評分。這個向量稱為輪廓向量。與電影有關的所有信息都存儲在另一個稱為物品向量的向量中。物品向量包含每部電影的詳細信息,例如類型,演員,導演等。

基于內容的過濾算法找到輪廓向量和物品向量之間的角度的余弦值,即余弦相似度。假設A是輪廓向量,B是物品向量,則它們之間的相似度可以計算為:\operatorname{sim}(A, B)=\cos (\theta)=\frac{A \cdot B}{\|A\||| B \|}sim(A,B)=cos(θ)=∥A∥∣∣B∥A?B基于介于-1到1之間的余弦值,電影以降序排列,推薦使用以下兩種方法之一:

  • Top-n方式:推薦前n部電影(此處n可由業務決定)
  • 評分表方法:設置閾值并推薦所有超過該閾值的電影

其他可用于計算相似度的方法是:

  • 歐幾里德距離:如果在n維空間中繪制,相似的物品將彼此緊鄰。因此,我們可以計算物品之間的距離,并根據該距離向用戶推薦物品。歐氏距離的公式由下式給出:

\text { Euclidean Distance }=\sqrt{\left(x_{1}-y_{1}\right)^{2}+\ldots+\left(x_{N}-y_{N}\right)^{2}} Euclidean Distance =(x1?y1)2+…+(xN?yN)2

  • 皮爾遜相關性:它告訴我們兩個項目之間有多少相關性。相關性越高,相似性越高。皮爾遜相關性可以使用以下公式計算:

\operatorname{sim}(u, v)=\frac{\sum\left(r_{u i}-\bar{r}_{u}\right)\left(r_{v i}-\bar{r}_{v}\right)}{\sqrt{\sum\left(r_{u i}-\bar{r}_{u}\right)^{2}} \sqrt{\sum\left(r_{v i}-\bar{r}_{v}\right)^{2}}}sim(u,v)=∑(rui?rˉu)2∑(rvi?rˉv)2∑(rui?rˉu)(rvi?rˉv)

該算法的主要缺點是它僅限于推薦相同類型的項目。絕不會推薦用戶過去從未購買或不喜歡的產品。因此,如果用戶過去僅觀看或喜歡動作電影,則系統將僅推薦動作電影。這是構建引擎的一種非常狹窄的方法。

為了改進這種類型的系統,我們需要一種算法,該算法不僅可以根據內容來推薦商品,還可以根據用戶的行為來推薦商品。

2.3.2協同過濾

讓我們通過一個例子來理解這一點。如果A喜歡《星際穿越》,《盜夢空間》和《前目的地》等三部電影,而B人喜歡《盜夢空間》,《前目的地》和《致命魔術》,那么他們的興趣幾乎相同。我們可以肯定地說,A應該喜歡《致命魔術》,B應該喜歡《星際穿越》。協同過濾算法使用“用戶行為”來推薦項目。這是業界最常用的算法之一,因為它不依賴于任何其他信息。協同過濾技術有多種類型,我們將在下面詳細介紹它們。

基于用戶的協同過濾

該算法首先找到用戶之間的相似度得分。然后,根據相似度評分,挑選出最相似的用戶,并推薦這些相似的用戶之前喜歡或購買的產品。

就我們之前的電影例子來說,該算法根據每個用戶先前對不同電影給予的評分來找到每個用戶之間的相似性。通過計算其他用戶對項目i給出的用戶評分的加權總和,可以計算出用戶u對某個項目的預測。

預測Pu,i由下式給出:P_{u, i}=\frac{\sum_{v}\left(r_{v, i} * s_{u, v}\right)}{\sum_{v} s_{u, v}}Pu,i=∑vsu,v∑v(rv,i?su,v)公式解讀,

  • Pu,i是一個項目的預測
  • Rv,i是用戶v對電影i的評級
  • Su,v是用戶之間的相似性

現在,我們在配置文件向量中具有用戶的評分,并基于此我們必須預測其他用戶的評分。為此我們將要采取以下的步驟:

  1. 為了進行預測,我們需要用戶u和v之間的相似性。我們可以利用皮爾遜相關性。
  2. 首先,我們找到兩個用戶都評價過的物品,并根據這些評價來計算用戶之間的相關性。
  3. 可以使用相似度值來計算預測。該算法首先計算每個用戶之間的相似度,然后基于每個相似度計算預測結果。具有較高相關性的用戶將趨于相似。
  4. 基于這些預測值,提出建議。讓我們通過一個例子來理解它:

考慮用戶電影評分矩陣:

用戶/電影X1X2X3X4X5平均用戶評分A41–4–3B–4–233C–1–443

這里我們有一個用戶電影分級矩陣。為了更實際地理解這一點,讓我們在上表中找到用戶(A,C)和(B,C)之間的相似性。由A和C評級的電影是電影x2和x4,由B和C評級的電影是x2,x4和x5。\begin{aligned} &\mathrm{r}_{\mathrm{AC}}=\left[(1-3)^{*}(1-3)+(4-3)^{*}(4-3)\right]\left[\left(1(1-3)^{2}+(4-3)^{2}\right)^{32+}\left((1-3)^{2}+(4-3)^{2}\right)^{3 / 3}\right]=1\\ &\mathrm{r}_{\mathrm{BC}}=\left[(4-3)^{*}(1-3)+(2-3)^{*}(4-3)+(3-3)^{*}(4-3) M\left((4-3)^{2}+(2 \cdot 3)^{2}+(3-3)^{2}\right)^{3 / 2}+\left((1-3)^{2}+(4-3)^{2}+(4-3)^{2}\right)^{1 / 2}\right]=-0.866 \end{aligned}rAC=[(1?3)?(1?3)+(4?3)?(4?3)][(1(1?3)2+(4?3)2)32+((1?3)2+(4?3)2)3/3]=1rBC=[(4?3)?(1?3)+(2?3)?(4?3)+(3?3)?(4?3)M((4?3)2+(2?3)2+(3?3)2)3/2+((1?3)2+(4?3)2+(4?3)2)1/2]=?0.866用戶A和C之間的相關性大于B和C之間的相關性。因此,用戶A和C具有更高的相似性,并且將向用戶C推薦用戶A喜歡的電影,反之亦然。

該算法非常耗時,因為它涉及為每個用戶計算相似度,然后為每個相似度分數計算預測。處理此問題的一種方法是僅選擇幾個用戶(鄰居)而不是全部進行預測,也就是我們不選擇對所有相似性值進行預測,而是僅選擇幾個相似性值。選擇鄰居的方法有很多:

  • 選擇一個閾值相似度,然后選擇高于該值的所有用戶
  • 隨機選擇用戶
  • 以相似度值從大到小的順序排列鄰居,并選擇前N個用戶
  • 使用集群選擇鄰居

當用戶數較少時,此算法很有用。當有大量用戶時,此方法無效,因為計算所有用戶對之間的相似度將花費大量時間。這導致我們進行物品-物品協同過濾,當用戶數量超過建議的物品數時,這種方法是有效的。

基于物品的協同過濾

在該算法中,我們計算每對項目之間的相似度。

因此,在我們的案例中,我們將發現每個電影對之間的相似性,并以此為基礎,推薦過去用戶喜歡的相似電影。該算法的工作原理與基于用戶的協同過濾類似,只是有一點點變化–我們計算“項目-鄰居”的加權總和,而不是計算“用戶-鄰居”的加權總和。預測如下:P_{u, i}=\frac{\sum_{N}\left(s_{i, N} * R_{u, N}\right)}{\sum_{N}\left(\left|s_{i, N}\right|\right)}Pu,i=∑N(∣si,N∣)∑N(si,N?Ru,N)現在我們將發現項目之間的相似性。\operatorname{sim}(i, j)=\cos (\vec{i}, \vec{j})=\frac{\vec{i} \cdot \vec{j}}{\|\vec{i}\|_{2} *\|\vec{j}\|_{2}}sim(i,j)=cos(i,j)=∥i∥2?∥j∥2i?j現在,由于我們有了每部電影和評分之間的相似性,因此進行了預測,并根據這些預測推薦了類似的電影。讓我們通過一個例子來理解它。

用戶/電影x1X2X3X4X5A41244B24421C–1–34平均物品評分32333

這里的平均物品評分是對特定物品給予的所有評分的平均值(將其與我們在基于用戶的協同過濾中看到的表進行比較)。與我們之前看到的基于用戶的相似度不同,我們查找到的基于項目的相似度。\begin{aligned} &\mathrm{C}_{14}=\left[(4-3)^{*}(4-3)+(2-3)^{*}(2-3)\right] /\left[\left((4-3)^{2}+(2-3)^{2}\right)^{1/2} *\left((4-3)^{2}+(2-3)^{2}\right)^{1 / 2}\right]=1\\ &\mathrm{C}_{15}=\left[(4-3)^{*}(4-3)+(2-3)^{*}(1-3)\right] /\left[\left((4-3)^{2}+(2-3)^{2}\right)^{1/2} *\left((4-3)^{2}+(1-3)^{2}\right)^{1/2}\right]=0.94 \end{aligned}C14=[(4?3)?(4?3)+(2?3)?(2?3)]/[((4?3)2+(2?3)2)1/2?((4?3)2+(2?3)2)1/2]=1C15=[(4?3)?(4?3)+(2?3)?(1?3)]/[((4?3)2+(2?3)2)1/2?((4?3)2+(1?3)2)1/2]=0.94電影x1和x4之間的相似度大于電影x1和x5之間的相似度。因此,基于這些相似值,如果有任何用戶搜索電影x1,那么將會向他們推薦電影X4,反之亦然。在進一步實施這些概念之前,我們必須知道一個問題的答案–如果在數據集中添加新用戶或新物品,將會發生什么?這被稱為 冷啟動。冷啟動可以有兩種類型:

  1. 用戶冷啟動
  2. 物品冷啟動

用戶冷啟動意味著在數據集中引入了一個新用戶。由于沒有該用戶的歷史記錄,因此系統不知道該用戶的首選項。向該用戶推薦物品變得越來越困難。那么,如何解決這個問題呢?一種基本方法是應用基于流行度的策略,即推薦最受歡迎的物品。這些可以通過最近整體或區域流行的內容來確定。一旦我們了解了用戶的喜好,推薦物品就會更加容易。

另一方面,物品冷啟動意味著將新產品投放市場或添加到系統中。用戶行為是對于確定任何產品的價值的最重要的因素。物品獲得的互動越多,我們的模型就越容易將物品推薦給合適的用戶。我們可以利用基于內容的過濾來解決此問題。系統首先將新產品的內容用于推薦,然后最終用戶對該產品執行操作。

現在,使用Python中的一個案例研究來鞏固對這些概念的理解。準備好你的電腦,因為這將會很有趣!

3.使用MovieLens數據集的Python案例研究

我們將處理MovieLens數據集,并建立一個模型來向最終用戶推薦電影。這些數據是由明尼蘇達大學的GroupLens研究項目收集的。該數據集包括:

  • 從943個用戶對1682個電影中選出的10萬個評分(1-5分)
  • 用戶的人口統計信息(年齡,性別,職業等)

首先,我們將導入標準庫并使用Python讀取數據集。你可以通過下方的代碼,幫助你進行入門。你可以在自己的電腦上運行代碼并獲取輸出:

# importing libraries
import pandas as pd
import numpy as np

# 傳遞每個CSV的列名,因為該文件沒有給出列名,使用Pandas進行讀取他們
#你可以從readme文件中檢查列名
#閱讀用戶文件
u_cols = ['user_id', 'age', 'sex', 'occupation', 'zip_code']
users = pd.read_csv('ml-100k/u.user', sep='|', names=u_cols,encoding='latin-1')

# 閱讀評級文件:
r_cols = ['user_id', 'movie_id', 'rating', 'unix_timestamp']
ratings = pd.read_csv('ml-100k/u.data', sep='\t', names=r_cols,encoding='latin-1')

# 閱讀物品文件:
i_cols = ['movie id', 'movie title' ,'release date','video release date', 'IMDb URL', 'unknown', 'Action', 'Adventure',
'Animation', 'Children\'s', 'Comedy', 'Crime', 'Documentary', 'Drama', 'Fantasy',
'Film-Noir', 'Horror', 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Thriller', 'War', 'Western']
items = pd.read_csv('ml-100k/u.item', sep='|', names=i_cols,
encoding='latin-1')

#加載數據集之后,我們應該查看每個文件的內容 (用戶, 評分, 物品).
#查看用戶文件
print("\nUser Data :")
print("shape : ", users.shape)
print(users.head())
#數據集中有943個用戶,每個用戶有5個特征,也就是用戶ID,年齡,性別,職業,和編碼

# 評分數據
print("\nRatings Data :")
print("shape : ", ratings.shape)
print(ratings.head())
# 我們有不同的用戶和電影的組合的10萬行數據量的評分,現在最后檢查物品文件

# Item Data
print("\nItem Data :")
print("shape : ", items.shape)
print(items.head())

該數據集包含1682部電影的屬性。有24列,其中最后19列指定特定電影的類型。這些列都是二進制列,即值為1表示電影屬于該類型,否則為0。

數據集已由GroupLens分為訓練集和測試集,其中每個用戶的測試數據具有10個等級,即總計9,430行。我們將把這兩個文件讀入我們的Python中。

#創建列名
r_cols = ['user_id', 'movie_id', 'rating', 'unix_timestamp']
#讀取訓練集
ratings_train = pd.read_csv('ml-100k/ua.base', sep='\t', names=r_cols, encoding='latin-1')
#讀取測試集
ratings_test = pd.read_csv('ml-100k/ua.test', sep='\t', names=r_cols, encoding='latin-1')
#查看訓練集與測試集
ratings_train.shape, ratings_test.shape

現在是構建我們推薦的引擎的時候了!

4.從頭開始構建協同過濾模型

我們將根據基于用戶相似度和基于物品相似度進行推薦電影。為此,首先我們需要計算唯一身份用戶和電影的數量。

n_users = ratings.user_id.unique().shape[0]
n_items = ratings.movie_id.unique().shape[0]

現在,我們將創建一個用戶-物品向量,該向量可用于計算用戶和物品之間的相似度。

data_matrix = np.zeros((n_users, n_items))
for line in ratings.itertuples():
    data_matrix[line[1]-1, line[2]-1] = line[3]

現在,我們將計算相似度。我們可以使用sklearn中的pairwi se_distance函數來計算余弦相似度。

from sklearn.metrics.pairwise import pairwise_distances 
user_similarity = pairwise_distances(data_matrix, metric='cosine')
item_similarity = pairwise_distances(data_matrix.T, metric='cosine')

這為我們提供了數組形式的基于物品和基于用戶的相似度。下一步是基于這些相似性進行預測。讓我們定義一個函數來做到這一點。

def predict(ratings, similarity, type='user'):
    if type == 'user':
        mean_user_rating = ratings.mean(axis=1)
        #我們用np.newaxis使得mean_user_rating具有與ratings相同的格式
        ratings_diff = (ratings - mean_user_rating[:, np.newaxis])
        pred = mean_user_rating[:, np.newaxis] + similarity.dot(ratings_diff) / np.array([np.abs(similarity).sum(axis=1)]).T
    elif type == 'item':
        pred = ratings.dot(similarity) / np.array([np.abs(similarity).sum(axis=1)])
    return pred

最后,我們將基于用戶相似性和物品相似性進行預測。

user_prediction = predict(data_matrix, user_similarity, type='user')
item_prediction = predict(data_matrix, item_similarity, type='item')

事實證明,我們還有一個可自動生成所有這些推薦的庫?,F在讓我們學習如何在Python中使用turicreate創建推薦引擎。要熟悉turicreate并將其安裝在你的計算機上,請上GitHub上搜索turicreate。

5.使用Turicreate建立簡單的受歡迎程度和協作過濾模型

安裝turicreate之后,首先讓我們導入它,并在我們的環境中讀取訓練和測試數據集。由于我們將使用turicreate,因此需要在SFrame中轉換數據集。

import turicreate
train_data = turicreate.SFrame(ratings_train)
test_data = turicreate.Sframe(ratings_test)

我們具有用戶行為以及用戶和電影的屬性,因此我們可以制作基于內容的內容協同過濾算法。我們將從一個簡單的流行度模型開始,然后構建一個協同過濾模型。

首先,我們將建立一個模型,該模型將根據最受歡迎的選擇來推薦電影,即所有用戶都收到相同推薦的模型。我們將使用turicreate推薦功能的 popularity_recommender函數。

popularity_model = turicreate.popularity_recommender.create(train_data, user_id='user_id', item_id='movie_id', target='rating')

我們使用的各種參數:

  • train_data:包含所需訓練數據的SFrame
  • user_id:代表每個用戶ID的列名
  • item_id:代表要推薦的每個物品的列名(movie_id)
  • **目標:**代表用戶給出的分數/等級的列名

現在是預測時間!我們將為數據集中的前5個用戶推薦前5個物品。

popularity_recomm = popularity_model.recommend(users=[1,2,3,4,5],k=5)
popularity_recomm.print_rows(num_rows=25)

注意,所有用戶的建議都是相同的-1467、1201、1189、1122、814。而且它們的順序相同的!這確認所有推薦電影的平均評分為5,即所有觀看該電影的用戶都將其評為最高評分。因此,我們的評分系統可以按預期工作。

建立受歡迎度模型后,我們現在將建立一個協作過濾模型。讓我們訓練商品相似性模型,并為前5個用戶提出前5個建議。

#訓練模型
item_sim_model = turicreate.item_similarity_recommender.create(train_data, user_id='user_id', item_id='movie_id', target='rating', similarity_type='cosine')

#提出推薦
item_sim_recomm = item_sim_model.recommend(users=[1,2,3,4,5],k=5)
item_sim_recomm.print_rows(num_rows=25)

在這里,我們可以看到每個用戶的建議(movie_id)是不同的。因此個性化是存在的,即對于不同的用戶,我們有不同的推薦集。

在此模型中,我們沒有每個用戶給出的每部電影的評分。我們必須找到一種方法來預測所有這些缺失的評分。為此,我們必須找到一組可以定義用戶如何評價電影的特征。這些稱為潛在特征。我們需要找到一種從現有特征中提取最重要的潛在特征的方法。下一部分將介紹的矩陣分解是一種這樣的技術,它使用較低維度的密集矩陣并有助于提取重要的潛在特征。

6.矩陣分解簡介

讓我們用一個例子來了解矩陣分解??紤]由不同用戶給不同電影的用戶電影評級矩陣(1-5)。

這里的user_id是不同用戶的唯一ID,每部電影也都分配了唯一的ID。評分為0.0表示用戶尚未對特定電影評分(1是用戶可以給予的最低評分)。我們要預測這些缺失的評分。使用矩陣分解,我們可以找到一些潛在的特征,這些這些特征可以確定用戶如何評價電影。我們將矩陣分解為組成部分,使這些部分的乘積將生成原始矩陣。

假設我們必須找到k個潛在特征。因此,我們可以將評級矩陣R(MxN)分為P(MxK)和Q(NxK),以使P x QT(此處QT是Q矩陣的轉置)近似于R矩陣:\mathrm{R}=\mathrm{P} \Sigma \mathrm{Q}^{\mathrm{T}}R=PΣQT公式內容:

  • M是用戶總數
  • N是電影總數
  • K是總潛在特征
  • R是MxN用戶電影評級矩陣
  • P是MxK用戶特征關聯矩陣,表示用戶與特征之間的關聯
  • Q是NxK項特征相關性矩陣,表示電影和特征之間的關聯
  • Σ是KxK對角特征權重矩陣,表示特征的基本權重

通過矩陣分解選擇潛在特征可消除數據中的噪聲。怎么樣?好吧,它刪除了那些無法確定用戶如何評價電影的特征。要獲得用戶puk對一部電影qik的所有潛在特征k的評分,我們可以計算這兩個向量的點積,并將它們相加,得到基于所有潛在特征的評分。r_{u i}=\Sigma^{K}_{k=1} p_{u k} \sigma_{k} q_{k i}rui=Σk=1Kpukσkqki這就是矩陣分解為我們提供未由用戶評級的電影的評級的方式。但是,如何將新數據添加到我們的用戶-電影評分矩陣中呢?也就是說新用戶加入并對電影進行評分,我們如何將這些數據添加到現有矩陣中?

讓我用矩陣分解方法使你更輕松的理解。如果有新用戶加入系統,則對角特征權重矩陣Σ以及項目特征相關性矩陣Q都將保持不變。唯一的變化將發生在用戶特征相似度矩陣P中。我們可以應用一些矩陣乘法方法可以做到這一點。

我們有,\mathrm{R}=\mathrm{P} \Sigma \mathrm{Q}^{\mathrm{T}}R=PΣQT讓我們在兩邊都乘以Q。\mathrm{RQ}=\mathrm{P} \Sigma \mathrm{Q}^{\mathrm{T}} \mathrm{Q}RQ=PΣQTQ現在,我們有\mathrm{Q}^{\top} \mathrm{Q}=1Q?Q=1所以,

\mathrm{RQ}=\mathrm{P} \SigmaRQ=PΣ進一步簡化,我們可以得到P矩陣:

\mathrm{RQ\Sigma}^{-1}=\mathrm{P}RQΣ?1=P

這是更新后的用戶特征相似性矩陣。類似地,如果將新電影添加到系統中,我們可以遵循類似的步驟來獲取更新的物品特征相關性矩陣Q。

記住,我們將R矩陣分解為P和Q。但是我們如何確定哪個P和Q矩陣將逼近R矩陣呢?我們可以使用梯度下降算法來做到這一點。此處的目的是實際等級與使用P和Q估算的評分之間的平方誤差最小。該平方誤差由下式給出:

\mathrm{e}_{\mathrm{ui}^{2}}=\left(\mathrm{r}_{\mathrm{ui}}-\check{\mathrm{r}}_{\mathrm{ui}}\right)^{2}=\left(\mathrm{r}_{\mathrm{ui}}-\Sigma_{\mathrm{k}=1}^{\mathrm{k}} \mathrm{p}_{\mathrm{uk}} \sigma_{\mathrm{k}} \mathrm{q}_{\mathrm{ki}}\right)^{2}eui2=(rui?rˇui)2=(rui?Σk=1kpukσkqki)2

這里,

  • eui是錯誤
  • rui是用戶u對電影i的實際評分
  • ?ui是用戶u對電影i的預測評分

我們的目標是確定p和q的值,使得誤差最小化。我們需要更新p和q值,以便獲得這些矩陣的優化值,從而使誤差最小?,F在,我們將為puk和qki定義一個更新規則。梯度下降中的更新規則由要最小化的誤差的梯度定義。\frac{\partial}{\partial p u k}\left(e_{u i}^{2}\right)=-2\left(r_{u i}-\check{r}_{u i}\right) q_{k i}=-2 e_{u i} q_{k i}?puk?(eui2)=?2(rui?rˇui)qki=?2euiqki

\frac{\partial}{\partial q k i}\left(e_{u i}^{2}\right)=-2\left(r_{u i}-\tilde{r}_{u i}\right) p_{u k}=-2 e_{u i} p_{u k}?qki?(eui2)=?2(rui?r~ui)puk=?2euipuk

由于現在我們有了梯度,我們可以為puk和qki應用更新規則。\mathrm{p}_{\mathrm{uk}}^{\prime}=\mathrm{p}_{\mathrm{uk}}-\alpha^{*} \frac{\partial}{\partial p u k}\left(\mathrm{e}_{u \mathrm{l}}^{2}\right)=\mathrm{p}_{\mathrm{uk}}+2 \mathrm{e}_{\mathrm{ui}} \mathrm{q}_{\mathrm{k}}puk′=puk?α??puk?(eul2)=puk+2euiqk

q_{k j}^{\prime}=q_{k i}-\alpha^{*} \frac{\partial}{\partial q k i}\left(e_{u i}^{2}\right)=q_{k i}+2 e_{u i} p_{u k}qkj′=qki?α??qki?(eui2)=qki+2euipuk

α是學習速率決定每個更新的大小??梢灾貜蜕鲜龅母?,直到將錯誤最小化為止。完成之后,我們將獲得可用于預測收視率的最佳P和Q矩陣。讓我們快速回顧一下該算法的工作原理,然后我們將構建推薦引擎來預測未評分電影的評分。

以下是矩陣分解如何用于預測收視率的方法:

# for f = 1,2,....,k :
    # for rui ε R :
        # predict rui
        # update puk and qki

因此,基于每個潛在特征,將使用預測的rui值填充R矩陣中所有缺失的評分。然后使用梯度下降對puk和qki進行更新,并獲得它們的最佳值??梢匀缦嘛@示:

現在,我們已經了解了該算法的內部工作原理,我們將舉一個例子,看看如何將矩陣分解為它的組成部分。

考慮一個2 X 3矩陣A 2X3,如下所示:

在這里,我們有2個用戶和3個電影的相應評分?,F在,我們將把這個矩陣分解為子部分,像這樣:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-nO23UsOj-1589942971148)(.\圖片\14.png)]

AAT的特征值將給我們P矩陣,而ATA的特征值將給我們Q矩陣。Σ是AAT或ATA的特征值的平方根。

計算AAT的特征值。

\begin{aligned} &\operatorname{det}\left(A A^{\top}-\lambda l\right)=0\\ &\lambda^{2}-34 \lambda+225=(\lambda-25)(\lambda-9)=0 \end{aligned}det(AA??λl)=0λ2?34λ+225=(λ?25)(λ?9)=0因此,AAT的特征值是25、9。類似地,我們可以計算ATA的特征值。這些值將分別為25、9、0?,F在,我們必須為AAT和ATA計算相應的特征向量。

對于λ= 25,我們有:

可以將其簡化為:

該矩陣中的單位長度向量為:

同樣,λ= 9我們有:

我們可以將行簡化為

該矩陣中的單位長度向量為:

該矩陣的內核中的單位長度向量為:

同樣,對于λ= 9,我們有:

可以將其減少為:

該矩陣的內核中的單位長度向量為:

對于最后一個特征向量,我們可以找到一個垂直于q1和q2的單位向量。所以,

Σ 2X3矩陣是矩陣特征值的平方根AAT或 ATA,即,25和9。

最后,我們可以通過公式σpi= Aqi或pi = 1 /σ(Aqi)來計算P 2X2。給出:

因此,A矩陣的分解形式為:

由于我們擁有P和Q矩陣,因此我們可以使用梯度下降方法來獲得它們的優化版本。讓我們使用矩陣分解來構建推薦引擎。

7.使用矩陣分解構建推薦引擎

我們定義一個函數來預測用戶對所有未由他/她評分的電影的評分。

class MF():

    # 初始化用戶電影評級矩陣, no.潛在的特征,α和β。
    def __init__(self, R, K, alpha, beta, iterations):
        self.R = R
        self.num_users, self.num_items = R.shape
        self.K = K
        self.alpha = alpha
        self.beta = beta
        self.iterations = iterations

    #初始化用戶特征和電影矩陣
    def train(self):
        self.P = np.random.normal(scale=1./self.K, size=(self.num_users, self.K))
        self.Q = np.random.normal(scale=1./self.K, size=(self.num_items, self.K))

        #初始化偏差項
        self.b_u = np.zeros(self.num_users)
        self.b_i = np.zeros(self.num_items)
        self.b = np.mean(self.R[np.where(self.R != 0)])

        #訓練樣本名單
        self.samples = [
        (i, j, self.R[i, j])
        for i in range(self.num_users)
        for j in range(self.num_items)
        if self.R[i, j] > 0
        ]

        #給定迭代次數的隨機梯度下降
        training_process = []
        for i in range(self.iterations):
        np.random.shuffle(self.samples)
        self.sgd()
        mse = self.mse()
        training_process.append((i, mse))
        if (i+1) % 20 == 0:
            print("Iteration: %d ; error = %.4f" % (i+1, mse))

        return training_process

    # 計算總平均平方誤差
    def mse(self):
        xs, ys = self.R.nonzero()
        predicted = self.full_matrix()
        error = 0
        for x, y in zip(xs, ys):
            error += pow(self.R[x, y] - predicted[x, y], 2)
        return np.sqrt(error)

    # 隨機梯度下降得到優化的P和Q矩陣
    def sgd(self):
        for i, j, r in self.samples:
            prediction = self.get_rating(i, j)
            e = (r - prediction)

            self.b_u[i] += self.alpha * (e - self.beta * self.b_u[i])
            self.b_i[j] += self.alpha * (e - self.beta * self.b_i[j])

            self.P[i, :] += self.alpha * (e * self.Q[j, :] - self.beta * self.P[i,:])
            self.Q[j, :] += self.alpha * (e * self.P[i, :] - self.beta * self.Q[j,:])

    # 用戶 i 和 電影 j的評分
    def get_rating(self, i, j):
        prediction = self.b + self.b_u[i] + self.b_i[j] + self.P[i, :].dot(self.Q[j, :].T)
        return prediction

    # 完整的用戶電影評分矩陣
    def full_matrix(self):
        return mf.b + mf.b_u[:,np.newaxis] + mf.b_i[np.newaxis:,] + mf.P.dot(mf.Q.T)

現在我們有了一個可以預測評分的函數。此函數的輸入是:

  • R –用戶電影評分矩陣
  • K –潛在特征
  • alpha –隨機梯度下降的學習率
  • beta –偏差的正則化參數
  • iterations–執行隨機梯度下降的迭代次數

我們必須將用戶項目評分轉換為矩陣形式??梢允褂?a href='/map/python/' style='color:#000;font-size:inherit;'>python中的Pivot函數來完成。

R= np.array(ratings.pivot(index = 'user_id', columns ='movie_id', values = 'rating').fillna(0))

fillna(0)將使用0填充所有缺失的評分?,F在我們有了R矩陣。我們可以初始化潛在特征的數量,但是這些特征的數量必須小于或等于原始特征的數量。

現在讓我們預測所有缺失的評分。讓我們假設K = 20,alpha = 0.001,beta = 0.01和iterations = 100。

mf = MF(R, K=20, alpha=0.001, beta=0.01, iterations=100)
training_process = mf.train()
print()
print("P x Q:")
print(mf.full_matrix())
print()

這將為我們提供與每20次迭代相對應的誤差值,最后是得到完整的用戶電影評分矩陣。輸出看起來像這樣:

我們已經創建了推薦引擎。在下一節中,我們將重點介紹如何評估推薦引擎。

8.推薦引擎的評估指標

為了評估推薦引擎,我們可以使用以下指標

8.1召回(Recall)

  • 用戶喜歡的商品中有多少是被推薦的
  • 它由下式給出:

\text { Recall }=\frac{t p}{t p+f n} Recall =tp+fntp

  • 這里tp代表推薦給用戶他/她的喜歡的數量,tp + fn代表用戶喜歡的數量總和如果用戶喜歡5個項目,推薦引擎決定推薦3個項目,則召回率為0.6召回次數越大,建議就越好

8.2精度(Precision):

  • 在所有推薦項目中,用戶實際喜歡的有多少?
  • 它由下式給出:\text { Precision }=\frac{t p}{t p+f p} Precision =tp+fptp
  • 這里tp代表推薦給用戶他/她喜歡的項目數量,tp + fp代表推薦給用戶的項目總數如果向用戶推薦了5個項目,而他最喜歡4個項目,則精度為0.8精度越高,建議越好但是請考慮一下這種情況:如果我們僅簡單的推薦所有項目,它們肯定會涵蓋用戶喜歡的項目。因此,我們有100%的召回率!但是請考慮一下精度。如果我們建議說1000個項目,而用戶只喜歡其中的10個項目,則精度為0.1%。這真的很低。因此,我們的目標應該是最大限度地提高準確性和召回率。

8.3 均方根誤差(RMSE):

  • 它測量預測分數中的誤差:R M S E=\sqrt{\frac{\sum_{i=1}^{N}\left(\text {Predicted}_{i}-\text {Actual}_{i}\right)^{2}}{N}}RMSE=N∑i=1N(Predictedi?Actuali)2
  • 在這里,“Predicted”是模型預測的評分,而“Actual”是原始評分如果用戶給電影評分為5,而我們預測的評分為4,則RMSE為1RMSE值越小,建議越好

上面的指標告訴我們我們的建議有多準確,但是它們不關注建議的順序,即它們不關注首先推薦的產品以及之后推薦的產品。我們需要一些指標,也應考慮推薦產品的順序。因此,讓我們看一些排名指標

8.4平均倒數排名(Mean Reciprocal Rank):

  • 評估建議列表\mathrm{MRR}=\frac{1}{\mathrm{n}} \cdot \sum_{i=1}^{\mathrm{n}} \frac{1}{\mathrm{r}\left(\mathrm{Q}_{i}\right)}MRR=n1?i=1∑nr(Qi)1
  • 假設我們向用戶推薦了3部電影,按照給定的順序為A,B,C,但用戶只喜歡電影C。由于電影C的順序為3,那么順序的倒數為1/3平均倒數排名越大,建議越好

8.5 K點映射:截止k點平均精度(MAP at k )

  • Precision和Recall并不在乎建議中的順序
  • 截止點k的精度是僅考慮從等級1到k級建議的子集所計算得出的精度M A P_{i}=\frac{1}{\left|R_{i}\right|} \sum_{k=1}^{\left|R_{i}\right|} P\left(R_{i}[k]\right)MAPi=∣Ri∣1k=1∑∣Ri∣P(Ri[k])
  • 假設我們提出了三個建議[0,1,1]。此處0表示推薦不正確,而1表示推薦正確。那么在k處的精度將為[0,1/2,2/3],平均精度將為(1/3)*(0 + 1/2 + 2/3)= 0.38所以平均精度越大,建議的精度就越高

8.6歸一化折現累積增益(NDCG)

  • MAP和NDCG之間的主要區別在于MAP假設某個項目是你感興趣的(或不感興趣的),而NDCG則給出了相關性得分
  • 讓我們以一個例子來理解它:假設從A到J的10部電影中,我們可以推薦前五部電影,即A,B,C,D和E,而我們不能推薦其他五部電影,即F, G,H,I和J。推薦為[A,B,C,D]。因此,在這種情況下,NDCG將為1,因為推薦產品與用戶相關
  • NDCG值越高,建議越好

9.我們還有什么可以嘗試的?

到目前為止,我們已經了解了什么是推薦引擎,它的不同類型及其工作方式?;趦热莸倪^濾和基于物品的過濾算法都有其優點和缺點。

在某些領域,生成有用的內容描述可能非常困難。如果用戶的先前行為沒有為此提供相關證據,則基于內容的過濾模型將不會選擇項目。必須使用其他技術,以便系統可以在用戶已經表現出興趣的范圍之外提出建議。

基于物品的過濾模型沒有這些缺點。因為不需要描述所建議的項目,所以系統可以處理任何類型的信息。此外,它可以推薦用戶以前不感興趣的產品。但是,如果沒有基于用戶評分的預測,則基于物品的過濾無法為新項目提供建議。即使用戶開始對該商品進行評分,該商品也需要花費一些時間才能獲得足夠的評分,以便做出準確的推薦。

結合了基于內容的過濾和基于物品的過濾的系統可能會從內容的表示形式以及用戶之間的相似性中受益。結合基于物品的協作過濾和基于內容的過濾的一種方法是基于基于內容的推薦和基于物品的推薦的加權平均值進行預測。這樣做的各種方法是:

  • 合并項目分數在這種方法中,我們結合了從兩種過濾方法獲得的評級。最簡單的方法是取評分的平均值假設一種方法建議電影的評分為4,而另一種方法建議同一電影的評分為5。因此最終的建議將是娶兩個分數的平均值,即4.5我們也可以為不同的方法分配不同的權重
  • 組合物品等級:假設基于物品的協同過濾推薦了5部電影A,B,C,D和E按以下順序進行推薦:A,B,C,D,E,而基于內容的過濾按以下順序推薦了它們:B,D,A,C,E那么電影的推薦排名為:

基于物品的協同過濾

電影排名A1B0.8C0.6D0.4E0.2

基于內容的過濾:

電影排名B1D0.8A0.6C0.4E0.2

因此,混合推薦引擎將合并這些排名,并根據合并后的排名做出最終推薦。合并排名為:

電影新排名A1 + 0.6 = 1.6B0.8 + 1 = 1.8C0.6 + 0.4 = 1D0.4 + 0.8 = 1.2E0.2 + 0.2 = 0.4

推薦將根據這些排名進行。因此,最終建議將如下所示:B,A,D,C,E。

通過這種方式,可以將兩種或更多種技術組合起來以構建混合推薦引擎并提高它們的總體推薦準確性和能力。

結束語

這是一篇有關推薦引擎的非常全面的文章。本教程應該足夠好,可以幫助你開始學習推薦引擎這個主題。我們不僅介紹了基本的推薦技術,還介紹了如何實施當今行業中可用的一些更先進的技術。

我們還介紹了與每種技術相關的一些關鍵事實。作為想學習如何創建推薦引擎的人,我建議你學習本教程中討論的技術,然后在模型中實現它們。

原文鏈接:https://www.analyticsvidhya.com/blog/2018/06/comprehensive-guide-recommendation-engine-python/?utm_source=blog&utm_medium=comprehensive-guide-k-means-cluster

數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢