聊聊推薦系統,FM模型效果好在哪裡?

Coder樑發表於2021-06-17

本文始發於公眾號: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模型搞懂再說

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的表示式,大家一看就明白了。

\[\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 \]

從這個公式當中,我們可以看出來當我們進行預測的時候,我們需要遍歷所有的交叉項,最終得到預測值。這裡又有了一個很大的問題,就是計算的複雜度。由於我們使用了所有特徵的二階交叉項,那麼我們需要累加的項的數量就是\(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)\),所以我們先把這兩項忽略,單獨來看第三項,也就是困擾我們的這一項。

對於這個式子,我們可以進行化簡:

\[\begin{aligned}\sum_{i=1}^n\sum_{j=i+1}^n v_i^T v_j x_i x_j &= \frac{1}{2}\sum_{i=1}^n\sum_{j=1}^n v_i^Tv_jx_i x_j - \frac{1}{2}\sum_{i=1}^nv_i^Tv_jx_ix_j\\&=\frac{1}{2}(\sum_{i=1}^n\sum_{j=1}^n\sum_{f=1}^kv_{i, f}v_{j, f}x_ix_j-\sum_{i=1}^n\sum_{f=1}^kv_{i,f}v_{i,f}x_ix_i)\\&=\frac{1}{2}\sum_{f=1}^k((\sum_{i=1}^nv_{i, f}x_i)(\sum_{j=1}^nv_{j, f}x_j)-\sum_{i=1}^nv_{i,f}^2x_i^2)\\&=\frac{1}{2}\sum_{f=1}^k((\sum_{i=1}^nv_{i,f}x_i)^2 - \sum_{i=1}^nv_{i, f}^2 x_i^2)\end{aligned} \]

簡單來解釋一下這個推導過程,第一行我想大家應該都能看懂,第二行也很好理解,其實就是把\(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家族當中的模型,看看它們都有怎樣的變化。

今天的文章就到這裡,感謝閱讀,如果喜歡的話,不要忘了三連。

相關文章