【王喆-推荐系统】模型篇-(task5)wide&deep模型

简介: Wide&Deep是工业界中有巨大影响力的模型,如果直接翻译成中文是宽和深的模型,其模型结构如下所示:wide和deep让模型兼具逻辑回归和深度神经网络的特点。

一、Wide&Deep 模型的结构

Wide&Deep是工业界中有巨大影响力的模型,如果直接翻译成中文是宽和深的模型,其模型结构如下所示:wide和deep让模型兼具逻辑回归和深度神经网络的特点。

Wide就是将输入层直接连接到输出层(中间没有做任何处理)

——让模型具有较强的记忆力

Deep则其实是上个task的embedding+MLP

——让模型具有较强的泛化性

image.png

二、模型的记忆能力

记忆力:可理解为模型直接学习历史数据中物品或者特征的“共现频率”,并且把它们直接作为推荐依据的能力。

在sparrow项目的电影推荐中有一些规则,如看了A电影的用户经常喜欢看电影B,这是一种类似“因为A所以B”的规则,这类规则有两个特点:

数量特多,模型难记住;

没法推而广之,规则已经比较具体了:没办法或者说也没必要跟其他特征做进一步的组合。就像看了电影 A 的用户 80% 都喜欢看电影 B,这个特征已经非常强了,我们就没必要把它跟其他特征再组合在一起。

结论:wide部分增强模型记忆力,因为单层线性模型“擅长”记住大量且直接的规则。

三、模型的泛化能力

“泛化能力”指的是模型对于新鲜样本、以及从未出现过的特征组合的预测能力。

栗子1:现在如果已知35岁的女性用户和25岁的男性用户都喜欢看电影A,那如果让学习后的模型现在推理:35岁的男性用户是否喜欢看电影A,如果泛化性强一丢丢的模型可能就会回答【喜欢】,基于35女的35和25男的男做出的推理。

栗子2:矩阵分解算法就是为了解决协同过滤“泛化能力”不强而诞生的。因为协同过滤只会“死板”地使用用户的原始行为特征,而矩阵分解因为生成了用户和物品的隐向量,所以就可以计算任意两个用户和物品之间的相似度了。这就是泛化能力强的另一个例子。

结论:通过deep部分可以增强模型的泛化性,因为深度学习模型有很强的数据拟合能力,特征可以充分交叉,这里就沿用了上个task的embedding+MLP。

四、Wide&Deep 模型的应用场景

Wide&Deep 模型是由 Google 的应用商店团队 Google Play 提出的,在 Google Play 为用户推荐 APP 这样的应用场景下。

Wide&Deep 模型的推荐目标:尽量推荐那些用户可能喜欢,愿意安装的应用。

问题:具体到 Wide&Deep 模型中,Google Play 团队是如何为 Wide 部分和 Deep 部分挑选特征的。

image.png

图2 Google Play Wide&Deep模型的细节 (出自Wide & Deep Learning for Recommender Systems )

上图2补充google play团队这个模型的细节:从左边的wide的特征开始看起,只利用两个特征(“已安装应用”特征和“曝光应用”特征)的交叉,就是说wide想学的东西是希望记住“因为A所以B”的规则——如果安装了应用A,是否会安装B这样的规则。

再看deep部分的左边:是一个非常典型的 Embedding+MLP 结构,其中的输入特征很多,有用户年龄、属性特征、设备类型,还有已安装应用的 Embedding 等等。把这些特征一股脑地放进多层神经网络里面去学习之后,它们互相之间会发生多重的交叉组合,这最终会让模型具备很强的泛化能力。如刚才35女和25男的栗子学到具有泛化性的模型。

五、tensorflow实现

这部分的特征处理和上一个task是一样的,看模型结构:

deep模块:和上个task的特征是一样的,输入层加两层 128 维隐层的结构,它的输入是类别型 Embedding 向量和数值型特征。

wide模块:把输入特征连接到输出层,注意Wide 部分所用的特征 crossed_feature。

# wide and deep model architecture
# deep part for all input features
deep = tf.keras.layers.DenseFeatures(numerical_columns + categorical_columns)(inputs)
deep = tf.keras.layers.Dense(128, activation='relu')(deep)
deep = tf.keras.layers.Dense(128, activation='relu')(deep)
# wide part for cross feature
wide = tf.keras.layers.DenseFeatures(crossed_feature)(inputs)
# 拼接wide和deep层
both = tf.keras.layers.concatenate([deep, wide])
output_layer = tf.keras.layers.Dense(1, activation='sigmoid')(both)
model = tf.keras.Model(inputs, output_layer)

