从学校毕业从19年实习在美团做广告推荐,然后20年开始一直在华为做视频推荐,从业时间不长,但是较学校的认知相比,还是完善了很多,故此总结,方便以后回顾。
文章目录
端到端流程
实践中的推荐系统或者“推荐”这个需求的设计,相对来说是一个比较长的链路,
初始阶段:了解推荐需求,了解业务特点,设计需要采集样本特征、标签
推荐模型应用到不同阶段,需要解决的问题不同,对于不同的业务场景,看重的指标也不同。因此,在工业界实践中,第一步也是最重要的一步:明确业务诉求,制定评估指标。
和学术界的单一评估指标不同,实际应用中根据业务发展的不同阶段,业务场景的不同,可能涉及的优化指标不同。
比如不同的业务场景:广告推荐、短视频推荐、电影推荐、小说推荐,在乎的指标都有所差异,比如广告场景不仅仅在乎CTR,从广告主的角度还在乎投资回报率RIO,但是这些转化因为转化时间比较长,所以label比较难以采集,怎么有效的采集转化,根据实际场景的不同又可以细分;小说推荐因为小说本身连载的性质,从业务角度来看更在乎用户的留存率。
再比如同一个业务的不同栏目,栏目定位不同,需求和评估指标也会有所差异,ee场景,要求探究用户的隐藏兴趣,就不能以ctr作为评估指标,更多的要以一些多元化的指标作为评估指标。
中间涉及的一些名词:
CTR::点击率 = 点击量 / 曝光量
CVR:转化率 = 转化量 / 点击量
ROI:投资回报率 = 订单额/消费量(即广告费用)
第二步:根据需要优化的目标,设计样本采集流程
新同学进入社会的第一步最不适应的点在于,可选择性太大了。之前在做kaggle比赛,或者写论文的时候,数据集都是固定的,也没有什么可挑选的。能做好的效果上限已经由数据集决定了,工作只用聚焦在特征工程、模型调参去适应这个小样本即可。
工业实践中,最痛苦的事情就在于,你并不确定上限在哪,你也不知道哪些特征可能是有用的,哪些没用,你可以选择的特征太多了,你可以选择的样本也太多了。
以淘宝购物来说,比如你是做女装分会场推荐的,只选择用户的女装点击购买数据,你也可以选择全淘宝的购买数据,你可以选择近一个月的,也可以选择近一年的,也可以选择近10年的,甚至对于淘系整个推荐大服务来说,一些用户画像的数据,比如年龄,购买力这些,可能有20个组给你提供了用户画像,你选择哪一个。还有就是什么算曝光了,这个定义是什么,是在界面上展现过就采集么?那如果用户快速上滑呢?或者该物品只展现了上边缘,到底算不算曝光了?
而且这个问题最吊诡的原因在于,可能你优化了一年的模型达到的提升效果,不如别人调研了一个星期,加了一些有用的效果提升大。
特别是,提数据需求是一个需要多项目组合作的工作,前端设置打点,数据组加工数据,很多涉及到项目排期问题,所以作为一个算法工程师,提前想好需要哪些特征,标签,是一个非常重要的事情,而且要具备前瞻性,因为可能你的诉求提上去,就变更不了了。
这里总结一些博主在实践中比较成功的一次方法论【后面可能会有更好的方法论,期待ing】,可以遵循以下步骤:
下面将以电影推荐为例介绍如何设计特征:
- 根据生活经验、博客等,梳理所有所有和用户观影行为可能相关的因素,比如:流行度、流量明星、不同的发行商(欢喜传媒等)、知名的导演(李安等)
- 根据核心因素,扩展成多维的具体指标:要把上面的那些因素扩展成具体的指标,比如流行度是一个比较笼统的概念,你可以扩展为近x天的播放量、完播量、观看人数、播放超过10%的数量/用户数量等,这个时间窗口也是一个很魔幻的点,对于一些效应性电影,特别是某些流量鲜肉们拍的,一般只有近7天的活跃度,不太会有人重复播放;对于一些经典老电影,播放量比较平均。所以这里不妨多设计几个窗口,在后面的特征选择中,选择最好的几个时间窗口。
- 小数据初步探究,进一步多维度扩展:还有一点在实践中非常重要的是用户和物品的冷启动,如何利用少量数据完成个性化推荐,用户群和物品群的概念非常重要,可以挖掘一些显式的标签用户群,比如经常半夜两点登陆的用户喜欢看什么电影?
- 初步审核特征:特征是否可以在实际中应用,还需要评估以下因素:(1)覆盖率 (2)线上线下特征的一致性 (3)数据可采集的可获得性、准确性 确定数据获取方案【根据现网实际技术水平评估,比如你的前端告诉你,我可以根据屏幕的反射判断用户是否看见物品啦,这种🐂,看官还是需要审慎,有些不确定的东西,用了不如不用】(4)时效性:需要确定数据就位时间,从技术层面可以给下游的同学进行一些大数据任务优化的指导,或者向现实屈服换一些数据。这个阶段,最好要配合数据组的同学校验数据质量,告诉他们详细的计算指标,以便提前了解数据质量,预先发现数据问题。
总之,第一阶段的主要目标是构造所有可用的特征。
阶段一:检查数据质量、初步挑选特征
经过漫长的等待后,拿到数据的小伙伴仍然不可以掉以轻心,接下来将进入工作量最大的一个阶段:特征工程。
这里其实包括 特征选择 和特征加工两个部分,这两个部分通常交叉进行。
特征加工的目的在于:将特征转化成有效的特征表示。
特征选择的目的在于:选择有用特征,降低数据维度,避免维度灾难,降低模型学习难度。
特征选择在方法论上filter法:依次判断单个变量和目标变量的相关性;wapper法:特征子集逐步回归、前向选择、后向选择;embeeding法:RF、LGB等。
但是实际操作中,我只喜欢用树模型。
在具体的实际操作中,可以遵循以下步骤:
-
1. 剔除易识别的无效的特征:无效的id值 ,比如数据库中的自增主键;一些方差很小的属性值 ,几乎所有样本恒定。假使这个属性值让样本区分度很大,应该直接分群建模。
-
2. 剔除作弊和异常数据:局部异常值检测,异常用户检查
-
3. 初步的特征处理:特征编码:
连续特征离散化的好处 :- 离散化的应该10-20,保证5%的统计量
- 离散化的稀疏向量内积速度更快,计算结果方便存储
- 对异常数据具有鲁棒性
- 引入非线性特征,增强模型表达能力
- 离散化后可以进行特征交叉,进一步增强非线性。
- 简化了模型,使模型更稳定
连续特征标准化、归一化的好处 :
- 有一些算法要求属性零均值单位方差,比如PCA
- 数量级差异会使数量级较大的属性占据主导地位,对于使用梯度下降以及和距离相关的KNN模型等不利。
- 数量级差异会导致迭代速度降低。
Tips: (1)决策树 模型中不推荐对离散特征onehot,原因有以下两个:1)产生样本不均衡的问题,而且会导致每个分增益都非常小 2)影响决策树学习:独热表码的表达能力差,特征的重要性会比实际的值低。
-
4. 根据模型选择预测能力强的特征:
- 与模型无关的预测能力:信息增益:ID3树 、信息增益率 :C4.5树、Gini系数:CART树 、
- 与模型有关的预测能力:模型的评估指标如AUC、Logloss等。可以分成正向检查,和反向将特征随机打散,看模型恶化的程度。
相关公式:
信 息 增 益 = 熵 − 条 件 熵 , 越 大 越 好 H ( c ) − H ( c ∣ x ) 信息增益=熵-条件熵,越大越好H(c)-H(c|x) 信息增益=熵−条件熵,越大越好H(c)−H(c∣x)
信 息 增 益 率 , 越 大 越 好 = H ( c ) − H ( c ∣ x ) H ( x ) 信息增益率,越大越好= \frac{H(c)-H(c|x)}{H(x)} 信息增益率,越大越好=H(x)H(c)−H(c∣x)
基 尼 系 数 , 越 小 越 好 = 1 − ∑ p i 2 基尼系数,越小越好 = 1- \sum{p_i^2} 基尼系数,越小越好=1−∑pi2
-
5. 检查结果的可解释性 重点观察一下几个指标:PSI值 、 IV和WOE值
-
6.特征被认为重要的稳定性:特征的重要性应该进行多次实验,避免偶然性带来的误差,不同的特征、样本子集、统计特征被认为重要的次数。
-
7. 特征之间的相关性:经过前面的环节,特征之间存在重要性的概率已经比较小了,但是如果在模型训练的时候发现指标不稳定,不妨对此做一些检查,共线性>0.8的特征只保留预测能力更大的那一个。
阶段二:挑选模型,进一步特征处理
- 表征学习
- 没有免费的午餐理论
没有一种模型适合所有的数据分布,所以需要先了解哪些模型适合现在场景的数据分布,并且了解随着模型演进修复了什么问题。
以ctr建模来说,各个模型介绍,请看相应的文章介绍:
FM:隐向量内积建模组合特征
FM:针对不同的Field使用不同的隐向量
wide&Deep:交叉特征作为一个线性模型的输入,wide和deep各使用一个优化器。
DCN:利用cross层代替wide层,自动构建高阶特征。
DeepFM:
DIN:
DIN:行为序列中不同的item对当前预测的item有不同的影响。
DIEN:解决DIN无法捕捉用户兴趣动态变化的特点
DSIN:从session层面局部建模。
多目标问题:
阶段三:根据离线指标优化模型
对于完整模型训练来说,算法只是其中一部分,完整的包括:
- 算法模型
- 评估指标
- 训练策略
- 模型分析
评估指标
对于分类任务,损失函数有:
对于回归任务,损失函数有:
对于多目标任务,损失函数可以设计为:
训练策略
数据集小的时候,学习率不宜过小,mini-batch-size不宜过大。
常用的超参数以及范围:
类别 | 常用取值 |
---|---|
learning rate | 1e-3,1e-4,1e-5,可以更细致如1.2e-3 |
decay rate | 1e-3,1e-4,1e-5 |
decay step | 1 2 3 4 5,还可以阶梯式下降 |
embedding size | 40 50 60 70 80 90,常用范围公式( log 2 类 别 + 1 , log 2 类 别 + 2 \log_2{类别}+1,\log_2{类别}+2 log2类别+1,log2类别+2) 或者 6 ∗ 类 别 数 6*\sqrt{类别数} 6∗类别数 |
Adam 学习率 | β 1 \beta_1 β1=0.9, β 2 \beta_2 β2=0.999, ϵ = 1 0 − 8 \epsilon=10^{-8} ϵ=10−8 |
Drop out
Normalization:Batch 、Layer
gradient decent
模型分析
训练数据集上表现不好,loss降不下来
原因: 模型不收敛
定位方法: (1)
深度模型梯度可视化
深度模型激活函数可视化
详情请参考文章: 使用tensorboard进行超参数优化。
模型收敛之后:如何诊断模型是过拟和还是欠拟合:
准备:不同时间窗口、不同范围的训练及和测试集。
绘制损失函数随数据集增加的学习曲线,可以设置使用1天、2天、3天、4天、5天、6天等
欠拟合:测试误差训练误差收敛,但是效果都不好
过拟合:训练样本增加,训练误差还是远小于测试误差
欠拟合
欠拟合即模型呈现高偏差状态,模型未训练出数据集特征,训练集、测试集精度都很低。
- 增加特征:增加业务衍生的相关特征,或者用FM、GBDT构建组合特征、DCN的cross层
- 增加模型复杂度:细分用户群体,多个模型,线性+高次;神经网络增加层数、隐单元
- 减少正则参数
过拟合
欠拟合即模型呈现高方差状态,训练及精度高,新数据集精度低。
- 增加数据
- 降低模型复杂度
- 增加正则
- 多模型融合
- droput
- 减少特征数据:共线性特征,特征降维
- 早停
正则
正则刻画模型复杂度的指标,通过限制模型中w的大小【注意,一般不对b计算】,使得模型不能你和训练数据的随机噪声。
L1正则
让参数变得稀疏,有更多的零。
参数遵循拉普拉斯分布。
不可导,近端求解。
L2正则
让参数变得小,有更多的小数,但是不会变成0。
参数遵循正态分布。
可导。
阶段四:线上A/B实验,根据case分析推荐瓶颈,制定优化方案
【图在另一个电脑上,回头补贴】
以后不要在公司写博客了,也记不住。