推薦系統(tǒng)實(shí)戰(zhàn)之FM(Factorization Machine)算法——keras算法練習(xí)(4)

筆者在之前的文章中介紹過使用keras搭建一個(gè)基于矩陣分解的推薦系統(tǒng),而那篇文章所介紹的方法可能只是一個(gè)龐大推薦系統(tǒng)中的一小環(huán)節(jié)蜓洪。而對(duì)于工業(yè)級(jí)別的推薦系統(tǒng)官扣,面對(duì)極其龐大的產(chǎn)品種類數(shù)量,一步就輸出符合用戶心意的產(chǎn)品可能夠嗆炕吸,最好的方式應(yīng)該是從巨大的產(chǎn)品類別之中粗篩出一些靠譜的待推薦產(chǎn)品幔睬,然后再從粗篩的產(chǎn)品中精挑細(xì)選出要推薦給用戶的最終產(chǎn)品

工業(yè)級(jí)別的推薦系統(tǒng)簡介

工業(yè)級(jí)別的推薦系統(tǒng)的架構(gòu)圖如下圖所示览闰,大致分為兩個(gè)階段:

  • 召回階段:也就是粗篩階段,由于涉及到的產(chǎn)品數(shù)量巨大巷折,大的公司都是千萬級(jí)別压鉴,甚至上億級(jí)別的產(chǎn)品數(shù)量,此階段的模型應(yīng)該盡量簡單锻拘,特征維度也盡量少油吭,這樣方便快速篩選出一些待推薦的產(chǎn)品。
  • 排序階段:即對(duì)上一階段粗篩出來的待推薦產(chǎn)品進(jìn)行精挑細(xì)選署拟,此階段為了推薦出符合用戶心意的產(chǎn)品婉宰,需要模型盡量的準(zhǔn)確。而且由于粗篩階段將數(shù)據(jù)量減少到幾千推穷,甚至幾百級(jí)別心包,所以使用復(fù)雜模型,并且特征維度也可以盡量豐富馒铃,盡量多一些蟹腾,這樣訓(xùn)練出來的模型才能有較強(qiáng)的性能。


    推薦系統(tǒng)的架構(gòu)圖

而接下來我要介紹的FM(Factorization Machine)算法区宇,不僅在召回階段有用武之地娃殖,在排序階段也是很拿得出手的推薦模型。

FM(Factorization Machine)算法簡介

Factorization Machine的中文叫因子分解機(jī)萧锉,F(xiàn)M算法的最強(qiáng)特點(diǎn)就是考慮到了特征的二階組合——即特征兩兩組合形成一個(gè)新的特征珊随。在產(chǎn)品推薦,CTR預(yù)估等任務(wù)中柿隙,特征相互組合很可能會(huì)得到一個(gè)特別強(qiáng)的新特征叶洞。接下來我們從FM算法的公式來了解一下此算法的精髓:
y = w_0 + \sum_{i=1}^{n}w_ix_i + \sum_{i=1}^{n} \sum_{j=i+1}^{n} <v_i,v_j>x_ix_j
如果我們單看FM算法的前面一部分:y = w_0 + \sum_{i=1}^{n}w_ix_i ,這不就是一個(gè)Logistics回歸模型嗎,確實(shí)沒錯(cuò)禀崖,F(xiàn)M算法的前半部分就是Logistics回歸衩辟,算法的后半部分才體現(xiàn)出FM的特征組合的思想:

  • 其中v_i 和v_j可以理解成特征i和特征j的另外一種向量表示
  • v_i 和v_j 向量相乘得到的值則是特征i和特征j組合特征的權(quán)重波附,
  • Logistics回歸 + 特征之間的兩兩組合艺晴,最后給每個(gè)兩兩組合而來的新特征乘上一個(gè)權(quán)重值昼钻,就實(shí)現(xiàn)了FM算法的特征的二階組合的思想。

通過下圖我們可以將FM算法的公式轉(zhuǎn)化為:

FM算法的改寫


不要小看了公式的改寫這一步封寞,公式的改寫這一過程會(huì)帶來了算法時(shí)間復(fù)雜度的下降然评,加速算法的運(yùn)行。接下來我們就嘗試使用keras實(shí)現(xiàn)一下FM算法狈究。

FM算法實(shí)戰(zhàn)

首先導(dǎo)入畢要的python 包碗淌,導(dǎo)入 sklearn中乳腺癌的分類任務(wù)數(shù)據(jù)(筆者只是為了實(shí)現(xiàn)算法,所以只找了個(gè)簡單的現(xiàn)成數(shù)據(jù)跑一跑)抖锥。

import keras
from keras.layers import Layer, Dense, Dropout,Input
from keras import Model,activations
from keras.optimizers import Adam
import keras.backend as K
from sklearn.datasets import load_breast_cancer

FM層的定義亿眠,其中call函數(shù)中定義了FM的主要實(shí)現(xiàn)部分。

