python機器學習:推薦系統實現(以矩陣分解來協同過濾)

原文鏈接:http://tecdat.cn/?p=10911

 

用戶和產品的潛在特徵編寫推薦系統矩陣分解工作原理使用潛在表徵來找到類似的產品。

1. 用戶和產品的潛在特徵

我們可以通過爲每個用戶和每部電影分配屬性,然後將它們相乘併合並結果來估計用戶喜歡電影的程度。

r語言機器學習:推薦系統實現(以矩陣分來解協作過濾)

相同的計算可以表示爲矩陣乘法問題。首先,我們把用戶屬性放在一個名爲U的矩陣中,在這個例子中是5,-2,1,-5和5。然後,我們把電影屬性放在一個名爲M的矩陣中,我們使用矩陣乘法來找出用戶的評分。

r語言機器學習:推薦系統實現(以矩陣分來解協作過濾)

但要做到這一點,我們必須已經知道用戶屬性和電影屬性。爲每個用戶和每部電影提供屬性評級並不容易。我們需要找到一種自動的方法。我們來看看電影評分矩陣,

r語言機器學習:推薦系統實現(以矩陣分來解協作過濾)

它顯示了我們數據集中的所有用戶如何評價電影。這個矩陣非常稀疏,但它給了我們很多信息。例如,我們知道用戶ID2給電影1號五顆星。所以,基於此,我們可以猜測,這個用戶的屬性可能類似於電影的屬性,因爲它們匹配的很好。換句話說,我們有一些線索可以使用。

讓我們看看我們如何利用這些線索來了解每部電影和每個用戶。在我們剛剛看到的等式中,U乘M等於電影等級,我們已經知道一些用戶的實際電影等級。我們已經擁有的電影評分矩陣是我們方程式的解決方案。雖然它是解決方案的一部分,但是這個陣列仍然有很多漏洞,但對於我們來說,這已經足夠了。

r語言機器學習:推薦系統實現(以矩陣分來解協作過濾)

實際上,我們可以使用目前爲止我們所知道的電影評級,然後逆向找到滿足該等式的U矩陣和M矩陣。當然,這纔是最酷的部分。當我們將U和M相乘時,他們實際上會給我們一個完整的矩陣,我們可以使用那個完成的矩陣來推薦電影。讓我們回顧一下我們將如何構建這個推薦系統。

r語言機器學習:推薦系統實現(以矩陣分來解協作過濾)

首先,我們創建了我們在數據集中所有用戶評論的矩陣。接下來,我們從已知的評論中分解出一個U矩陣和一個M矩陣。最後,我們將把我們找到的U和M矩陣相乘,得到每個用戶和每部電影的評分。但是還有一個問題。以前,當我們爲每個用戶和每部電影手工創建屬性時,我們知道每個屬性的含義。我們知道第一個屬性代表動作,第二個代表劇情,等等。但是當我們使用矩陣分解來提出U和M時,我們不知道每個值是什麼意思。我們所知道的是,每個價值都代表了一些讓用戶感覺被某些電影吸引的特徵。我們不知道如何用文字來描述這些特徵。因此,U和M被稱爲潛在向量。潛在的詞意味着隱藏。換句話說,這些向量是隱藏的信息,我們通過查看評論數據和反向推導。

2. 編寫推薦系統

我們來編寫推薦系統的主要代碼。打開Chapter 5/factor_review_matrix.py。首先,我將使用pandas read_csv函數將檢查數據集加載到名爲raw_dataset_df的數據集中。

然後我們使用pandas數據透視表函數來構建評論矩陣。在這一點上,ratings_df包含一個稀疏的評論陣列。

接下來,我們希望將數組分解以找到用戶屬性矩陣和我們可以重新乘回的電影屬性矩陣來重新創建收視率數據。爲此,我們將使用低秩矩陣分解算法。我已經在matrix_factorization_utilities.py中包含了這個實現。我們將在下一個視頻中詳細討論它是如何工作的,但讓我們繼續使用它。首先,我們傳遞了評分數據,但是我們將調用pandas的as_matrix()函數,以確保我們作爲一個numpy矩陣數據類型傳入。

