深度學習推薦系統(tǒng)-DeepFM

DeepFM

0.結(jié)論

  • DeepFM對W&D模型的改進之處:用FM替代了原來Wide部分,加強了淺層網(wǎng)絡部分的特征組合能力
  • DeepFM改進之處與DeepCrossing的思路基本一致绑改,唯一不同之處在于DeepCrossing模型利用多層Cross網(wǎng)絡進行特征組合纳猫,而DeepFM模型利用FM進行特征組合
  • FM的局限性:屬于二階特征交叉的模型暑始,無法擴展到三階以上球及,限制其模型的表達

1. 動機

對于CTR問題合愈,被證明的最有效的提升任務表現(xiàn)的策略是特征組合(Feature Interaction), 在CTR問題的探究歷史上來看就是如何更好地學習特征組合照捡,進而更加精確地描述數(shù)據(jù)的特點』安啵可以說這是基礎(chǔ)推薦模型到深度學習推薦模型遵循的一個主要的思想栗精。而組合特征大牛們研究過組合二階特征,三階甚至更高階瞻鹏,但是面臨一個問題就是隨著階數(shù)的提升悲立,復雜度就成幾何倍的升高。這樣即使模型的表現(xiàn)更好了新博,但是推薦系統(tǒng)在實時性的要求也不能滿足了薪夕。所以很多模型的出現(xiàn)都是為了解決另外一個更加深入的問題:如何更高效的學習特征組合?

為了解決上述問題赫悄,出現(xiàn)了FM和FFM來優(yōu)化LR的特征組合較差這一個問題原献。并且在這個時候科學家們已經(jīng)發(fā)現(xiàn)了DNN在特征組合方面的優(yōu)勢馏慨,所以又出現(xiàn)了FNN和PNN等使用深度網(wǎng)絡的模型。但是DNN也存在局限性姑隅。

  • ==DNN局限==
    當我們使用DNN網(wǎng)絡解決推薦問題的時候存在網(wǎng)絡參數(shù)過于龐大的問題写隶,這是因為在進行特征處理的時候我們需要使用one-hot編碼來處理離散特征,這會導致輸入的維度猛增讲仰。這里借用AI大會的一張圖片:


    image

這樣龐大的參數(shù)量也是不實際的慕趴。為了解決DNN參數(shù)量過大的局限性,可以采用非常經(jīng)典的Field思想鄙陡,將OneHot特征轉(zhuǎn)換為Dense Vector

image

此時通過增加全連接層就可以實現(xiàn)高階的特征組合冕房,如下圖所示:
image

但是仍然缺少低階的特征組合,于是增加FM來表示低階的特征組合趁矾。

  • ==FNN和PNN==

結(jié)合FM和DNN其實有兩種方式耙册,可以并行結(jié)合也可以串行結(jié)合。這兩種方式各有幾種代表模型愈魏。在DeepFM之前有FNN觅玻,雖然在影響力上可能并不如DeepFM,但是了解FNN的思想對我們理解DeepFM的特點和優(yōu)點是很有幫助的培漏。


image

FNN是使用預訓練好的FM模塊溪厘,得到隱向量,然后把隱向量作為DNN的輸入牌柄,但是經(jīng)過實驗進一步發(fā)現(xiàn)畸悬,在Embedding layer和hidden layer1之間增加一個product層(如上圖所示)可以提高模型的表現(xiàn),所以提出了PNN珊佣,使用product layer替換FM預訓練層蹋宦。

  • ==Wide&Deep==

FNN和PNN模型仍然有一個比較明顯的尚未解決的缺點:對于低階組合特征學習到的比較少,這一點主要是由于FM和DNN的串行方式導致的咒锻,也就是雖然FM學到了低階特征組合冷冗,但是DNN的全連接結(jié)構(gòu)導致低階特征并不能在DNN的輸出端較好的表現(xiàn)』笸В看來我們已經(jīng)找到問題了蒿辙,將串行方式改進為并行方式能比較好的解決這個問題。于是Google提出了Wide&Deep模型滨巴,但是如果深入探究Wide&Deep的構(gòu)成方式思灌,雖然將整個模型的結(jié)構(gòu)調(diào)整為了并行結(jié)構(gòu),在實際的使用中Wide Module中的部分需要較為精巧的特征工程恭取,換句話說人工處理對于模型的效果具有比較大的影響(這一點可以在Wide&Deep模型部分得到驗證)泰偿。

image

如上圖所示,該模型仍然存在問題:在output Units階段直接將低階和高階特征進行組合蜈垮,很容易讓模型最終偏向?qū)W習到低階或者高階的特征耗跛,而不能做到很好的結(jié)合裕照。

綜上所示,DeepFM模型橫空出世课兄。

