推荐系统之Wide&Deep

Wide&Deep模型结合了Wide层的记忆能力和Deep层的泛化能力。Wide层通过L1 FTRL优化器学习稀疏特征,用于捕捉明显的关联规则。Deep层通过DNN学习特征的低维表示,处理稀疏性问题。两者通过联合训练优化,以提高推荐系统的性能。模型的实现使用了TensorFlow的Estimator API。
摘要由CSDN通过智能技术生成

前言

Wide&Deep模型主要两个重要的概念就是Memorization和Generalization,wide层采用LR模型加上大量原始特征和叉乘特征作为输入,‘记忆’历史数据中曾共同出现过的特征对。而deep层则主要为sparse特征学习低维的dense embeddings来捕获特征相关性,学习到的embedding本身会带一定的语义特征。

加入wide层学习浅层特征的动机:

  1. 因子分解机或者深度神经网络在低维稠密向量下学习,但是无法get到稀疏高维的情况,会对小众查询给出非零的预测,也就是过拟合;
  2. 线性模型用外积特征变换可以依赖少量的参数记住特征对

Wide层

wide层模型结构
wide部分是一个广义的线性模型,输入的特征主要有两部分组成,一部分是原始的部分特征,另一部分是原始特征的交叉特征即cross product外积运算,当两个特征同时交叉出现时为1,任意一个特征不出现表示为0。
在这里插入图片描述

为什么Wide部分要用L1 FTRL训练?

对于wide部分训练时候使用的优化器是带L1正则的FTRL算法(Follow-the-regularized-leader),FTRL可以理解为稀疏性很好,精度又不错的随机梯度下降方法。W&D模型采用L1-FTRL是想让Wide部分变得更加的稀疏,即Wide部分的大部分参数都为0,这就大大压缩了模型权重及特征向量的维度。通过这样Wide部分模型训练完之后留下来的特征都是非常重要的,那么模型的“记忆能力”就可以理解为发现"直接的",“暴力的”,“显然的”关联规则的能力。

Deep层

Deep部分是一个DNN模型,输入的特征主要分为两大类,一类是数值特征(可直接输入DNN),一类是类别特征(需要经过Embedding之后才能输入到DNN中)。Deep部分可以减少人工的特征参与,对历史上没出现过的情况有更好的泛化能力。对于Deep部分的DNN模型作者使用了深度学习常用的优化器AdaGrad,这也是为了使得模型可以得到更精确的解。
在这里插入图片描述

联合训练

在这里插入图片描述
联合训练的公示如上,wide_n_deep模型的组合依赖于其输出的对数几率的加权作为预测。随后这一值被输入到一个一般的逻辑损失函数中联合训练。联合训练和拼装不同,其是在训练过程中同时优化wide和deep模型及总和的权重,而拼装是将模型分别训练,结果是在最后进行组合。整体的模型结构如图:
在这里插入图片描述

总结

由上图可见,wide部分输入的是两个id类特征的乘积,id特征为User Installed App 和 Impression App,不难猜测Google的工程师使用这个组合特征的意图,是想发现当前曝光app和用户安装app的关联关系,以此来直接影响最终的得分。两个id类特征向量进行组合,在维度爆炸的同时,会让原本已经非常稀疏的multihot特征向量,变得更加稀疏。正因如此,wide部分的权重数量其实是海量的。为了不把数量如此之巨的权重都搬到线上进行model serving,采用FTRL过滤掉哪些稀疏特征无疑是非常好的工程经验。
然而Deep部分的输入,要么是Age,订单次数,评分这些数值类特征,要么是已经降维并稠密化的Embedding向量。所以Deep部分不存在严重的特征稀疏问题。
因此wide部分记住的是历史数据中那些常见、高频的模式,是推荐系统中的“红海”。实际上,Wide侧没有发现新的模式,只是学习到这些模式之间的权重,做一些模式的筛选。正因为Wide侧不能发现新模式,因此我们需要根据人工经验、业务背景,将我们认为有价值的、显而易见的特征及特征组合,喂入Wide侧。
而deep侧通过embedding的方式将categorical/id特征映射成稠密向量,让DNN学习到这些特征之间的深层交叉,以增强扩展能力。

代码

这里使用tensorflow的API-estimator来实现wide_n_deep模型:

// """Example code for TensorFlow Wide & Deep Tutorial using TF.Learn API."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse #argsparse是python的命令行解析的标准模块,内置于python,直接在命令行中就可以向程序中传入参数并让程序运行。
import sys
import tempfile #tempfile模块用于快速地创建名称唯一的临时文件供使用.

import pandas as pd
from six.moves import urllib
import tensorflow as tf

CSV_COLUMNS = [
    "age", "workclass", "fnlwgt", "education", "education_num",
    "marital_status", "occupation", "relationship", "race", "gender",
    "capital_gain", "capital_loss", "hours_per_week", "native_country",
    "income_bracket"
]

'''
https://zhuanlan.zhihu.com/p/73701872
常见的特征预处理:连续变量分箱、离散变量one-hot、离散指标embedding等
tensorflow提供了一个特征处理函数tf.feature_column,它通过对特征处理将数据输入网络并交由estimator来进行训练

categorical_column_with_vocabulary_list类别型函数,将类别按照顺序输出成0-n的整数,然后再用indicator_column做one-hot编码
当类别过多,无法一一列举,可以使用with_vocabulary_file,以文件形式输入
'''

gender = tf.feature_column.categorical_column_with_vocabulary_list(
    "gender", ["Female", "Male"])

education = tf.feature_column.categorical_column_with_vocabulary_list(
    "education", [
        "Bachelors", "HS-grad", "11th", "Masters", "9th",
        "Some-college", "Assoc-acdm", "Assoc-voc", "7th-8th",
        "Doctorate", "Prof-school", "5th-6th", "10th", "1st-4th",
        "Preschool", "12th"
    ])

marital_status = tf.feature_column
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值