class FM(Layer):
    def __init__(self, output_dim=30, activation="relu",**kwargs):
        self.output_dim = output_dim
        self.activate = activations.get(activation)
        super(FM, self).__init__(**kwargs)

    def build(self, input_shape):
        self.wight = self.add_weight(name='wight', 
                                      shape=(input_shape[1], self.output_dim),
                                      initializer='glorot_uniform',
                                      trainable=True)
        self.bias = self.add_weight(name='bias', 
                                      shape=(self.output_dim,),
                                      initializer='zeros',
                                      trainable=True)
        self.kernel = self.add_weight(name='kernel', 
                                      shape=(input_shape[1], self.output_dim),
                                      initializer='glorot_uniform',
                                      trainable=True)
        super(FM, self).build(input_shape)

    def call(self, x):
        feature =  K.dot(x,self.wight) + self.bias
        a = K.pow(K.dot(x,self.kernel), 2)
        b = K.dot(x, K.pow(self.kernel, 2))
        cross = K.mean(a-b, 1, keepdims=True)*0.5
        cross = K.repeat_elements(K.reshape(cross, (-1, 1)), self.output_dim, axis=-1)
        return self.activate(feature + cross)

    def compute_output_shape(self, input_shape):
        return (input_shape[0], self.output_dim)

數(shù)據(jù)載入

載入sklearn中乳腺癌的分類任務(wù)數(shù)據(jù)磅废。

data = load_breast_cancer()["data"]
target = load_breast_cancer()["target"]

模型構(gòu)建

這里我采用了一層FM層纳像,一層15個(gè)神經(jīng)元的隱層構(gòu)建了一個(gè)兩層的網(wǎng)絡(luò)模型,Loss 采用的是平方誤差損失(mse)拯勉,當(dāng)然也可以采用交叉熵?fù)p失(cross entropy)竟趾。

K.clear_session()
inputs = Input(shape=(30,))
out = FM(20)(inputs)
out = Dense(15,activation="sigmoid")(out)
out = Dense(1,activation="sigmoid")(out)

model = Model(inputs=inputs, outputs=out)
model.compile(loss='mse',
                      optimizer=adam(0.0001),
                      metrics=['accuracy'])
model.summary()

模型訓(xùn)練

定義好batch_size 和訓(xùn)練輪數(shù),就可以將模型跑起來了谜喊。

model.fit(data, target,
            batch_size=1,
            epochs=100,
            validation_split=0.2)

下圖訓(xùn)練的截圖潭兽,由于數(shù)據(jù)集太小,太簡單這里也沒有對(duì)比FM和其他算法的性能差異斗遏,不過看網(wǎng)上的博客教程,F(xiàn)M在應(yīng)對(duì)特征豐富的推薦任務(wù)時(shí)有著很不錯(cuò)的效果鞋邑。畢竟考慮到了特征之間的組合關(guān)系诵次。


模型訓(xùn)練

結(jié)語

筆者之前也介紹過GBDT+ LRWide and deep等推薦算法枚碗,這次介紹的FM算法也是推薦算法中比較常用的算法逾一,他們都有一個(gè)共同的特點(diǎn)——就是這些算法都在尋找特征之間的組合關(guān)聯(lián),從而實(shí)現(xiàn)推薦算法性能的提升肮雨。萬事萬物都存在聯(lián)系遵堵,確實(shí)只有算法能夠洞察事物(特征)之間聯(lián)系,才有可能做出更精確的推薦決策怨规。

參考文獻(xiàn)

https://zhuanlan.zhihu.com/p/58160982
https://github.com/Hourout/CTR-keras

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末陌宿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子波丰,更是在濱河造成了極大的恐慌壳坪,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掰烟,死亡現(xiàn)場離奇詭異爽蝴,居然都是意外死亡沐批,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門蝎亚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來九孩,“玉大人,你說我怎么就攤上這事发框∧沓牛” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵缤底,是天一觀的道長顾患。 經(jīng)常有香客問我,道長个唧,這世上最難降的妖魔是什么江解? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮徙歼,結(jié)果婚禮上犁河,老公的妹妹穿的比我還像新娘。我一直安慰自己魄梯,他們只是感情好桨螺,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著酿秸,像睡著了一般灭翔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辣苏,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天肝箱,我揣著相機(jī)與錄音,去河邊找鬼稀蟋。 笑死煌张,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的退客。 我是一名探鬼主播骏融,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼萌狂!你這毒婦竟也來了档玻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤粥脚,失蹤者是張志新(化名)和其女友劉穎窃肠,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刷允,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡冤留,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年碧囊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纤怒。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡糯而,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出泊窘,到底是詐尸還是另有隱情熄驼,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布烘豹,位于F島的核電站瓜贾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏携悯。R本人自食惡果不足惜祭芦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望憔鬼。 院中可真熱鬧龟劲,春花似錦、人聲如沸轴或。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽照雁。三九已至蚕愤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間囊榜,已是汗流浹背审胸。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卸勺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓烫扼,卻偏偏與公主長得像曙求,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子映企,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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