生成了一个由“用户已好评电影”和“当前评价电影”组成的一个交叉特征,就是代码中的 crossed_feature,设置这个特征的目的在于让模型记住好评电影之间的相关规则,更具体点来说就是,就是让模型记住“一个喜欢电影 A 的用户,也会喜欢电影 B”这样的规则:

这样的规则不是唯一的,需要你根据自己的业务特点来设计, 比如在电商网站中,这样的规则可以是,购买了键盘的用户也会购买鼠标。在新闻网站中,可以是打开过足球新闻的用户,也会点击 NBA 新闻等等。

movie_feature = tf.feature_column.categorical_column_with_identity(key='movieId', num_buckets=1001)
rated_movie_feature = tf.feature_column.categorical_column_with_identity(key='userRatedMovie1', num_buckets=1001)
crossed_feature = tf.feature_column.crossed_column([movie_feature, rated_movie_feature], 10000)

在 Deep 部分和 Wide 部分都构建完后,我们要使用 concatenate layer 把两部分连接起来,形成一个完整的特征向量,输入到最终的 sigmoid 神经元中,产生推荐分数。

【拓展】尝试设置不同的特征,以及不同的参数组合,真实地体验深度学习模型的调参过程。

六、Pytorch实现

image.png

首先分别搭建两个部分:

class Linear(nn.Module):
    """
    Linear part
    """
    def __init__(self, input_dim):
        super(Linear, self).__init__()
        self.linear = nn.Linear(in_features=input_dim, out_features=1)
    def forward(self, x):
        return self.linear(x)
class Dnn(nn.Module):
    """
    Dnn part
    """
    def __init__(self, hidden_units, dropout=0.):
        """
        hidden_units: 列表, 每个元素表示每一层的神经单元个数, 比如[256, 128, 64], 两层网络, 第一层神经单元128, 第二层64, 第一个维度是输入维度
        dropout: 失活率
        """
        super(Dnn, self).__init__()
        self.dnn_network = nn.ModuleList([nn.Linear(layer[0], layer[1]) for layer in list(zip(hidden_units[:-1], hidden_units[1:]))])
        self.dropout = nn.Dropout(p=dropout)
    def forward(self, x):
        for linear in self.dnn_network:
            x = linear(x)
            x = F.relu(x)
        x = self.dropout(x)
        return x

最后拼接起来,搭建wide&deep模型,最后的输出部分可以对Wide和Deep的输出加上一个权重得到最后的输出。

class WideDeep(nn.Module):
    def __init__(self, feature_columns, hidden_units, dnn_dropout=0.):
        super(WideDeep, self).__init__()
        self.dense_feature_cols, self.sparse_feature_cols = feature_columns
        # embedding 
        self.embed_layers = nn.ModuleDict({
            'embed_' + str(i): nn.Embedding(num_embeddings=feat['feat_num'], embedding_dim=feat['embed_dim'])
            for i, feat in enumerate(self.sparse_feature_cols)
        })
        hidden_units.insert(0, len(self.dense_feature_cols) + len(self.sparse_feature_cols)*self.sparse_feature_cols[0]['embed_dim'])
        self.dnn_network = Dnn(hidden_units)
        self.linear = Linear(len(self.dense_feature_cols))
        self.final_linear = nn.Linear(hidden_units[-1], 1)
    def forward(self, x):
        dense_input, sparse_inputs = x[:, :len(self.dense_feature_cols)], x[:, len(self.dense_feature_cols):]
        sparse_inputs = sparse_inputs.long()
        sparse_embeds = [self.embed_layers['embed_'+str(i)](sparse_inputs[:, i]) for i in range(sparse_inputs.shape[1])]
        sparse_embeds = torch.cat(sparse_embeds, axis=-1)
        dnn_input = torch.cat([sparse_embeds, dense_input], axis=-1)
        # Wide
        wide_out = self.linear(dense_input)
        # Deep
        deep_out = self.dnn_network(dnn_input)
        deep_out = self.final_linear(deep_out)
        # out
        outputs = F.sigmoid(0.5 * (wide_out + deep_out))
        return outputs  

七、作业

对于 Deep 部分来说,一股脑地把所有特征都扔进 MLP 中去训练,这样的方式有没有什么改进的空间?比如说,“用户喜欢的电影风格”和“电影本身的风格”这两个特征,我们能不能进一步挖掘出它们之间的相关性,而不是简单粗暴地扔给神经网络去处理呢?

