小白讀deepFm CTR預(yù)估(shenweichen代碼)

作者的代碼可見:https://github.com/shenweichen/DeepCTR

本文分析的數(shù)據(jù)全部借用文章中的數(shù)據(jù)常摧。見



PART1 main函數(shù)

step1:讀取數(shù)據(jù),代碼中使用的是pandas的read_csv文件的讀取方法牡整。

step2:將離線型特征、連續(xù)型特征的特征名嘲叔、標(biāo)簽名分別放到不同的list中。

????????為了后續(xù)畫圖方便贵白,沒有將所有特征用到抚芦,只用了前兩個(gè)連續(xù)特征和前兩個(gè)離散特征



這樣實(shí)際上我們得到了三個(gè)list倍谜。如果我們用該代碼迈螟,使用的特征名和他給的特征名不一致的,我們可以直接顯示給定特征名尔崔。例如

    sparse_features = ['C1', 'C2']
    dense_features  = ['I1', 'I2']
    target          = ['label']

step3:基礎(chǔ)特征工程

????????這也是在一般的機(jī)器學(xué)習(xí)中我們也會做的一個(gè)操作就是特征工程答毫,只不過深度學(xué)習(xí)的特征工程較機(jī)器學(xué)習(xí)簡單,一般我們不去人工挖掘一些交叉的特征您旁,而是交給embedding層去做處理烙常。
????????一般有哪些特征工程的方法,可以參考:https://www.zhihu.com/question/29316149
該論文中只做了兩種處理鹤盒,一是對離線型特征做LabelEncoder蚕脏,該方法是將特征中的文本信息轉(zhuǎn)成數(shù)字。例如:

from pandas import DataFrame
from sklearn.preprocessing import LabelEncoder
import pandas as pd
data = {'水果':['蘋果','梨','草莓'],
       '數(shù)量':[3,2,5],
       '價(jià)格':[10,9,8]}
#根據(jù)dict創(chuàng)建dataframe
df = DataFrame(data)
lbe = LabelEncoder()
df['水果'] = lbe.fit_transform(data['水果'])

????????可以看到蘋果被重新編碼為1侦锯,梨重新編碼為0驼鞭,草莓重新編碼為2。若使用的時(shí)候尺碰,自己的數(shù)據(jù)集中的數(shù)據(jù)本身就是數(shù)字型的挣棕,其實(shí)這步就可以省略。
????????對于連續(xù)型特征亲桥,由于涉及到線性運(yùn)算洛心,若某一維度的值特別大后,就會導(dǎo)致該特征對模型整體影響偏高题篷。所以為了消除這種影響词身,一般會進(jìn)行歸一化處理。本文采用的min-max歸一化番枚。

mms = MinMaxScaler(feature_range=(0, 1))
data[dense_features] = mms.fit_transform(data[dense_features])

將每列的特征壓縮在0-1范圍之類法严。當(dāng)前還有0均值1方差的歸一化處理方式。

step4:數(shù)據(jù)處理(格式轉(zhuǎn)換)

sparseFeat = [SparseFeat(feat, vocabulary_size=data[feat].nunique(), embedding_dim=4) for feat in sparse_features]
denseFeat =  [DenseFeat(feat, 1,) for feat in dense_features]
#其中vocabulary_size表示的是詞典的詞大小葫笼,即離散變量它的取值有多少個(gè)深啤。
#例如對于性別這個(gè)離散特征,它的取值有'female', 'male'和未識別路星。則有三種可取值溯街。

????????其中nunique()可以求dataframe的某列中不同元素的個(gè)數(shù)。用該方法就可以求出離散特征可取值的個(gè)數(shù)奥额。還是對之前的蘋果和梨的例子苫幢。可以看到

print(df['水果'].nunique()) #結(jié)果為3

其實(shí)sparseFeat 和denseFeat 只是將之前的特征名封裝成了一個(gè)類垫挨。對于離散型特征C1韩肝,要指定該特征可取值的個(gè)數(shù),即vocabulary_size九榔,還有embedding_dim即經(jīng)過embedding后希望得到的維度哀峻。對于embedding_dim其實(shí)有個(gè)疑問:

if embedding_dim == "auto":
       embedding_dim =  6 * int(pow(vocabulary_size, 0.25))

????????對于embedding后的維度涡相,用戶可以通過顯式指定embedding_dim,也可以設(shè)置為auto剩蟀,這樣會根據(jù)上述的公式得到維度催蝗。也就是詞典的大小開兩次根號后的六倍。但是為什么這么處理呢育特?


PART2 DeepFM方法

????????為了直觀地看出代碼中的模型整個(gè)框架丙号,先用C1、C2缰冤、I1犬缨、I2兩個(gè)連續(xù)型特征和兩個(gè)離散型特征。使用如下代碼