2. 模型的結(jié)構(gòu)與原理

image

前面的Field和Embedding處理是和前面的方法是相同的牍氛,如上圖中的綠色部分;DeepFM將Wide部分替換為了FM layer如上圖中的藍色部分

這幅圖其實有很多的點需要注意烟阐,很多人都一眼略過了搬俊,這里我個人認為在DeepFM模型中有三點需要注意:

  • Deep模型部分
  • FM模型部分
  • Sparse Feature中黃色和灰色節(jié)點代表什么意思

2.1 FM

詳細內(nèi)容參考FM模型部分的內(nèi)容,下圖是FM的一個結(jié)構(gòu)圖蜒茄,從圖中大致可以看出FM Layer是由一階特征和二階特征Concatenate到一起在經(jīng)過一個Sigmoid得到logits(結(jié)合FM的公式一起看)唉擂,所以在實現(xiàn)的時候需要單獨考慮linear部分和FM交叉特征部分。
\hat{y}_{FM}(x) = w_0+\sum_{i=1}^N w_ix_i + \sum_{i=1}^N \sum_{j=i+1}^N v_i^T v_j x_ix_j

image

2.2 Deep

Deep架構(gòu)圖

image

Deep Module是為了學習高階的特征組合檀葛,在上圖中使用用全連接的方式將Dense Embedding輸入到Hidden Layer玩祟,這里面Dense Embeddings就是為了解決DNN中的參數(shù)爆炸問題,這也是推薦模型中常用的處理方法屿聋。

Embedding層的輸出是將所有id類特征對應的embedding向量concat到到一起輸入到DNN中空扎。其中v_i表示第i個field的embedding,m是field的數(shù)量润讥。
z_1=[v_1, v_2, ..., v_m]
上一層的輸出作為下一層的輸入转锈,我們得到:
z_L=\sigma(W_{L-1} z_{L-1}+b_{L-1})
其中\sigma表示激活函數(shù),z, W, b分別表示該層的輸入楚殿、權(quán)重和偏置撮慨。

最后進入DNN部分輸出使用sigmod激活函數(shù)進行激活:
y_{DNN}=\sigma(W^{L}a^L+b^L)

3. 代碼實現(xiàn)

DeepFM在模型的結(jié)構(gòu)圖中顯示,模型大致由兩部分組成脆粥,一部分是FM砌溺,還有一部分就是DNN, 而FM又由一階特征部分與二階特征交叉部分組成,所以可以將整個模型拆成三部分变隔,分別是一階特征處理linear部分规伐,二階特征交叉FM以及DNN的高階特征交叉。在下面的代碼中也能夠清晰的看到這個結(jié)構(gòu)匣缘。此外每一部分可能由是由不同的特征組成猖闪,所以在構(gòu)建模型的時候需要分別對這三部分輸入的特征進行選擇。

  • linear_logits: 這部分是有關(guān)于線性計算孵户,也就是FM的前半部分w1x1+w2x2...wnxn+b的計算萧朝。對于這一塊的計算岔留,我們用了一個get_linear_logits函數(shù)實現(xiàn)夏哭,后面再說,總之通過這個函數(shù)献联,我們就可以實現(xiàn)上面這個公式的計算過程竖配,得到linear的輸出何址, 這部分特征由數(shù)值特征和類別特征的onehot編碼組成的一維向量組成,實際應用中根據(jù)自己的業(yè)務放置不同的一階特征(這里的dense特征并不是必須的进胯,有可能會將數(shù)值特征進行分桶用爪,然后在當做類別特征來處理)

  • fm_logits: 這一塊主要是針對離散的特征,首先過embedding胁镐,然后使用FM特征交叉的方式偎血,兩兩特征進行交叉,得到新的特征向量盯漂,最后計算交叉特征的logits

  • dnn_logits: 這一塊主要是針對離散的特征颇玷,首先過embedding,然后將得到的embedding拼接成一個向量(具體的可以看代碼就缆,也可以看一下下面的模型結(jié)構(gòu)圖)帖渠,通過dnn學習類別特征之間的隱式特征交叉并輸出logits值

