模型简介
DIN(Deep Interest Network)是2018年阿里巴巴基于对业务的观察而提出的模型,应用于阿里巴巴的电商广告推荐业务。不同于以往的深度学习推荐模型前向传播流程(稀疏向量稠密化→拼接离散和连续部分→喂入DNN中进行特征交叉),DIN引入了注意力机制,使得该模型能够基于大量用户历史行为信息,计算历史信息与当前商品的关联,从而对用户是否点击某个商品进行预测,并且能学习到用户兴趣的变化。
模型结构与分析
模型的结构如图所示
1.Embedding层
和之前提到的其它推荐模型一样,采用Embedding层将稀疏的矩阵转换成稠密的(可以理解为该矩阵乘以自己的转置矩阵,将含有数值1的embedding向量取出来)
2.Pooling层与Concat层
DIN在这一层中采用了Attention机制,先将上一层输出的含用户历史行为的embedding向量与广告embedding向量及两者外积计算后得到的向量输入ActivationUnit,从而给这条用户历史行为加权,使得有用信息能够凸显出来,经过concat层进行连接,作为MLP(全连接神经网络)的输入
3.MLP
全连接层,用了学习特征之间的各种交互
4.Loss
基于深度学习的CTR模型广泛使用的损失函数是 负对数似然函数(the negative log-likelihood function)Loglos,使用标签作为目标项来监督整体的预测。
模型搭建与训练
import warnings
warnings.filterwarnings("ignore")
import itertools
import pandas as pd
import numpy as np
from tqdm import tqdm
from collections import namedtuple
import tensorflow as tf
from tensorflow.keras.layers import *
from tensorflow.keras.models import *
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler, LabelEncoder
from utils import SparseFeat, DenseFeat, VarLenSparseFeat
# 构建输入层
# 将输入的数据转换成字典的形式,定义输入层的时候让输入层的name和字典中特征的key一致,就可以使得输入的数据和对应的Input层对应
def build_input_layers(feature_columns):
input_layer_dict = {
}
for fc in feature_columns:
if isinstance(fc, SparseFeat):
input_layer_dict[fc.name] = Input(shape=(1,), name=fc.name)
elif isinstance(fc, DenseFeat):
input_layer_dict[fc.name] = Input(shape=(fc.dimension, ), name=fc.name)
elif isinstance(fc, VarLenSparseFeat):
input_layer_dict[fc.name] = Input(shape=(fc.maxlen, ), name=fc.name)
return input_layer_dict
# 构建embedding层
def build_embedding_layers(feature_columns, input_layer_dict):
embedding_layer_dict = {
}
for fc in feature_columns:
if isinstance(fc, SparseFeat):
embedding_layer_dict[fc.name] = Embedding(fc.vocabulary_size, fc.embedding_dim, name='emb_' + fc.name)
elif isinstance(fc, VarLenSparseFeat):
embedding_layer_dict[fc.name] = Embedding(fc.vocabulary_size + 1, fc.embedding_dim, name='emb_' + fc.name, mask_zero=True)
return embedding_layer_dict
def embedding_lookup(feature_columns, input_layer_dict, embedding_layer_dict):
embedding_list = []
for fc in feature_columns:
_input = input_layer_dict[fc]
_embed = embedding_layer_dict[fc]
embed = _embed(_input)
embedding_list.append(embed)
return embedding_list
class Dice(Layer):
def __init__(self):
super(Dice, self).__init__()
self.bn = BatchNormalization(center=False, scale=False)
def build(self, input_shape)</