用Python進行奇異值分解(SVD)實戰指南
來自專欄論智
編寫:Bing
視頻:https://www.youtube.com/watch?v=d7iIb_XVkZs
Github:PirosB3/PyConUS2018
你是否經常沉迷於各大視頻網站,連續不斷地追劇?或者在某些音樂軟體的推薦列表中發現十分合自己口味的歌曲?事實上,這些視頻網站和音樂軟體能如此「智能」、私人化的背後,是一系列推薦機制。本文來源於機器學習工程師Daniel Pyrathon的一次演講,他是一款名為Coffee meets Bagel的社交APP的工程師。在這次演講中,他向大家講解了Python在推薦引擎的學習演算法中的應用。
什麼是推薦引擎
很多人都聽說過「搜索引擎」,推薦引擎與搜索引擎類似,是主動發現用戶當前或潛在的需求定律,並主動推送信息給用戶的信息網路,相當於在每個用戶上都安裝了一個搜索引擎。推薦引擎的優勢在於,它可以實時學習,不斷更新,隨著用戶使用某項應用或與其交互進行學習,並不斷優化結果。總的來說,推薦引擎的優點有兩個:
- 增強用戶粘性:如果用了推薦系統,用戶粘性會比傳統的搜索引擎效果更佳
- 多樣化的推薦:如果用戶以個人為單位,大量的數據會生成多樣化的推薦結果
目前,許多大公司都將推薦機製作為開發的重點。零售業巨頭亞馬遜35%的收益來自於它的推薦引擎,視頻網站Netflix中75%的用戶都是基於推薦演算法選擇影片。本文將針對推薦演算法的一個通用策略——協同過濾(collaborative filtering)進行講解,這是推薦引擎的一個細分領域,為了更好地理解這一策略,我們先從它的組成部分說起。
協同過濾有三大要素:用戶、評分和產品。首先,用戶是系統的重要組成因素,他們可以是博客的讀者,或者是網上商城的顧客。其次,產品就很容易理解了,可以是歌曲或者電影。最後,評分是連接用戶和產品之間的橋樑,它可以用數字表示,對用戶和產品之間的關係進行量化,也可以是點贊或反對等等可以讓用戶表達自己意見的方式。下文將以電影為例子,具體講解推薦機制。
什麼是協同過濾?
協同過濾是利用來自相似用戶的評分進行內容推薦的一種方法,具體可以用以下矩陣表示:
這裡有五位用戶和四部電影,每個格子中代表用戶對某部電影的意見。現在,推薦機制想要猜測用戶5對藍色電影的意見,即
協同過濾的第一步就是尋找與目標用戶相似的用戶。經過對比我們發現,用戶2和用戶5都支持綠色電影,都反對黃色電影;用戶3和用戶5都支持紅色電影和綠色電影;用戶2和3都對綠色和藍色電影給出了一致意見。所以我們可以很容易地進行初步推測,用戶5可能也不喜歡藍色電影。
這就是用現有的用戶評分,對目標用戶行為進行協同推測。除此之外,協同過濾還有很多形式,這裡,我們著重要講的是其中一種方法——奇異值分解(Singular Value Decomposition)。
奇異值分解
奇異值分解(SVD)是目前推薦引擎中一種常用的演算法,Spotify曾在文章中表示他們利用SVD進行推薦。Netflix還曾在2009年舉辦過一場競賽,希望找到能提高Netflix推薦演算法準確度的方法,最終獲勝的團隊正是利用SVD的一種變體,將推薦準確度提升了10%,並獲得了一百萬美元獎金。下面就是SVD的主要組成要素。
什麼是特徵(features)
特徵是機器學習演算法中與用戶和產品有關的元數據,在電影領域,用戶的特徵包括年齡、國家、性別等,產品特徵包括上映日期、導演、時長等。事實上我們認為,用戶對產品的評價都來自於這些特徵,我們將這些特徵輸入到學習演算法中,之後對各個特徵的權重進行定義。
然而這些特徵都是由人類定義的,並且是可以看到的。除此之外還有許多看不見的特徵,它們在預測評分時非常重要。類似SVD這類的演算法可以在資料庫中,基於已知的特徵,學習生成抽象的、新的特徵——隱性特徵(latent feature)。隱性特徵沒有具體的形式,但是可以用於高度信息化的語境中對用戶行為進行預測。
如何生成隱性特徵?
這裡,我們繼續用電影作為案例。下面是三位用戶和四部電影,每位用戶對其中幾部電影進行了評分,數字越大表示用戶越喜愛這部電影。
SVD中用到的方法稱為矩陣分解(matrix factorization),也就是將上面的矩陣分解為兩個小矩陣。將SVD運行到上面的矩陣中後,我們得到以下結果:
我們在用戶和電影中分別得到了兩個隱性特徵,如果將這兩個小矩陣重新結合,會得到與中間矩陣相似的結果。為了方便講解,這裡只用到了兩個隱性特徵,事實上,隱性特徵可以根據需要生成,隱性特徵越多,就表示你從原始矩陣中提取到的信息越多。
隱性特徵的用途主要有兩種:預測新分數和進行對比。當我們有了隱性特徵,就能隨意組合進行預測。例如我們想預測用戶1對藍色電影的看法,就可以進行數量積運算:
最終得到的結果為3.52,表明用戶1對藍色電影的評價較好。
除此之外,有了隱性特徵,我們還能對各元素進行對比,即在各用戶之間或各部電影之間進行對比,從而找到用戶之間或電影之間的相似度。這裡我用的是餘弦相似性進行表示。
從圖中可以看出,用戶1和3之間的夾角更小(0.046),也就是說二者的相似度比用戶3和用戶2之間的更高。
Demo
接下來,讓我們看看SVD的具體操作過程。首先作者介紹了如何訓練SVD模型,接著會講到如何生成推薦內容。
訓練一個SVD模型
首先,我們要下載一個名為MovieLens的數據集,這個數據集非常有名,內含2.7萬部電影和13.8萬用戶,總共有2000萬個評分。我們這裡列出了五組電影評分數據:
接著,我們要用到一個名為Surprise的庫訓練SVD,這一過程只需要四步。
第一步,創建一個讀取器。讀取器是Surprise庫中的一個元素,它可以定義評分中的高低值。
第二步,數據集初始化。在這一案例中,我們將數據分為三部分:用戶編號、產品編號(電影名稱)、評分。
第三步,保留一部分數據用於測試。這裡留下了25%的數據。
第四步,將SVD運行到數據集上。
訓練SVD演算法後會生成兩個矩陣,分別是用戶矩陣和產品矩陣。在模型之上還有一個名為qi的屬性,在這個案例中,qi的值如下所示:
(596,100)表示我們共研究了596部電影的評分,每部電影有100個隱性特徵。那麼我們該如何將這些隱性特徵與電影對應起來呢?這裡我們用到了一種隱藏特徵——raw2inner_items,這是一個詞典,可以將隱性特徵與電影的另一個特徵row_idx對應起來。
預測評分
用模型預測電影評非常簡單,只需要用到Surprise庫中的predict() API就可以實現。
相似性
我們知道,如果兩個對象之間的餘弦距離越接近0,表明二者越相似。這裡,我們要評估三部電影之間的相似性——《星球大戰》(1977)、《星球大戰VI:絕地歸來》(1983)和《阿拉丁)(1992)。首先,我們先比較《星球大戰》和《星球大戰VI:絕地歸來》之間的餘弦距離,結果是0.296。接著,我們比較《星球大戰》和《阿拉丁》之間的餘弦距離,結果是0.859。表明《星球大戰》和《星球大戰VI:絕地歸來》之間的相似度更高。這一過程只用到了評分,沒有其他任何訓練數據。
接著,我們還可以搜索與某一影片相關的其他電影,並且按相似度進行排名:
結語
在此次演講中,Daniel Pyrathon向我們展示了SVD在推薦演算法中強大的功能。同時,生成的隱性特徵不僅僅能用於推薦演算法,還可以用在分類演算法中。最重要的是,即使對分類演算法沒有過多地了解,也可以嘗試SVD的應用,並使用Surprise庫,因為Python真的非常簡潔,大大降低了SVD演算法的准入門檻。
推薦閱讀:
※有趣的數學問題
※如何培養孩子的數感?學霸教你以下幾招
※簡明複數基本運算
※數學速算方法(來自妙妙筆記)
※這樣的數學家,中國有一千個就了不得