def DeepFM(linear_feature_columns, dnn_feature_columns):
    # 構(gòu)建輸入層,即所有特征對應的Input()層竭宰,這里使用字典的形式返回空郊,方便后續(xù)構(gòu)建模型
    dense_input_dict, sparse_input_dict = build_input_layers(linear_feature_columns + dnn_feature_columns)

    # 將linear部分的特征中sparse特征篩選出來,后面用來做1維的embedding
    linear_sparse_feature_columns = list(filter(lambda x: isinstance(x, SparseFeat), linear_feature_columns))

    # 構(gòu)建模型的輸入層切揭,模型的輸入層不能是字典的形式狞甚,應該將字典的形式轉(zhuǎn)換成列表的形式
    # 注意:這里實際的輸入與Input()層的對應,是通過模型輸入時候的字典數(shù)據(jù)的key與對應name的Input層
    input_layers = list(dense_input_dict.values()) + list(sparse_input_dict.values())

    # linear_logits由兩部分組成伴箩,分別是dense特征的logits和sparse特征的logits
    linear_logits = get_linear_logits(dense_input_dict, sparse_input_dict, linear_sparse_feature_columns)

    # 構(gòu)建維度為k的embedding層入愧,這里使用字典的形式返回,方便后面搭建模型
    # embedding層用戶構(gòu)建FM交叉部分和DNN的輸入部分
    embedding_layers = build_embedding_layers(dnn_feature_columns, sparse_input_dict, is_linear=False)

    # 將輸入到dnn中的所有sparse特征篩選出來
    dnn_sparse_feature_columns = list(filter(lambda x: isinstance(x, SparseFeat), dnn_feature_columns))

    fm_logits = get_fm_logits(sparse_input_dict, dnn_sparse_feature_columns, embedding_layers) # 只考慮二階項

    # 將所有的Embedding都拼起來嗤谚,一起輸入到dnn中
    dnn_logits = get_dnn_logits(sparse_input_dict, dnn_sparse_feature_columns, embedding_layers)
    
    # 將linear,FM,dnn的logits相加作為最終的logits
    output_logits = Add()([linear_logits, fm_logits, dnn_logits])

    # 這里的激活函數(shù)使用sigmoid
    output_layers = Activation("sigmoid")(output_logits)

    model = Model(input_layers, output_layers)
    return model

關(guān)于每一塊的細節(jié)棺蛛,這里就不解釋了,在我們給出的GitHub代碼中巩步,我們已經(jīng)加了非常詳細的注釋旁赊,大家看那個應該很容易看明白, 為了方便大家的閱讀椅野,我們這里還給大家畫了一個整體的模型架構(gòu)圖终畅,幫助大家更好的了解每一塊以及前向傳播(畫的圖不是很規(guī)范,先將就看一下竟闪,后面我們會統(tǒng)一在優(yōu)化一下這個手工圖)离福。

image

下面是一個通過keras畫的模型結(jié)構(gòu)圖,為了更好的顯示炼蛤,數(shù)值特征和類別特征都只是選擇了一小部分妖爷。

DeepFM

4. 思考

  1. 如果對于FM采用隨機梯度下降SGD訓練模型參數(shù),請寫出模型各個參數(shù)的梯度和FM參數(shù)訓練的復雜度
    答:模型各個參數(shù)的梯度理朋,及參數(shù)訓練的復雜度絮识,如下



  1. 對于下圖所示绿聘,根據(jù)你的理解Sparse Feature中的不同顏色節(jié)點分別表示什么意思
image

答: Sparse Feature中對Field采用One-Hot編碼,對于每個Field而言次舌,其含有N個灰色節(jié)點 與 1個黃色節(jié)點熄攘,其中灰色節(jié)點即為對應0,黃色節(jié)點對應1

5. 參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末彼念,一起剝皮案震驚了整個濱河市挪圾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逐沙,老刑警劉巖洛史,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異酱吝,居然都是意外死亡也殖,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門务热,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忆嗜,“玉大人,你說我怎么就攤上這事崎岂±粒” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵冲甘,是天一觀的道長绩卤。 經(jīng)常有香客問我,道長江醇,這世上最難降的妖魔是什么濒憋? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮陶夜,結(jié)果婚禮上凛驮,老公的妹妹穿的比我還像新娘。我一直安慰自己条辟,他們只是感情好黔夭,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嚷往。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天婚惫,我揣著相機與錄音,去河邊找鬼。 笑死辰妙,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的甫窟。 我是一名探鬼主播密浑,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼粗井!你這毒婦竟也來了尔破?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤浇衬,失蹤者是張志新(化名)和其女友劉穎懒构,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耘擂,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡胆剧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了醉冤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秩霍。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蚁阳,靈堂內(nèi)的尸體忽然破棺而出铃绒,到底是詐尸還是另有隱情,我是刑警寧澤螺捐,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布颠悬,位于F島的核電站,受9級特大地震影響定血,放射性物質(zhì)發(fā)生泄漏赔癌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一澜沟、第九天 我趴在偏房一處隱蔽的房頂上張望届榄。 院中可真熱鬧,春花似錦倔喂、人聲如沸铝条。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽班缰。三九已至,卻和暖如春悼枢,著一層夾襖步出監(jiān)牢的瞬間埠忘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留莹妒,地道東北人名船。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像旨怠,于是被迫代替她去往敵國和親渠驼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容