【答】改进算法的wide部分,提升记忆能力,使用端到端模型,减少人工操作。例如DCNMix、DeepFM。以DeepFM这个模型都可以很好学习到高低特征与交叉。(实际业界常用,推荐)。这里也可以回顾之前的各种典型网络模型:

image.png

【高低阶特征知识】

低阶特征:是指线性-线性组合,只能算一个有效的线性组合,线性-非线性-线性,这样算两个有效的线性组合,一般常说的低阶特征只有小于等于2阶;

高阶特征:说高阶特征,可以理解为经过多次线性-非线性组合操作之后形成的特征,为高度抽象特征,一般人脑很难解析出原有的特征了。

相关文章
|
1月前
|
机器学习/深度学习 搜索推荐 大数据
深度解析:如何通过精妙的特征工程与创新模型结构大幅提升推荐系统中的召回率,带你一步步攻克大数据检索难题
【10月更文挑战第2天】在处理大规模数据集的推荐系统项目时,提高检索模型的召回率成为关键挑战。本文分享了通过改进特征工程(如加入用户活跃时段和物品相似度)和优化模型结构(引入注意力机制)来提升召回率的具体策略与实现代码。严格的A/B测试验证了新模型的有效性,为改善用户体验奠定了基础。这次实践加深了对特征工程与模型优化的理解,并为未来的技术探索提供了方向。
90 2
深度解析:如何通过精妙的特征工程与创新模型结构大幅提升推荐系统中的召回率,带你一步步攻克大数据检索难题
|
1月前
|
机器学习/深度学习 算法 搜索推荐
django调用矩阵分解推荐算法模型做推荐系统
django调用矩阵分解推荐算法模型做推荐系统
26 4
|
1月前
|
机器学习/深度学习 搜索推荐 TensorFlow
使用Python实现智能电子商务推荐系统:深度学习模型详解
使用Python实现智能电子商务推荐系统:深度学习模型详解
169 4
|
2月前
|
搜索推荐 算法
模型小,还高效!港大最新推荐系统EasyRec:零样本文本推荐能力超越OpenAI、Bert
【9月更文挑战第21天】香港大学研究者开发了一种名为EasyRec的新推荐系统,利用语言模型的强大文本理解和生成能力,解决了传统推荐算法在零样本学习场景中的局限。EasyRec通过文本-行为对齐框架,结合对比学习和协同语言模型调优,提升了推荐准确性。实验表明,EasyRec在多个真实世界数据集上的表现优于现有模型,但其性能依赖高质量文本数据且计算复杂度较高。论文详见:http://arxiv.org/abs/2408.08821
57 7
|
1月前
|
机器学习/深度学习 搜索推荐 算法
推荐系统的矩阵分解和FM模型
推荐系统的矩阵分解和FM模型
20 0
|
5月前
|
机器学习/深度学习 搜索推荐 算法
基于深度学习神经网络协同过滤模型(NCF)的图书推荐系统
登录注册 热门图书 图书分类 图书推荐 借阅图书 购物图书 个人中心 可视化大屏 后台管理
13128 2
基于深度学习神经网络协同过滤模型(NCF)的图书推荐系统
|
4月前
|
机器学习/深度学习 数据采集 搜索推荐
打开黑盒神经网络!港大推出全新会说话的推荐系统大模型XRec,从黑盒预测到可解释
【7月更文挑战第2天】港大研发XRec模型,将可解释性引入推荐系统。XRec结合大型语言模型的语义理解与协同过滤,生成推荐的文本解释,提升透明度。该模型无关设计允许与各类推荐系统配合,增强用户体验。然而,计算资源需求高、数据质量和用户理解能力可能影响其效果。[查看论文](https://arxiv.org/pdf/2406.02377)**
68 11
|
6月前
|
数据采集 机器学习/深度学习 搜索推荐
使用Python实现推荐系统模型
使用Python实现推荐系统模型
134 1
|
6月前
|
算法 搜索推荐 Python
探索Python中的推荐系统:混合推荐模型
探索Python中的推荐系统:混合推荐模型
385 1
|
6月前
|
存储 搜索推荐 算法
大模型开发:在构建推荐系统时,你会考虑哪些因素?
构建推荐系统涉及关键因素:用户行为数据(理解兴趣)、物品属性(相似性分析)、上下文信息(时间、地点)、冷启动问题(新用户/物品推荐)、可扩展性与性能(高效算法)、多样性(避免单一推荐)、可解释性(增强信任)和评估优化(准确性和用户满意度)。通过综合运用这些因素,打造精准且有效的推荐服务。
125 1

热门文章

最新文章