接下來,這個方法接受一個名爲num_features的參數。 Num_features控制爲每個用戶和每個電影生成多少個潛在特徵。我們將以15爲起點。這個函數還有個參數regularization_amount。現在讓我們傳入0.1。在後面的文章中我們將討論如何調整這個參數。

函數的結果是U矩陣和M矩陣,每個用戶和每個電影分別具有15個屬性。現在,我們可以通過將U和M相乘來得到每部電影的評分。但不是使用常規的乘法運算符,而是使用numpy的matmul函數,所以它知道我們要做矩陣乘法。

結果存儲在一個名爲predicted_ratings的數組中。最後,我們將predict_ratings保存到一個csv文件。

首先,我們將創建一個新的pandas數據框來保存數據。對於這個數據框,我們會告訴pandas使用與ratings_df數據框中相同的行和列名稱。然後,我們將使用pandas csv函數將數據保存到文件。運行這個程序後可以看到,它創建了一個名爲predicted_ratings.csv的新文件。我們可以使用任何電子表格應用程序打開該文件。

r語言機器學習:推薦系統實現(以矩陣分來解協作過濾)

這個數據看起來就像我們原來的評論數據,現在每個單元格都填滿了。現在我們評估下每個單個用戶會爲每個單獨的電影評分。例如,我們可以看到用戶3評級電影4,他們會給它一個四星級的評級。現在我們知道所有這些評分,我們可以按照評分順序向用戶推薦電影。讓我們看看用戶1號,看看我們推薦給他們的電影。在所有這些電影中,如果我們排除了用戶以前評價過的電影,右邊34號電影是最高分的電影,所以這是我們應該推薦給這個用戶的第一部電影。當用戶觀看這部電影時,我們會要求他們評分。如果他們的評價與我們預測的不一致,我們將添加新評級並重新計算此矩陣。這將有助於我們提高整體評分。我們從中獲得的評分越多,我們的評分陣列中就會出現的孔越少,我們就有更好的機會爲U和M矩陣提供準確的值。

3. 矩陣分解工作原理

因爲評分矩陣等於將用戶屬性矩陣乘以電影屬性矩陣的結果,所以我們可以使用矩陣分解反向工作以找到U和M的值。在代碼中,我們使用稱爲低秩矩陣分解的算法,去做這個。我們來看看這個算法是如何工作的。矩陣分解是一個大矩陣可以分解成更小的矩陣的思想。所以,假設我們有一個大的數字矩陣,並且假設我們想要找到兩個更小的矩陣相乘來產生那個大的矩陣,我們的目標是找到兩個更小的矩陣來滿足這個要求。如果您碰巧是線性代數的專家,您可能知道有一些標準的方法來對矩陣進行因式分解,比如使用一個稱爲奇異值分解的過程。但是,這是有這麼一個特殊的情況下,將無法正常工作。問題是我們只知道大矩陣中的一些值。大矩陣中的許多條目是空白的,或者用戶還沒有檢查特定的電影。所以,我們不是直接將評級數組分成兩個較小的矩陣,而是使用迭代算法估計較小的矩陣的值。我們會猜測和檢查,直到我們接近正確的答案。哎哎等等, 咋回事呢?首先,我們將創建U和M矩陣,但將所有值設置爲隨機數。因爲U和M都是隨機數,所以如果我們現在乘以U和M,結果是隨機的。下一步是檢查我們的計算評級矩陣與真實評級矩陣與U和M的當前值有多不同。但是我們將忽略評級矩陣中所有沒有數據的點,只看在我們有實際用戶評論的地方。我們將這種差異稱爲成本。成本就是錯誤率。接下來,我們將使用數字優化算法來搜索最小成本。數值優化算法將一次調整U和M中的數字。目標是讓每一步的成本函數更接近於零。我們將使用的函數稱爲fmin_cg。它搜索使函數返回最小可能輸出的輸入。它由SciPy庫提供。最後,fmin_cg函數將循環數百次,直到我們得到儘可能小的代價。當成本函數的價值如我們所能得到的那樣低,那麼U和M的最終值就是我們將要使用的。但是因爲它們只是近似值,所以它們不會完全完美。當我們將這些U矩陣和M矩陣相乘來計算電影評級時,將其與原始電影評級進行比較,我們會看到還是有一些差異。但是隻要我們接近,少量的差異就無關緊要了。

