一文讀懂FM演算法優勢,並用python實現!(附程式碼)
作者:ANKIT CHOUDHARY
翻譯:張媛
術語校對:馮羽
文字校對:譚佳瑤
本文共3933字,建議閱讀9分鐘。
本文帶大家瞭解因子分解機演算法並解析其優勢所在,教你在python中實現。
介紹
我仍然記得第一次遇到點選率預測問題時的情形,在那之前,我一直在學習資料科學,對自己取得的進展很滿意,在機器學習黑客馬拉松活動中也開始建立了自信,並決定好好迎接不同的挑戰。
為了做得更好,我購買了一臺記憶體16GB,i7處理器的機器,但是當我看到資料集的時候卻感到非常不安,解壓縮之後的資料大概有50GB - 我不知道基於這樣的資料集要怎樣進行點選率預測。幸運地是,Factorization Machines(FM)演算法拯救了我。
任何從事點選率預測問題或者推薦系統相關工作的人都會遇到類似的情況。由於資料量巨大,利用有限的計算資源對這些資料集進行預測是很有挑戰性的。
然而在大多數情況下,由於很多特徵對預測並不重要,所以這些資料集是稀疏的(每個訓練樣本只有幾個變數是非零的)。在資料稀疏的場景下,因子分解有助於從原始資料中提取到重要的潛式或隱式的特徵。
因子分解有助於使用低維稠密矩陣來表示目標和預測變數之間的近似關係。在本文中我將討論演算法Factorization Machines(FM) 和Field-Aware Factorization Machines(FFM),然後在迴歸/分類問題中討論因子分解的優勢,並通過python程式設計實現。
目錄
1. 因式分解的直觀介紹
2. FM演算法如何優於多項式和線性模型
3. FFM演算法介紹
4. 在python中使用xLearn庫進行演算法實現
因式分解的直觀介紹
為了直觀地理解矩陣分解,我們來看一個例子:假設有一個使用者-電影評分(1-5)矩陣,矩陣中的每一個值表示使用者給電影的評分(1-5)。
從上述表格中我們可以看出,一些評分是缺失的,我們想設計一種方法來預測這些缺失的評分。直觀上來講,利用矩陣分解來解決這個問題的關鍵是應該有一些潛在的特徵決定使用者如何評價一部電影。舉例來說 - 使用者A和B都是演員阿爾·帕西諾的粉絲,那麼他們就會對阿爾·帕西諾的電影評分較高。在上述例子中,對特定演員的偏好是一個隱藏的特性,因為我們沒有明確地將其包含在評分矩陣中。
假設我們要計算K個隱藏或潛在的特徵,我們的任務是找出矩陣P (U x K)和Q (D x K) (U – 使用者, D – 電影),使得 P x QT 近似等於評分矩陣R。
P矩陣的每一行表示使用者與不同特徵的相關性,Q矩陣的每一行表示該特徵與電影同樣的相關性。為了得到使用者ui對電影dj的評分,我們可以計算對應於ui和dj兩個向量的點積。
接下來要做的就是求出矩陣P和矩陣Q。我們使用梯度下降演算法來計算,目標函式是使使用者的實際評分與通過矩陣P和Q估計的評分之間的平方誤差最小,這裡的平方誤差由以下方程求出。
現在我們要給pik和qkj定義一個更新規則,梯度下降法中的更新規則是由最小化誤差值的梯度來定義的。
獲得梯度值後,接下來可以定義pik和qkj的更新規則。
這裡α是控制更新步長的學習速率,使用上述更新規則,我們可以迭代地執行操作,直到誤差收斂到最小,同時使用下面的公式計算總的誤差,以此來確定什麼情況下應該停止迭代。
上述解決方案很簡單並且經常會導致過擬合,即現有的評分都被準確預測到,但是不能很好地推廣到未知的資料上。為了解決這個問題,我們可以引入一個正則化引數 β,它將分別控制矩陣P和Q中向量“使用者-特徵”和“電影-特徵”,並給出一個更好的評分的近似值。
如果對利用python實現上述功能和相關細節感興趣,請參考這個連結http://www.quuxlabs.com/wp-content/uploads/2010/09/mf.py_.txt。一旦我們用上述方法計算出了矩陣P和Q,得到的近似評分矩陣如下:
現在,我們既能夠重新生成現有評分,也能對未知的評分進行一個合理的近似。
FM演算法如何優於多項式和線性模型
首先考慮一組點選率預測資料的訓練示例。以下資料來自相關體育新聞網站(釋出商)和體育用品公司(廣告商)。
當我們討論FM或者FFM的時候,資料集中的每一列(比如上述表格中的出版商、廣告商等)將被稱為一個欄位,每一個值( ESPN、Nike 等)都被稱為一個特徵。
線性或邏輯迴歸模型在很多問題上表現很好,但缺點是這種模型只能學習所有變數或者特徵各自的影響,無法學習變數之間的相互作用
。
在上述等式中,w0、wESPN等代表引數,xESPN、xNike等代表資料集中的各個特徵,通過最小化上述函式的對數損失,得到邏輯迴歸模型。捕獲特徵之間相互作用的一種方法是使用多項式函式,將每個特徵對的乘積作為單獨的引數來學習,並且把每一個乘積作為一個獨立的變數。
這也可以稱為 Poly2模型,因為每一項都只考慮了兩個特徵之間的相互影響。
問題在於,即使面對一箇中等大小的資料集,也需要一個龐大的模型,這對儲存模型所需要的記憶體空間和訓練模型所花費的時間都有很大的影響;
其次,對於一個稀疏資料集,這種技術不能很好地學習所有的權重或引數,因為沒有有足夠的訓練樣本使每一個特徵對的權重是可靠的。
救星FM
FM演算法解決了成對特徵互動的問題。它使我們能夠根據每一對特徵組合中的可靠資訊(隱藏特徵)來訓練模型,同時在時間和空間複雜度上更有效地實現上述目標。具體來講,它將成對互動特徵作為低維向量的點積(長度為K)進行建模,以下包含了一個二階因子分解的方程。
FM(K=3)項中每個引數的表示方法如下:
上述等式中,我們分別計算了與2個特徵對應的2個長度為3的潛因子的點積。
從建模的角度來看,這是非常強大的,因為每一個特徵最後都會轉換到一個相似特徵被互相巢狀的空間,簡而言之,點積基本上表示了潛在特徵的相似程度,特徵越相近,點積越大。
對於餘弦函式,當 θ是0時,得到最大值1;當 θ是180度,得到-1,所以當 θ接近於0時,相似性最大。
FM演算法的另一個巨大優勢是能夠線上性時間複雜度下使用簡單的數學方法計算模型中成對特徵的相互作用。如果你想進一步瞭解具體的實現步驟,請參考連結中關於FM演算法的原始研究論文。
https://www.csie.ntu.edu.tw/~b97053/paper/Rendle2010FM.pdf
示例:FM演算法效能優於 POLY2演算法的演示
考慮以下一組虛構的點選率資料:
這個資料集由作為釋出者的體育網站和體育用品廣告商構成。廣告是以彈出的方式來顯示的,使用者可以選擇點選廣告或者關閉廣告。
特徵對(ESPN,Adidas)只有一個負的訓練資料,那麼在Poly2演算法中,這個特徵對可能會學到一個負的權重值wESPN,Adidas;而在FM演算法中,由於特徵對(ESPN,Adidas)是由wESPN·wAdidas決定的,而其中的wESPN和wAdidas分別是從其他特徵對中學到的(比如(ESPN,Nike),(NBC,Adidas)等),所以預測可能更加精確。
另一個例子是特徵對(NBC,Gucci)沒有任何訓練資料,對於Poly2演算法,這個特徵對的預測值為0;但是在FM演算法中,因為wNBC和wGucci可以從其他特徵對中學到,所以仍然有可能得到有意義的預測值。
FFM演算法介紹
為了理解FFM演算法,我們需要認識field的概念。field通常是指包含一個特定特徵的更廣泛的類別。在上述訓練示例中,field分別指釋出者(P)、廣告商(A)和性別(G)。
在FM演算法中,每一個特徵只有一個隱向量v,來學習其他特徵帶來的潛在影響。以ESPN為例,wESPN被用來學習特徵Nike(wESPN·wNike)和Male(wESPN.wMale)之間的潛在作用。
但是,由於ESPN和Male屬於不同的field,所以對特徵對(ESPN,Nike)和(ESPN,Male)的起作用的潛在作用可能不同。FM演算法無法捕捉這個差異,因為它不區分field的概念,在這兩種情況中,它會使用相同引數的點積來計算。
在FFM演算法中,每個特徵有若干個隱向量。例如,當考慮特徵ESPN和Nike之間的互動作用時,用符號wESPN,A來表示ESPN的隱藏特徵,其中A(廣告商)表示特徵Nike的field。類似的,關於性別的field的一個重要的引數wESPN,G也會被學習到。
事實證明,FFM演算法對獲得由 Criteo、Avazu、Outbrain舉辦的點選率(CTR)比賽第一名是至關重要的,同時也幫助贏得了2015年RecSys挑戰賽的三等獎。關於點選率資料集可以從Kaggle獲得。
在python中使用xLearn庫進行演算法實現
一些在python中實現FM & FFM的最流行的庫如下所示:
為了在資料集上使用FM演算法,需要將資料轉換為libSVM格式。以下為訓練和測試的資料檔案格式:
<label> <feature1>:<value1> <feature2>:<value2> …
在增加了field的概念之後,每個特徵被唯一編碼並被賦值,上述圖中,特徵ESPN用1表示,特徵Nike用2表示,以此類推。每一行包含一個等效的訓練示例並以“\ n”或換行符結尾。
對於分類(二進位制/多類),<label>是一個指示類標籤的整數。
對於迴歸,<label>是任何實數的目標值。
測試檔案中的標籤僅用於計算準確度或誤差,未知的情況下可以用任何數值填寫第一列。
同樣,對於FFM演算法,需要將資料轉換為libffm格式。在這裡,我們也需要對field進行編碼,因為該演算法需要field的資訊來學習。格式如下:
<label><field1>:<feature1>:<value1><field2>:<feature2>:<value2> …
有關數值特徵的重要說明
數值特徵需要被離散化(通過將特定數值特徵的整個範圍分成較小的範圍並且分別對每個範圍進行標記編碼而轉換為分類特徵),然後如上所示轉換為libffm格式。
另一種可能性是新增一個與特徵值相同的虛擬field值,它將是該特定行的數值特徵(例如,具有值45.3的特徵可以被變換為1:1:45.3)。 但是虛擬field值可能不包含任何資訊,因為它們僅僅是這些數值特徵的複製品。
xLearn
最近推出的xLearn庫提供了一個在各種資料集上實現FM和FFM模型的快速解決方案。 它比libfm和libffm庫快得多,為模型測試和調優提供了更好的功能。
在這裡,我們將用一個例子來說明FFM演算法,資料來自Criteo點選率預測挑戰賽中CTR資料集的一個微小(1%)抽樣。 你可以從這裡[Office1] 下載這個資料集。
但首先我們需要將其轉換為xLearn所需的libffm格式以擬合模型。 以下函式將標準資料幀格式的資料集轉換為libffm格式。
df = Dataframe to be converted to ffm format
Type = Train/Test/Val
Numerics = list of all numeric fields
Categories = list of all categorical fields
Features = list of all features except the Label and Id
xLearn可以直接處理csv以及libsvm格式的資料來實現FM演算法,但對FFM演算法而言,我們必須將資料轉換為libffm格式。
一旦我們有了libffm格式的資料集,就可以使用xLearn庫來訓練模型。
類似於任何其他機器學習演算法,資料集被分成一個訓練集和一個驗證集。xLearn使用驗證/測試對數損失來自動執行提前停止的操作,並且我們還可以在隨機梯度下降的迭代中為驗證集設定其他的監控指標。
下面的python指令碼可以用於在ffm格式的資料集上使用xLearn來訓練和調整FFM模型的超引數。
該庫還允許我們使用cv()函式進行交叉驗證:
可以使用以下程式碼片段對測試集進行預測:
結語
在這篇文章中,我們已經演示了對一般分類/迴歸問題的因式分解的用法。如果您在執行這個演算法的過程中遇到任何問題請及時告知我們。有關xLearn詳細文件將在這個連結中給出,並會得到定期更新和支援。
http://xlearn-doc.readthedocs.io/en/latest/python_api.html
原文連結:
https://www.analyticsvidhya.com/blog/2018/01/factorization-machines/
張媛,某雲端計算公司不務正業服務工程師一枚。喜歡下雨天,讀閒書,缺乏技術細胞,欣賞並喜歡有態度有立場的人,愛浪漫,注重儀式感,喜歡記錄。最近的願望是擁有自己的小窩,給想念的人寫一封信。
翻譯組招募資訊
工作內容:將選取好的外文前沿文章準確地翻譯成流暢的中文。如果你是資料科學/統計學/計算機專業的留學生,或在海外從事相關工作,或對自己外語水平有信心的朋友,資料派翻譯組歡迎你們加入!
你能得到:提高對於資料科學前沿的認知,提高對外文新聞來源渠道的認知,海外的朋友可以和國內技術應用發展保持聯絡,資料派團隊產學研的背景為志願者帶來好的發展機遇。
其他福利:和來自於名企的資料科學工作者,北大清華以及海外等名校學生共同合作、交流。
點選文末“閱讀原文”加入資料派團隊~
轉載須知
如需轉載,請在開篇顯著位置註明作者和出處(轉自:資料派THUID:DatapiTHU),並在文章結尾放置資料派醒目二維碼。有原創標識文章,請傳送【文章名稱-待授權公眾號名稱及ID】至聯絡郵箱,申請白名單授權並按要求編輯。
釋出後請將連結反饋至聯絡郵箱(見下方)。未經許可的轉載以及改編者,我們將依法追究其法律責任。
為保證發文質量、樹立口碑,資料派現設立“錯別字基金”,鼓勵讀者積極糾錯。
若您在閱讀文章過程中發現任何錯誤,請在文末留言,或到後臺反饋,經小編確認後,資料派將向檢舉讀者發8.8元紅包。
同一位讀者指出同一篇文章多處錯誤,獎金不變。不同讀者指出同一處錯誤,獎勵第一位讀者。
感謝一直以來您的關注和支援,希望您能夠監督資料派產出更加高質的內容。
點選“閱讀原文”加入組織~
相關文章
- 一文讀懂「Attention is All You Need」| 附程式碼實現
- 一文讀懂支援向量機SVM(附實現程式碼、公式)公式
- FM演算法python實現演算法Python
- python實現FM演算法Python演算法
- 一文讀懂層次聚類(Python程式碼)聚類Python
- 一文讀懂微搭低程式碼
- 一文讀懂智慧城市發展趨勢
- OceanBase 原始碼解讀(七):一文讀懂資料庫索引實現原理原始碼資料庫索引
- 從程式碼層讀懂 Java HashMap 的實現原理JavaHashMap
- 資料變金礦:一文讀懂序列模型(附用例)模型
- 一文讀懂遺傳演算法基礎知識與實際應用演算法
- 一文讀懂SuperEdge拓撲演算法演算法
- 一文讀懂影象壓縮演算法演算法
- 怎樣用一行 Python 程式碼實現並行Python並行
- 一文讀懂動態規劃演算法動態規劃演算法
- 工業品MRO採購網站有哪些優勢?一文帶你讀懂!網站
- 一文讀懂隨機森林的解釋和實現隨機森林
- 一文讀懂Python中的對映Python
- 一文讀懂 MongoDB驅動程式 APIMongoDBAPI
- 一文讀懂mavenMaven
- 一行 Python 程式碼實現並行Python並行
- 一文讀懂常見HTTP狀態碼HTTP
- 一文讀懂如何實施資料治理?
- 如何讀懂並寫出裝逼的函式式程式碼函式
- 一文讀懂微核心
- 一文讀懂特徵工程特徵工程
- 一文讓你讀懂Synchronized底層實現,秒殺面試官synchronized面試
- 用6行Python程式碼實現選擇性排序演算法Python排序演算法
- 一文讀懂所有HTTP狀態碼含義HTTP
- 一文徹底讀懂 hystrix-go 原始碼Go原始碼
- 【機器學習】:Kmeans均值聚類演算法原理(附帶Python程式碼實現)機器學習聚類演算法Python
- 一文讀懂海姆達爾Heimdallr經濟模型,解析鏈遊明星的價值優勢!模型
- 從FM推演各深度CTR預估模型(附程式碼)模型
- 夯實Java基礎系列7:一文讀懂Java 程式碼塊和執行順序Java
- 一文讀懂大資料實時計算大資料
- 【晶片】一文讀懂:真實的中國晶片產業晶片產業
- 一文讀懂圖資料庫 Nebula Graph 訪問控制實現原理資料庫
- 一文讀懂區塊鏈以及一個區塊鏈的實現區塊鏈