CTR深度学习模型之 DIN(Deep Interest Network) 的理解与例子
在電商領(lǐng)域,每個用戶都有豐富的歷史行為數(shù)據(jù),這些數(shù)據(jù)具有如下特點(diǎn):
多樣性(Diversity):用戶可能對多種商品感興趣,例如手機(jī)、衣服。
局部激活(Local Activation):用戶是否點(diǎn)擊新商品,僅僅取決于歷史行為中與新商品相關(guān)度高的部分?jǐn)?shù)據(jù)。
如何從中捕獲特征對CTR預(yù)估模型非常重要。論文 《Deep Interest Network for Click-Through Rate Prediction 提出了深度興趣網(wǎng)絡(luò) Deep Interest Network,以下簡稱 DIN 模型,設(shè)計了類似 attention 的網(wǎng)絡(luò)結(jié)構(gòu)來激活歷史行為數(shù)據(jù)中與候選廣告相關(guān)度高的行為,即:增大與目標(biāo)廣告相關(guān)性高的歷史行為權(quán)重。
模型解讀
基準(zhǔn)模型
論文并沒有直接講解DIN模型,而是先介紹了基準(zhǔn)模型的結(jié)構(gòu):
此模型主要功能是將輸入的用戶特征、行為特征、候選廣告以及上下文特征轉(zhuǎn)換成 embedding,然后將這些 embedding 拼接在一起用幾個全連接層完成點(diǎn)擊率的預(yù)測。這里面有幾個需要注意的細(xì)節(jié):
1,用戶行為序列的長度一般是不同的,所以為了能夠?qū)⒉煌蛄虚L度的embedding 向量轉(zhuǎn)換成相同的大小,一種思路是將所有的 embedding 向量進(jìn)行 sum pooling,即對所有 embedding 向量求和,得到一個固定大小的向量,作為全連接層的輸入。
2,直接對行為的 embedding 向量求和,會損失很多信息,即:無法捕捉到候選廣告與歷史行為信息中的局部相關(guān)性。
DIN模型
于是,在論文中又提出了改進(jìn)后的模型: DIN,網(wǎng)絡(luò)結(jié)構(gòu)如下圖:
與基準(zhǔn)模型相比,最大的區(qū)別在于:引入了與 attention 機(jī)制功能相似的 Activation Unit 用于根據(jù)候選廣告計算歷史行為的權(quán)重。
如果用 {e1,e2,...,eHe_1, e_2, ... , e_He1?,e2?,...,eH?} 表示用戶 U 對 H 個商品行為 embedding 向量,vAv_AvA? 表示候選廣告的向量,那么用戶 U 對廣告 A 的興趣向量 vU(A)v_U(A)vU?(A) 可以用下面的公式計算:
vU(A)=f(vA,e1,e2,...,eH)=∑j=1Ha(ej,vA)ej=∑j=1Hwjejv_U(A) = f(v_A,e_1,e_2,...,e_H)=\sum_{j=1}^Ha(e_j,v_A)e_j=\sum_{j=1}^Hw_je_j vU?(A)=f(vA?,e1?,e2?,...,eH?)=j=1∑H?a(ej?,vA?)ej?=j=1∑H?wj?ej?
其中, a(?)a(\cdot)a(?) 本質(zhì)上是一個前饋神經(jīng)網(wǎng)絡(luò),用于計算 eje_jej? 的權(quán)重 wjw_jwj?。在計算權(quán)重時,需要將 eje_jej? 與 vAv_AvA? 作為下圖 Activation Unit 的輸入,最終得到的輸出就是權(quán)值。
如果歷史行為中某個商品 eje_jej? 與候選廣告商品 vAv_AvA? 相似度高,那么在使用 SUM Pooling 計算 vU(A)v_U(A)vU?(A) 時,相似度高的商品的權(quán)重也應(yīng)該高一些。從公式可以看出,引入了 Activation Unit 之后,不同的候選廣告,用戶的興趣向量也會有所不同。
需要注意的是,與 attention 不同,權(quán)值 w 不需要保證的和為1。
訓(xùn)練技巧
Dice 激活函數(shù)
PReLU 可以看作是 ReLU 的改版,計算方法為:
f(s)={sifs>0αsifs≤0=p(s)?s+(1?p(s))?αs\begin{aligned} f(s) & =\left\{ \begin{array}{l} s \;\;\qquad if\quad s>0 \\ \alpha s \qquad if\quad s \le 0 \end{array} \right. \\ & = p(s) \cdot s + (1-p(s))\cdot\alpha s \end{aligned} f(s)?={sifs>0αsifs≤0?=p(s)?s+(1?p(s))?αs?
無論是 ReLU 或者是 PReLU 突變點(diǎn)都是0。而論文認(rèn)為突變點(diǎn)的選擇應(yīng)該依賴于數(shù)據(jù),于是基于 PReLU 提出了 Dice 激活函數(shù):
f(s)=p(s)?s+(1?p(s))?αsp(s)=11+e?s?E[s]Var[s]+?f(s)=p(s) \cdot s+(1-p(s)) \cdot \alpha s\\ p(s)=\frac{1}{1+e^{-\frac{s-E[s]}{\sqrt{V a r[s]+\epsilon}}}} f(s)=p(s)?s+(1?p(s))?αsp(s)=1+e?Var[s]+??s?E[s]?1?
其中E[s],Var[s]E[s], Var[s]E[s],Var[s] 分別是每個 mini-batch 數(shù)據(jù)的均值與方差,?\epsilon? 取 10?810^{-8}10?8 。于是,p(s)p(s)p(s) 函數(shù)的圖像如下:
這樣的激活函數(shù)能夠適應(yīng)不同分布的輸入數(shù)據(jù),整體表現(xiàn)要優(yōu)于 PReLU。
自適應(yīng)正則化
在使用例如 l2l_2l2? 這樣的傳統(tǒng)正則化方法時,每一個 mini-batch 正則化項的計算都需要所有的參數(shù)的參與,在參數(shù)數(shù)量龐大的情況下,這個計算消耗太大了。于是論文提出了一種正則化方法,只需要對在每個 mini-batch 中出現(xiàn)的參數(shù)進(jìn)行計算。
回顧 DIN 模型,發(fā)現(xiàn)絕大多數(shù)參數(shù)出現(xiàn)在 embedding 層,令:
W∈RD×KW \in R ^{D \times K} W∈RD×K
表示整個 embedding 層的參數(shù),其中 D 是嵌入維度,K 是特征個數(shù)。則正則化項的計算公式如下:
L2(W)≈∑j=1K∑m=1Bαmjnj∣∣wj∣∣22L_2(W) \approx \sum_{j=1}^K \sum_{m=1}^B \frac{\alpha_{mj}}{n_j}||w_j||_2^2 L2?(W)≈j=1∑K?m=1∑B?nj?αmj??∣∣wj?∣∣22?
其中,αmj\alpha_{mj}αmj? 表示特征 j 是否出現(xiàn)在 mini-batch 樣本 B 中,njn_jnj? 表示樣本 j 在 B 中的出現(xiàn)次數(shù), wjw_jwj? 則是第 j 個嵌入向量。整個公式的核心思想是出現(xiàn)的頻率越大,正則化的強(qiáng)度越小。
GAUC 評估指標(biāo)
GAUC 是 AUC 的加權(quán)平均:
GAUC=∑i=1nwi×AUCi∑i=1nwi=∑i=1nimpi×AUCi∑i=1nimpi\mathrm{GAUC}=\frac{\sum_{i=1}^{n} w_{i} \times \mathrm{AUC}_{i}}{\sum_{i=1}^{n} w_{i}}=\frac{\sum_{i=1}^{n} \mathrm{imp}_{i} \times \mathrm{AUC}_{i}}{\sum_{i=1}^{n} \mathrm{imp}_{i}} GAUC=∑i=1n?wi?∑i=1n?wi?×AUCi??=∑i=1n?impi?∑i=1n?impi?×AUCi??
其中:n 是用戶的數(shù)量,AUCiAUC_iAUCi? 表示用戶 iii 所有樣本的 AUC,impiimp_iimpi? 是用戶 iii 所有樣本的個數(shù)。AUC 是考慮所有樣本的排名,而實(shí)際上,我們只要關(guān)注給每個用戶推薦的廣告的排序,因此GAUC更具有指導(dǎo)意義。
模型例子
例子是在 tensorflow2.0 的環(huán)境中使用了 deepctr 實(shí)現(xiàn)的 DIN 模型,deepctr 安裝方式如下:
pip install deepctr[gpu]在其 github 倉庫中提供了一個 demo,其代碼以及關(guān)鍵部分的注釋如下:
import numpy as npfrom deepctr.models import DIN from deepctr.feature_column import SparseFeat, VarLenSparseFeat, DenseFeat,get_feature_namesdef get_xy_fd():# 對基礎(chǔ)特征進(jìn)行 embeddingfeature_columns = [SparseFeat('user',vocabulary_size=3,embedding_dim=10),SparseFeat('gender', vocabulary_size=2,embedding_dim=4), SparseFeat('item_id', vocabulary_size=3,embedding_dim=8), SparseFeat('cate_id', vocabulary_size=2,embedding_dim=4),DenseFeat('pay_score', 1)]# 指定歷史行為序列對應(yīng)的特征behavior_feature_list = ["item_id", "cate_id"]# 構(gòu)造 ['item_id', 'cate_id'] 這兩個屬性歷史序列數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu): hist_item_id, hist_cate_id# 由于歷史行為是不定長數(shù)據(jù)序列,需要用 VarLenSparseFeat 封裝起來,并指定序列的最大長度為 4 # 注意,對于長度不足4的部分會用0來填充,因此 vocabulary_size 應(yīng)該在原來的基礎(chǔ)上 + 1feature_columns += [VarLenSparseFeat(SparseFeat('hist_item_id', vocabulary_size=3 + 1,embedding_dim=8,embedding_name='item_id'), maxlen=4),VarLenSparseFeat(SparseFeat('hist_cate_id', 2 + 1,embedding_dim=2 + 1, embedding_name='cate_id'), maxlen=4)]# 基礎(chǔ)特征數(shù)據(jù)uid = np.array([0, 1, 2])ugender = np.array([0, 1, 0])iid = np.array([1, 2, 3])cate_id = np.array([1, 2, 2]) pay_score = np.array([0.1, 0.2, 0.3])# 構(gòu)造歷史行為序列數(shù)據(jù)# 構(gòu)造長度為 4 的 item_id 序列,不足的部分用0填充hist_iid = np.array([[1, 2, 3, 0], [3, 2, 1, 0], [1, 2, 0, 0]])# 構(gòu)造長度為 4 的 cate_id 序列,不足的部分用0填充hist_cate_id = np.array([[1, 2, 2, 0], [2, 2, 1, 0], [1, 2, 0, 0]])# 構(gòu)造實(shí)際的輸入數(shù)據(jù)feature_dict = {'user': uid, 'gender': ugender, 'item_id': iid, 'cate_id': cate_id,'hist_item_id': hist_iid, 'hist_cate_id': hist_cate_id, 'pay_score': pay_score}x = {name:feature_dict[name] for name in get_feature_names(feature_columns)}y = np.array([1, 0, 1])return x, y, feature_columns, behavior_feature_listif __name__ == "__main__":x, y, feature_columns, behavior_feature_list = get_xy_fd()# 構(gòu)造 DIN 模型model = DIN(dnn_feature_columns=feature_columns, history_feature_list=behavior_feature_list)model.compile('adam', 'binary_crossentropy',metrics=['binary_crossentropy'])history = model.fit(x, y, verbose=1, epochs=10)DIN 模型至少需要傳入兩個參數(shù),一個是 dnn_feature_columns , 用于對所有輸入數(shù)據(jù)進(jìn)行 embedding;另一個是 history_feature_list,用于指定歷史行為序列特征的名字,例如 [“item_id”, “cate_id”]。
要特別注意的地方是:特征 f 的歷史行為序列名為 hist_f 。例如要使用 ‘item_id’, ‘cate_id’ 這兩個特征的歷史行為序列數(shù)據(jù),那么在構(gòu)造輸入數(shù)據(jù)時,其命名應(yīng)該加上前綴“hist_” ,即 ‘hist_item_id’, ‘hist_cate_id’。
參考鏈接:
CTR預(yù)估–阿里Deep Interest Network
Deep Interest and Evolution Network for CTR
AI算法工程師手冊/DIN
總結(jié)
以上是生活随笔為你收集整理的CTR深度学习模型之 DIN(Deep Interest Network) 的理解与例子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 美国三大股指
- 下一篇: 梳理百年深度学习发展史-七月在线机器学习