wide&deep

原文链接:https://arxiv.org/pdf/1606.07792.pdf

简单介绍

wide&deep顾名思义就是通过算法优化对用户进行个性化推荐(deep)和广泛推荐(wide)的算法。是谷歌公司发布于2016年的论文。比如再刷新闻的时候,软件时常会给你推荐很多种类,还会推荐你特别感兴趣的,这就和这种算法差不多。当然这个得区分热点推荐等。

main contributions:

  1. 帮助解决稀疏输入的通用推荐系统,用于训练带有嵌入的前馈神经网络和线性变换的线性模型。
  2. 这个推荐系统的实施和评估是在线实验
  3. 该算法在TensorFlow上有开源的数据接口,可以直接调用

Wide&Deep算法框架

在这里插入图片描述
在Wide&Deep算法框架上分为两个部分一个为线性模型(Wide Models)
公式为:
  Y = W T X + b   \ Y = W^{T}X+b\,  Y=WTX+b
在个模型中我们将项目的特征作为输入也就是当做公式中的X,X = [x1, x2, x3,…xn], 公式中的W和b都是这个模型中的参数,通过训练可以得到这个模型的相关参数设置。
在这里插入图片描述
在上式中,就是一个做与运算的公式,只有都为true才为1,否则为0.通过这个公式,Wide Models可以捕捉了二元特征之间的相互作用,增加了广义线性模型的非线性。
在这里插入图片描述
上图为推荐系统在应用过程中的框架图。
Deep Models部分是一个前馈神经网络的模型,公式为:
  a ( l + 1 ) = f ( W l a l + b l )   \ a^{(l+1)} = f( W^{l}a^{l}+b^{l})\,  a(l+1)=f(Wlal+bl)
这个公式中的f表示的是激活函数,其中使用的是ReLu()函数,l表示的是神经网络模型的层数。

Wide&Deep连解部分

公式描述:
在这里插入图片描述
通过训练不同的wide和deep权重来计算wide和deep推荐的重要性,其中使用的是sigmoid激活函数。
通过计算每个项目最终得分进行排名再对项目进行推荐。

代码部分

正因为Wide侧不能发现新模式,因此我们需要根据人工经验、业务背景,将我们认为有价值的、显而易见的特征及特征组合,喂入Wide侧

Deep侧就是DNN,通过embedding的方式将categorical/id特征映射成稠密向量,让DNN学习到这些特征之间的深层交叉,以增强扩展能力。

# Wide&Deep 模型的wide部分及Deep部分的特征选择,应该根据实际的业务场景去确定哪些特征应该放在Wide部分,哪些特征应该放在Deep部分
def WideNDeep(linear_feature_columns, dnn_feature_columns):
    # 构建输入层,即所有特征对应的Input()层,这里使用字典的形式返回,方便后续构建模型
    dense_input_dict, sparse_input_dict = build_input_layers(linear_feature_columns + dnn_feature_columns)

    # 将linear部分的特征中sparse特征筛选出来,后面用来做1维的embedding
    linear_sparse_feature_columns = list(filter(lambda x: isinstance(x, SparseFeat), linear_feature_columns))

    # 构建模型的输入层,模型的输入层不能是字典的形式,应该将字典的形式转换成列表的形式
    # 注意:这里实际的输入与Input()层的对应,是通过模型输入时候的字典数据的key与对应name的Input层
    input_layers = list(dense_input_dict.values()) + list(sparse_input_dict.values())

    # Wide&Deep模型论文中Wide部分使用的特征比较简单,并且得到的特征非常的稀疏,所以使用了FTRL优化Wide部分(这里没有实现FTRL)
    # 但是是根据他们业务进行选择的,我们这里将所有可能用到的特征都输入到Wide部分,具体的细节可以根据需求进行修改
    linear_logits = get_linear_logits(dense_input_dict, sparse_input_dict, linear_sparse_feature_columns)
    
    # 构建维度为k的embedding层,这里使用字典的形式返回,方便后面搭建模型
    embedding_layers = build_embedding_layers(dnn_feature_columns, sparse_input_dict, is_linear=False)

    dnn_sparse_feature_columns = list(filter(lambda x: isinstance(x, SparseFeat), dnn_feature_columns))

    # 在Wide&Deep模型中,deep部分的输入是将dense特征和embedding特征拼在一起输入到dnn中
    dnn_logits = get_dnn_logits(dense_input_dict, sparse_input_dict, dnn_sparse_feature_columns, embedding_layers)
    
    # 将linear,dnn的logits相加作为最终的logits
    output_logits = Add()([linear_logits, dnn_logits])

    # 这里的激活函数使用sigmoid
    output_layer = Activation("sigmoid")(output_logits)

    model = Model(input_layers, output_layer)
    return model

简单来说,这个模型的左边就是一个简单的线性回归模型,右边是一个DNN模型,通过这两个模型,训练出这两个模型各自所占的权重后,通过激活函数得到最终结果。当然这两个模型中DNN模型有对输入的数据进行embedding.

思考

思考题中有一个题目问道为什么deep不需要考虑数据的稀疏性的问题。我个人觉得这个可能就是embedding越来越常用,方法越来越多的原因。由于现在的数据量越来越大,如果依旧使用传统的协同过滤算法,或者简单的onehot编码等方法会存在运算量较大、数据稀疏性的问题。而使用embedding的方法,我们可以将某个项目的特征降维到,降低了运算的时间和空间复杂度的问题。同时还可以用过各种手段不断来优化项目的特征表示。这代表着我们可以通过这些手段得到更好的结果。
由于这篇文章来自于谷歌,且发表于2016年。这其实给了我们很多启发,网络模型并不是越复杂越好,层数越多越好。很多时候一些简单的算法也能取得很好的效果。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值