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包含一個稀疏的評論陣列。spa

接下來,咱們但願將數組分解以找到用戶屬性矩陣和咱們能夠從新乘回的電影屬性矩陣來從新建立收視率數據。爲此,咱們將使用低秩矩陣分解算法。我已經在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並再次運行該程序,以查看與其餘電影相似的內容。

相關文章
相關標籤/搜索