4. 使用潛在特徵來找到類似的產品

r語言機器學習:推薦系統實現(以矩陣分來解協作過濾)

搜索引擎是用戶發現新網站的常用方式。當第一次用戶從搜索引擎訪問您的網站時,您對用戶尚不足以提供個性化推薦,直到用戶輸入一些產品評論時,我們的推薦系統還不能推薦他們。在這種情況下,我們可以向用戶展示與他們已經在查看的產品類似的產品。目標是讓他們在網站上,讓他們看更多的產品。你可能在網上購物網站上看到過這個功能,如果你喜歡這個產品,你可能也會喜歡這些其他的產品。通過使用矩陣分解計算產品屬性,我們可以計算產品相似度。讓我們來看看find_similar_products.py。首先,我們將使用pandas的讀取CSV功能加載電影評級數據集。

我們還會使用read_csv將movies.csv加載到名爲movies_df的數據框中。

然後,我們將使用pandas的數據透視表函數(pivot_table)來創建評分矩陣,我們將使用矩陣分解來計算U和M矩陣。現在,每個電影都由矩陣中的一列表示。首先,我們使用numpy的轉置函數來觸發矩陣,使每一列變成一行。

這只是使數據更容易處理,它不會改變數據本身。在矩陣中,每個電影有15個唯一的值代表該電影的特徵。這意味着其他電影幾乎相同的電影應該是非常相似的。要找到類似這個電影的其他電影,我們只需要找到其他電影的編號是最接近這部電影的數字。這只是一個減法問題。讓我們選擇用戶正在看的主要電影,讓我們選擇電影ID5。

如果你喜歡,你可以選擇其他的電影。現在,我們來看看電影ID5的標題和流派。我們可以通過查看movies_df數據框並使用pandas的loc函數通過其索引查找行來做到這一點。讓我們打印出該電影的標題和流派。

接下來,讓我們從矩陣中獲取電影ID爲5的電影屬性。我們必須在這裏減去一個,因爲M是0索引,但電影ID從1開始。現在,讓我們打印出這些電影屬性,以便我們看到它們,這些屬性我們準備好找到類似的電影。

第一步是從其他電影中減去這部電影的屬性。這一行代碼從矩陣的每一行中分別減去當前的電影特徵。這給了我們當前電影和數據庫中其他電影之間的分數差異。您也可以使用四個循環來一次減去一個電影,但使用numpy,我們可以在一行代碼中完成。第二步是取我們在第一步計算出的差值的絕對值,numpy的ABS函數給我們絕對值,這只是確保任何負數出來都是正值。接下來,我們將每個電影的15個單獨的屬性差異合併爲一個電影的總差異分數。 numpy的總和功能將做到這一點。我們還會傳入訪問權限等於一個來告訴numpy總結每行中的所有數字,併爲每行產生一個單獨的總和。在這一點上,我們完成了計算。我們只是將計算得分保存回電影列表中,以便我們能夠打印每部電影的名稱。在第五步中,我們按照我們計算的差異分數對電影列表進行排序,以便在列表中首先顯示最少的不同電影。這裏pandas提供了一個方便的排序值函數。最後,在第六步中,我們打印排序列表中的前五個電影。這些是與當前電影最相似的電影。

好的,我們來運行這個程序。 我們可以看到我們爲這部電影計算的15個屬性。這是我們發現的五個最相似的電影。第一部電影是用戶已經看過的電影。 接下來的四部電影是我們向用戶展示的類似項目。根據他們的頭銜,這些電影看起來可能非常相似。他們似乎都是關於犯罪和調查的電影。續集,大城市法官三,都在名單上。這是用戶可能也會感興趣的電影。您可以更改電影ID並再次運行該程序,以查看與其他電影類似的內容。

發佈了445 篇原創文章 · 獲贊 246 · 訪問量 97萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章