本文始發於公眾號:Coder梁
大家好,我們今天繼續來聊聊推薦系統。
在上一回當中我們討論了LR模型對於推薦系統的應用,以及它為什么適合推薦系統,並且對它的優點以及缺點進行了分析。最后我們得出了結論,對於LR模型來說它的作用其實更多的是記住了一些特征的組合,所以在一些樣本當中表現非常好,但同樣也帶來了問題,就是需要人工生產大量的特征,帶來的負擔非常的大。
特征交叉
在我們講述解決方案之前,我們還是先來分析一下特征。
分析什么呢,分析我們人工制作的特征的內容。我們都知道無論是item還是user的統計類型的特征都是很容易搞定的,只需要做一些統計分析,有些更是可以直接從數倉當中獲取。真正麻煩的是什么呢,真正麻煩的是item和user相關聯的特征,在算法領域這種關聯稱為交叉。
舉個簡單的例子,比如男士_游戲
,女士_護膚品
這樣的特征,就是user和item進行交叉得出的。這里用到的是用戶的性別和商品的類別進行的交叉,除此之外我們還可以產生出各種各樣其他的交叉特征,本質上來說我們人工做的特征其實都是這些交叉特征。大家也可以想象得到,這些交叉特征對於能夠覆蓋到的樣本表現出來的效果肯定是非常好的,但是對於不能覆蓋的樣本其實就是完全沒有意義了。所以這就帶來了另外一個問題,就是泛化能力的問題。
說具體一點就是當我們交叉特征做到后面,能夠覆蓋的樣本的數量會非常非常少,尤其是一些本來就很小眾的特征之間的交叉。舉個例子,比如說高收入人群_房產
這個交叉特征。對於電商平台來說,房產本來就是很小眾的領域,只有極少數人才會閑着沒事在電商網站看房子。同樣高收入人群可能也很小眾,畢竟大部分人都是普通打工人,收入有限。這么一來,這樣得到的交叉特征能夠覆蓋的樣本就會非常非常稀疏。
大家可以簡單計算一下,假設房產在電商平台的商品當中的占比是1%,高收入群體在總用戶占比是10%的話,那么兩者交叉之后的占比就成了千分之一。那這樣稀疏的樣本在訓練模型的時候,我們是很難保證這個特征對應的權重已經訓練到了最佳程度。
如果說只是臟活累活多對於大公司來說倒也不是不可以忍受,大不了多雇一點人手就是了。但現在擺明了做出來的特征很有可能因為覆蓋率的問題沒有效果,那么這就不是很能接受了。
特征交叉的稀疏性以及大量的人力成本,這兩個問題是LR模型繞不開的硬傷,也是它被FM代替的直接原因。
Factorization Machines因子分解機
FM模型的英文全稱是Factorization Machine,翻譯過來就是因子分解機,一般業內都簡稱為FM。
FM是非常強大的模型雖然提出至今已經超過10年了,但目前仍然被很多中小型企業廣泛使用。它直接針對了LR的問題進行了修正,大大地提升了模型的效果,甚至可以說是推薦領域效果最顯著的一次大躍進。
我在之前的時候寫過FM這篇paper的完整解析,有感興趣的小伙伴可以通過下方的傳送門回顧一下。
FM的思想很簡單,就是強制特征之間做兩兩交叉。對於每一個交叉項都賦予一個權重,讓模型自己來學所有交叉項的權重。相當於把一維的LR拓展到了二維。
把一維拓展成二維和LR后期人們大量制作的手動交叉特征是一樣的,雖然是模型自動做了,但同樣會有稀疏性的問題。針對這個問題,FM創造性地提出了向量表示法。這個想法非常天才,可以說是划時代的。
向量表示法其實就是現在常說的embedding,也就是把一個標量用一個向量來代替。FM針對每一個特征在交叉之前都會賦予一個向量,這個向量的長度一般不會很長,介於16到256之間。我做過實驗,長度16和長度256效果上幾乎沒有差別。然后對於特征i和j,我們假設它們的向量分別是\(V_i, V_j\)。對於它們交叉項的權重,我們不是直接通過模型來賦予,而是用\(V_i \cdot V_j\)來計算得到。
這樣一來,對於特征數量是n的模型來說,它就把原本\(n * n\)的參數數量下降到了\(n * k\),這里的k就是我們剛才提到的向量的長度,這是一個常數。學過算法的同學都應該知道,這樣直接就把參數的數量級下降了一維。
我們寫出FM的表達式,大家一看就明白了。
從這個公式當中,我們可以看出來當我們進行預測的時候,我們需要遍歷所有的交叉項,最終得到預測值。這里又有了一個很大的問題,就是計算的復雜度。由於我們使用了所有特征的二階交叉項,那么我們需要累加的項的數量就是\(n^2\)。對於推薦場景來說,n是一個很大的值,動輒好幾十萬,顯然二階平方是我們無法接受的。
關於這個問題,FM模型有一段非常精彩的數學推導,完美地解決了這個問題。
復雜度優化
我們分析一下\(\hat{y} = w_0 + \sum_{i=1}^nw_ix_i+\sum_{i=1}^{n-1}\sum_{j=1}^nv_i^T v_jx_i, x_j\)這個式子,會發現前兩項都是一階項,復雜度都是\(O(n)\),所以我們先把這兩項忽略,單獨來看第三項,也就是困擾我們的這一項。
對於這個式子,我們可以進行化簡:
簡單來解釋一下這個推導過程,第一行我想大家應該都能看懂,第二行也很好理解,其實就是把\(v_i^Tv_j\)向量內積展開。第二行到第三行的轉化也不難理解,這里有三個\(\Sigma\),我們提取出的是最里面的\(\Sigma\),因為是有限項求和,我們調換順序並不會影響結果。提取出了公因式之后,得到的結果是兩個平方項。
這兩個平方項是精髓,因為它們都是\(O(n)\)的復雜度。正是因為把復雜的累加轉化成了兩個平方項的差,我們才完成了復雜度降維的工作。兩個平方項的計算復雜度都是\(O(n)\),再加上外面一層\(O(k)\)的復雜度,整體的復雜度是\(O(kn)\)。但由於k是常數,所以可近似看成\(O(n)\)的復雜度。
這樣我們就完成了FM模型預測的優化。
FM的優缺點
到這里,我們把FM的原理又過了一遍。
對於FM模型來說,它最大的優點就是擬合能力很強,因為引入了二階交叉的特征項,所以對於樣本的表達能力大大提升。並且由於通過數學公式,我們將\(O(n^2)\)的復雜度降到了\(O(n)\)。它的訓練以及預測速度都是非常快的,和LR旗鼓相當。
我們再來回顧一下LR的兩個問題,一個是需要人工制作大量的特征,第二個是樣本稀疏對於模型的訓練會有影響。
第一個問題已經沒有了,因為FM引入了自動交叉的機制,相當於默認幫助我們把所有的二階交叉特征都做了一遍。但對於第二個問題我們還需要分析一下,為什么FM模型可以解決樣本稀疏的問題呢?二階交叉項不還是會面臨樣本很少的情況嗎?
原因很簡單,因為FM把特征映射成了向量,在進行特征交叉的時候是通過向量的點乘來計算的交叉項的權重。對於特征i來說,它和其他所有特征交叉時使用的都是同一個向量\(V_i\)。這樣即使特征i和j的組合在樣本當中非常稀疏,但是由於\(V_i\)和\(V_j\)是單獨訓練的,所以我們仍然可以得到一個相對比較准確的權重。甚至即使i和j的組合在樣本當中沒有出現過,但是由於有了\(V_i\)和\(V_j\)向量,我們一樣可以表達i和j的組合特征,這也是正是FM強大的地方。
FM雖然強大但也不是沒有缺點,我們隨便想想也能找出來不少。比如說雖然模型自動做了二階交叉,但是二階交叉真的能表達所有的特征信息嗎?會不會有一些三階交叉的特征,甚至是四階交叉的特征會更有效果呢?而且所有的特征交叉都進行了學習,會不會當中有很多無用信息被包含進來了呢?再比如FM當中設定了每個特征和其他所有特征交叉的時候使用的向量是同一個,這樣一刀切真的效果最好嗎?再比如FM模型很難對連續性特征進行交叉,基本上只能交叉01離散型的特征,這樣真的不會丟失信息嗎?
我想這一系列問題問下來很難心里不大鼓,所以在FM時代的后期,針對FM模型的一些缺陷和不足進行了很多的實驗和嘗試,因此誕生了一系列各種各樣添磚加瓦的模型。FM模型也從單個模型成了一個巨大的家族,下一期我將會來和大家盤點一下FM家族當中的模型,看看它們都有怎樣的變化。
今天的文章就到這里,感謝閱讀,如果喜歡的話,不要忘了三連。