深度推荐系统入门
最近参加了datawhale组织的用深度学习来做推荐系统的学习,主要学习一些经典的模型,本文以此记录一下这个过程学习的一些心得。
学习地址:https://github.com/datawhalechina/team-learning-rs/tree/master/DeepRecommendationModel
1.DeepCrossing
DeepCrossing模型中加入了embedding和残差等结构,其中embedding在深度推荐系统中是比较常见的,其主要的思想是将稀疏的类别型特征转成稠密的Embedding向量,避免了one-hot编码带来的维度太大的问题,而加入残差的主要目的则是为了深层的神经网络也可以被很好的学习。
在将类别特征embedding之后再与和连续值特征进行合并(可以直接进行拼接),然后通过后续的全连接层对特征进行交叉组合,最后输出到一个分类器当中。
其中embedding应该是整个模型的核心思想处理,貌似也是深度推荐系统中一个重要的技术,就是解决one-hot等编码可能带来的稀疏的问题,embedding在nlp中也是非常关键的。
接下来主要通过代码看一下DeepCrossing的网络结构:
def DeepCrossing(dnn_feature_columns):
'''step1'''
# 构建输入层,即所有特征对应的Input()层,这里使用字典的形式返回,方便后续构建模型
dense_input_dict, sparse_input_dict = build_input_layers(dnn_feature_columns)
# 构建模型的输入层,模型的输入层不能是字典的形式,应该将字典的形式转换成列表的形式
# 注意:这里实际的输入与Input()层的对应,是通过模型输入时候的字典数据的key与对应name的Input层
input_layers = list(dense_input_dict.values()) + list(sparse_input_dict.values())
# 构建维度为k的embedding层,这里使用字典的形式返回,方便后面搭建模型
embedding_layer_dict = build_embedding_layers(dnn_feature_columns, sparse_input_dict, is_linear=False)
# 将所有的dense特征拼接到一起
dense_dnn_list = list(dense_input_dict.values())
dense_dnn_inputs = Concatenate(axis=1)(dense_dnn_list) # B x n (n表示数值特征的数量)
# 因为需要将其与dense特征拼接到一起所以需要Flatten,不进行Flatten的Embedding层输出的维度为:Bx1xdim
sparse_dnn_list = concat_embedding_list(dnn_feature_columns, sparse_input_dict, embedding_layer_dict, flatten=True)
sparse_dnn_inputs = Concatenate(axis=1)(sparse_dnn_list) # B x m*dim (m表示类别特征的数量,dim表示embedding的维度)
# 将dense特征和Sparse特征拼接到一起
dnn_inputs = Concatenate(axis=1)([dense_dnn_inputs, sparse_dnn_inputs]) # B x (n + m*dim)
'''step2'''
# 输入到dnn中,需要提前定义需要几个残差块
output_layer = get_dnn_logits(dnn_inputs, block_nums=3)
model = Model(input_layers, output_layer)
return model
可以看到就是对每个特征分别处理(类别特征使用embedding,连续值特征直接使用原始值),然后进行concat拼接作为后面全连接层的输入。其核心部分就是前面输入部分的处理,也就是上面的step1。
2.Wide&Deep
首先看一下Wide&Deep的整体网络结构,主要分为了两个部分,左边红色的。
wide部分是一个广义的线性模型,输入的特征主要有两部分组成,一部分是原始的部分特征,另一部分是原始特征的交叉特征;
Deep部分是一个DNN模型,输入的特征主要分为两大类,一类是数值特征(可直接输入DNN),一类是类别特征(需要经过Embedding之后才能输入到DNN中)。
W&D模型是将两部分输出的结果结合起来联合训练,将deep和wide部分的输出重新使用一个逻辑回归模型做最终的预测,输出概率值。联合训练的数学形式如下:需要注意的是,因为Wide侧的数据是高维稀疏的,所以作者使用了FTRL算法优化,而Deep侧使用的是 Adagrad。
P
(
Y
=
1
∣
x
)
=
δ
(
w
w
i
d
e
T
[
x
,
ϕ
(
x
)
]
+
w
d
e
e
p
T
a
l
f
+
b
)
P(Y=1|x)=\delta(w^T_{wide}[x,\phi (x)]+w^T_{deep}a^{lf}+b)
P(Y=1∣x)=δ(wwideT[x,ϕ(x)]+wdeepTalf+b)
但是用好这个模型的前提是根据自己的场景去选择那些特征放在Wide部分,哪些特征放在Deep部分。