深度學習在推薦系統、CTR預估領域已經有了廣泛應用,如wide&deep、deepFM模型等,今天介紹一下由阿里算法團隊提出的深度興趣網絡DIN和DIEN兩種模型
paper
DIN:https://arxiv.org/abs/1706.06978
DIEN:https://arxiv.org/abs/1809.03672
code
DIN:https://github.com/zhougr1993/DeepInterestNetwork
DIEN:https://github.com/mouna99/dien
DIN
常見的深度學習網絡用於推薦或者CTR預估的模式如下:
Sparse Features -> Embedding Vector -> MLPs -> Sigmoid -> Output.
這種方法主要通過DNN網絡抽取特征的高階特征,減少人工特征組合,如wide&deep、deepFM的DNN部分均是采用這種模式,然而阿里的小組經過研究認為還有以下兩種特性在線上數據中十分重要的,而當前的模型無法去挖掘
Diversity:用戶在瀏覽電商網站的興趣多樣性。
Local activation: 由於用戶興趣的多樣性,只有部分歷史數據會影響到當次推薦的物品是否被點擊,而不是所有的歷史記錄。
為了充分挖掘這些特性,聯系到attention機制在nlp等領域的大獲成功,阿里團隊將attention機制引入推薦系統,在向量進入MLP之前先通過attention機制計算用戶行為權重,讓每個用戶預測關注的興趣點(行為向量)不同。
網絡基本結構如上圖,Base Model有一個很大的問題,它對用戶的歷史行為是同等對待的,沒有做任何處理,這顯然是不合理的。一個很顯然的例子,離現在越近的行為,越能反映你當前的興趣。因此,DIN模型對用戶歷史行為基於Attention機制進行一個加權
···
def din_fcn_attention(query, facts, attention_size, mask, stag='null', mode='SUM', softmax_stag=1, time_major=False, return_alphas=False, forCnn=False):
if isinstance(facts, tuple):
# In case of Bi-RNN, concatenate the forward and the backward RNN outputs.
facts = tf.concat(facts, 2)
if len(facts.get_shape().as_list()) == 2:
facts = tf.expand_dims(facts, 1)
if time_major:
# (T,B,D) => (B,T,D)
facts = tf.array_ops.transpose(facts, [1, 0, 2])
mask = tf.equal(mask,tf.ones_like(mask))
facts_size = facts.get_shape().as_list()[-1] # Hidden size for rnn layer
query = tf.layers.dense(query,facts_size,activation=None,name='f1'+stag)
query = prelu(query)
queries = tf.tile(query,[1,tf.shape(facts)[1]]) # Batch * Time * Hidden size
queries = tf.reshape(queries,tf.shape(facts))
din_all = tf.concat([queries,facts,queries-facts,queries*facts],axis=-1) # Batch * Time * (4 * Hidden size)
d_layer_1_all = tf.layers.dense(din_all, 80, activation=tf.nn.sigmoid, name='f1_att' + stag)
d_layer_2_all = tf.layers.dense(d_layer_1_all, 40, activation=tf.nn.sigmoid, name='f2_att' + stag)
d_layer_3_all = tf.layers.dense(d_layer_2_all, 1, activation=None, name='f3_att' + stag) # Batch * Time * 1
d_layer_3_all = tf.reshape(d_layer_3_all,[-1,1,tf.shape(facts)[1]]) # Batch * 1 * time
scores = d_layer_3_all
key_masks = tf.expand_dims(mask,1) # Batch * 1 * Time
paddings = tf.ones_like(scores) * (-2 ** 32 + 1)
if not forCnn:
scores = tf.where(key_masks, scores, paddings) # [B, 1, T] ,沒有的地方用paddings填充
# Activation
if softmax_stag:
scores = tf.nn.softmax(scores) # [B, 1, T]
# Weighted sum
if mode == 'SUM':
output = tf.matmul(scores,facts) # Batch * 1 * Hidden Size
else:
scores = tf.reshape(scores,[-1,tf.shape(facts)[1]]) # Batch * Time
output = facts * tf.expand_dims(scores,-1) # Batch * Time * Hidden Size
output = tf.reshape(output,tf.shape(facts))
if return_alphas:
return output,scores
else:
return output
···
以上是其中attention的核心代碼
DIEN
在用DIN解決了用戶的興趣不同的問題后,模型還存在以下問題
1)用戶的興趣是不斷進化的,而DIN抽取的用戶興趣之間是獨立無關聯的,沒有捕獲到興趣的動態進化性
2)通過用戶的顯式的行為來表達用戶隱含的興趣,這一准確性無法得到保證。
為了解決以上兩個問題,阿里算法又提出了DIEN模型
對比DIN的結構,主要區別在於增加了興趣抽取層和興趣進化層(RNN)
作者將用戶行為表示為序列,利用GRU來抽取興趣狀態
在此之后,為了進一步保證興趣抽取的准確,作者設計了一個二分類網絡,用下一刻的真實行為加GRU的狀態拼接作為正例,抽取的假行為拼接GRU狀態作為負例,輸入二分類網絡
同時設計損失函數
然后,抽取完興趣的狀態送入興趣進化網絡,為了讓用戶興趣也能追着時間變化,采用RNN設計,同時繼承與DIN的attention機制,結合后采用了GRU with attentional update gate (AUGRU)的方法,修改了GRU的結構
此處有多種GRU結合attention的方法。
最終DIEN的實驗結果表現很好