plot_model(model, to_file='model_deepfm.png', show_shapes=True,show_layer_names=True)

畫出模型框架圖棉浸,結(jié)果如下:


????????可以看出怀薛,整個(gè)框架分為三個(gè)部分,F(xiàn)M迷郑,DNN枝恋,Linear三個(gè)部分。為了更好了理解每一個(gè)部分嗡害,我們拆分來理解焚碌。我們先看一下DeepFM的輸入
????????首先理解FM模型,該模型可以理解為是在LR模型基礎(chǔ)上的一種改進(jìn)吧霸妹。因?yàn)榫€性模型僅考慮特征的線性組合呐能,但是有時(shí)候特征與特征之間也存在一定的關(guān)系,由此應(yīng)運(yùn)出該模型抑堡。首先推導(dǎo)出模型表達(dá)式
FM模塊


這樣就推導(dǎo)出了FM的計(jì)算公式,簡記為和平方-平方和朗徊。接著我們看代碼中對應(yīng)FM模型的部分

fm_logit = add_func([FM()(concat_func(v, axis=1))
                         for k, v in group_embedding_dict.items() if k in fm_group])

首先得理解group_embedding_dict到底是什么首妖?其對應(yīng)的代碼如下:

def input_from_feature_columns(features, feature_columns, l2_reg, init_std, seed, prefix='', seq_mask_zero=True,
                               support_dense=True, support_group=False):
    sparse_feature_columns = list(
        filter(lambda x: isinstance(x, SparseFeat), feature_columns)) if feature_columns else []
    varlen_sparse_feature_columns = list(
        filter(lambda x: isinstance(x, VarLenSparseFeat), feature_columns)) if feature_columns else []

    embedding_matrix_dict = create_embedding_matrix(feature_columns, l2_reg, init_std, seed, prefix=prefix,
                                                    seq_mask_zero=seq_mask_zero)
    group_sparse_embedding_dict = embedding_lookup(embedding_matrix_dict, features, sparse_feature_columns)
    dense_value_list = get_dense_input(features, feature_columns)
    if not support_dense and len(dense_value_list) > 0:
        raise ValueError("DenseFeat is not supported in dnn_feature_columns")

    sequence_embed_dict = varlen_embedding_lookup(embedding_matrix_dict, features, varlen_sparse_feature_columns)
    group_varlen_sparse_embedding_dict = get_varlen_pooling_list(sequence_embed_dict, features,
                                                                 varlen_sparse_feature_columns)
    group_embedding_dict = mergeDict(group_sparse_embedding_dict, group_varlen_sparse_embedding_dict)
    if not support_group:
        group_embedding_dict = list(chain.from_iterable(group_embedding_dict.values()))
    return group_embedding_dict, dense_value_list
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市爷恳,隨后出現(xiàn)的幾起案子有缆,更是在濱河造成了極大的恐慌,老刑警劉巖温亲,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棚壁,死亡現(xiàn)場離奇詭異,居然都是意外死亡栈虚,警方通過查閱死者的電腦和手機(jī)袖外,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來魂务,“玉大人曼验,你說我怎么就攤上這事泌射。” “怎么了鬓照?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵熔酷,是天一觀的道長。 經(jīng)常有香客問我豺裆,道長拒秘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任臭猜,我火速辦了婚禮躺酒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘获讳。我一直安慰自己阴颖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布丐膝。 她就那樣靜靜地躺著量愧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪帅矗。 梳的紋絲不亂的頭發(fā)上偎肃,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天,我揣著相機(jī)與錄音浑此,去河邊找鬼累颂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛凛俱,可吹牛的內(nèi)容都是我干的紊馏。 我是一名探鬼主播,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼蒲犬,長吁一口氣:“原來是場噩夢啊……” “哼朱监!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起原叮,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤赫编,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后奋隶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體擂送,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年唯欣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嘹吨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,768評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡黍聂,死狀恐怖躺苦,靈堂內(nèi)的尸體忽然破棺而出身腻,到底是詐尸還是另有隱情,我是刑警寧澤匹厘,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布嘀趟,位于F島的核電站,受9級特大地震影響愈诚,放射性物質(zhì)發(fā)生泄漏她按。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一炕柔、第九天 我趴在偏房一處隱蔽的房頂上張望酌泰。 院中可真熱鬧,春花似錦匕累、人聲如沸陵刹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽衰琐。三九已至,卻和暖如春炼蹦,著一層夾襖步出監(jiān)牢的瞬間羡宙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工掐隐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狗热,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓虑省,卻偏偏與公主長得像匿刮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子探颈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評論 2 350

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