深度学习推荐模型-DIN
本文参考链接,仅供个人学习:
https://github.com/datawhalechina/team-learning-rs/tree/master/DeepRecommendationModel
相关学习书籍推荐:《深度学习推荐系统》王喆
DIN介绍
Deep Interest Network(DIN)是盖坤大神领导的阿里妈妈的精准定向检索及基础算法团队,在2017年6月提出的。
它针对电子商务领域(e-commerce industry)的CTR预估,重点在于充分利用/挖掘用户历史行为数据中的信息。
DIN模型-深度兴趣网络(Deep Interest Network)
1.基础模型:
Base Model主要由两部分组成:
- 把稀疏的输入(id特征)转换成embedding vector
- 增加MLPs得到最终的输出
2.Deep Interest Network网络结构:
- Activation Unit实现Attention机制,对Local Activation建模
- Pooling(weighted sum)对Diversity建模
基本模型是获得一个固定长度的用户的表示向量,但不管候选广告是什么,此表示向量对于给定用户均保持不变。这样,维度受限的用户表示向量将成为表达用户多样化兴趣的瓶颈。
与展示广告相关的行为极大地影响了点击操作。DIN通过给定一个候选广告,然后去注意与该广告相关的局部兴趣的表示来模拟此过程。DIN不会通过使用同一向量来表达所有用户的不同兴趣,而是通过考虑历史行为的相关性来自适应地计算用户兴趣的表示向量(对于给定的广告)。
模型优化
在模型学习优化上,DIN提出了Dice激活函数、自适应正则 ,显著的提升了模型性能与收敛速度。
模型demo:
import numpy as np
from deepctr.models import DIN
from deepctr.feature_column import SparseFeat, VarLenSparseFeat, DenseFeat,get_feature_names
def get_xy_fd():
# 对基础特征进行 embedding
feature_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)]
# 指定历史行为序列对应的特征
behavior_feature_list = ["item_id", "cate_id"]
# 构造 ['item_id', 'cate_id'] 这两个属性历史序列数据的数据结构: hist_item_id, hist_cate_id
# 由于历史行为是不定长数据序列,需要用 VarLenSparseFeat 封装起来,并指定序列的最大长度为 4
# 注意,对于长度不足4的部分会用0来填充,因此 vocabulary_size 应该在原来的基础上 + 1
feature_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)]
# 基础特征数据
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])
# 构造历史行为序列数据
# 构造长度为 4 的 item_id 序列,不足的部分用0填充
hist_iid = np.array([[1, 2, 3, 0], [3, 2, 1, 0], [1, 2, 0, 0]])
# 构造长度为 4 的 cate_id 序列,不足的部分用0填充
hist_cate_id = np.array([[1, 2, 2, 0], [2, 2, 1, 0], [1, 2, 0, 0]])
# 构造实际的输入数据
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_list
if __name__ == "__main__":
x, y, feature_columns, behavior_feature_list = get_xy_fd()
# 构造 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 模型至少需要传入两个参数,一个是 dnn_feature_columns , 用于对所有输入数据进行 embedding;另一个是 history_feature_list,用于指定历史行为序列特征的名字,例如 [“item_id”, “cate_id”]。
要特别注意的地方是:特征 f 的历史行为序列名为 hist_f 。例如要使用 ‘item_id’, ‘cate_id’ 这两个特征的历史行为序列数据,那么在构造输入数据时,其命名应该加上前缀“hist_” ,即 ‘hist_item_id’, ‘hist_cate_id’。