【CTR模型】TensorFlow2.0 的 DCN(Deep Cross Network) 实现与实战(附代码+数据)
CTR 系列文章:
本篇文章講解 DCN(Deep & Cross Network) 的 tensorflow2.0 實現(xiàn),并使用 Criteo 數(shù)據(jù)集的子集加以實踐。如果在看本文時有所困惑,可以看看 DCN(Deep & Cross Network) 的相關理論:CTR 模型之 Deep & Cross (DCN) 與 xDeepFM 解讀。
本文使用的數(shù)據(jù)下載地址于代碼獲取地址在文末獲取。
首先了解一下 Criteo數(shù)據(jù)集,它由有39個特征,1個label列,其中以I開頭的為數(shù)值型特征,以C開頭的為類別特征:
可以看到數(shù)據(jù)中有缺失值需要填充,并且類別變量需要進行類別編碼(onehot 編碼的任務交給模型),這部分預處理的代碼不詳細講了。
為了方便后面建立模型,先將特征劃分為 dense 特征與 sparse 特征兩個類別:
# 數(shù)值型 dense_feats = [f for f in cols if f[0] == "I"] # 類別型 sparse_feats = [f for f in cols if f[0] == "C"]Deep & Cross Network
DCN網(wǎng)絡結構如下:
構造模型輸入
對于 dense 特征,按下面的代碼構造輸入:
# 構造每個 dense 特征的輸入 dense_inputs = [] for f in dense_feats:_input = Input([1], name=f)dense_inputs.append(_input) # 將輸入拼接到一起 concat_dense_inputs = Concatenate(axis=1)(dense_inputs) # ?, 13對于 sparse 特征,按下面的代碼構造輸入:
# 這里單獨對每一個 sparse 特征構造輸入, # 目的是方便后面構造二階組合特征 sparse_inputs = [] for f in sparse_feats:_input = Input([1], name=f)sparse_inputs.append(_input)# embedding size k = 8 # 對sparse特征進行embedding sparse_kd_embed = [] for _input in sparse_inputs:f = _input.name.split(':')[0]voc_size = total_data[f].nunique()_embed = Flatten()(Embedding(voc_size, k, embeddings_regularizer=tf.keras.regularizers.l2(0.7))(_input))sparse_kd_embed.append(_embed)# 將sparse特征拼接在一起 concat_sparse_inputs = Concatenate(axis=1)(sparse_kd_embed)然后將所有的 dense 輸入和 sparse 輸入拼接到一起:
embed_inputs = Concatenate(axis=1)([concat_sparse_inputs, concat_dense_inputs])Cross Network
終于來到最核心的 Cross 部分,其中第 l+1l + 1l+1 層的計算過程為:
xl+1=x0xlTwl+bl+xlx_{l+1} =x_0x^T_lw_l + b_l + x_l xl+1?=x0?xlT?wl?+bl?+xl?
此公式的實現(xiàn)代碼如下:
這個代碼的執(zhí)行結果是第 l+1l+1l+1 層的輸出,共分為三個步驟:
關鍵在于第三步,計算 x0xlTwlx_0x^T_lw_lx0?xlT?wl? 時,如果先計算 x0xTx_0x^Tx0?xT則會得到一個矩陣,為了優(yōu)化內存的使用,可以先計算 xlTwlx^T_lw_lxlT?wl? 得到標量,然后再與 x0x_0x0? 相乘得到 feature crossing。
接下來可以利用循環(huán)構建多層 crossing layer:
def build_cross_layer(x0, num_layer=3):"""構建多層cross layer@param x0: 所有特征的embeddings@param num_layers: cross net的層數(shù)"""# 初始化xl為x0xl = x0# 構建多層cross netfor i in range(num_layer):xl = cross_layer(x0, xl)return xl# cross net cross_layer_output = build_cross_layer(embed_inputs, 3)DNN 部分
這部分好理解,直接上代碼吧:
fc_layer = Dropout(0.5)(Dense(128, activation='relu')(embed_inputs)) fc_layer = Dropout(0.3)(Dense(128, activation='relu')(fc_layer)) fc_layer_output = Dropout(0.1)(Dense(128, activation='relu')(fc_layer))輸出部分
代碼如下:
stack_layer = Concatenate()([cross_layer_output, fc_layer_output]) output_layer = Dense(1, activation='sigmoid', use_bias=True)(stack_layer)完善模型
model = Model(dense_inputs+sparse_inputs, output_layer) model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["binary_crossentropy", tf.keras.metrics.AUC(name='auc')])訓練模型
train_data = total_data.loc[:500000-1] valid_data = total_data.loc[500000:]train_dense_x = [train_data[f].values for f in dense_feats] train_sparse_x = [train_data[f].values for f in sparse_feats] train_label = [train_data['label'].values]val_dense_x = [valid_data[f].values for f in dense_feats] val_sparse_x = [valid_data[f].values for f in sparse_feats] val_label = [valid_data['label'].values]model.fit(train_dense_x+train_sparse_x, train_label, epochs=5, batch_size=128,validation_data=(val_dense_x+val_sparse_x, val_label),)最后,本文的代碼鏈接在:https://github.com/zxxwin/tf2_DCN 。
數(shù)據(jù)下載地址為:鏈接:https://pan.baidu.com/s/1Qy3yemu1LYVtj0Wn47myHQ 提取碼:pv7u
參考文章:
CTR預估模型:DeepFM/Deep&Cross/xDeepFM/AutoInt代碼實戰(zhàn)與講解
NELSONZHAO/zhihu/ctr_models/DCN
總結
以上是生活随笔為你收集整理的【CTR模型】TensorFlow2.0 的 DCN(Deep Cross Network) 实现与实战(附代码+数据)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CTR 模型之 Deep Cross
- 下一篇: 【图嵌入】DeepWalk原理与代码实战