一、整体架构
精排是整个推荐算法中比较重要的一个模块,目前基本都是基于模型来实现,涉及样本、特征、模型三部分。
- 正负样本不均衡 :比如CTR任务,如果点击率是5%,则正负样本1: 20,负样本远远多于正样本,导致样本不均衡。分类问题中样本不均衡,会导致模型整体偏向样本多的那个类别,导致其他类别不准确。解决方法主要有:
- 负采样: 对负样本进行采样,可以直接采用随机负采样。 一方面可以减少样本存储和模型训练的压力,另一方面可以缓解正负样本不均衡问题。 但负样本其实也有很多信息的,直接丢弃实在可惜,特别是小场景样本不足的时候。
- focal loss: 何凯明老师在图像多分类样本不均衡中采用的方法,也可以使用到推荐场景中。 通过减少负样本(易分类)在loss中的权重,使得模型更加专注于正样本(样本少,难分类)
- 不同活跃度用户样本不均衡 :中长尾用户样本少,高频用户样本多,最终模型容易偏向高频用户,从而在中长尾用户上预估越来越不准确。针对这一问题,可以对高频用户进行降采样,也可以对所有用户均采用相同的样本数(youtube做法)
- 样 本置信度问题 :曝光点击可以认为置信度较高,但曝光未点击就一定表名用户不会点击,一定是负样本吗?目前有以下集中情形:
- 用户完全没有正样本: 用户如果只是为了签到,或者碰巧被push唤醒,抑或是随便点开了APP,完全没有正样本,全部是负样本。 这个时候不点击只是用户此时意愿很差,跟你推的item是否符合他的兴趣关系不大。 此时可以直接将该用户所有的负样本过滤掉。
- 爬虫等非法流量 : 推荐工程侧直接拦截掉。
- 点击与否可能也与用户需求是否已经得到满足有关系。 美团采用了skip-above采样方式,对用户最后一个点击位置以下的负样本,直接丢弃。
(一)主要有哪些特征
精排是特征的艺术,虽然特征工程远远没有深度模型那么fancy,但在实际业务中,基于特征工程优化,比基于模型更稳定可靠,且效果往往不比优化模型低。特征工程一定要结合业务理解,在具体业务场景上,想象自己就是一个实际用户,会有哪些特征对你是否点击、是否转化有比较大的影响。一般来说,可以枚举如下特征:- context特征 :如星期、时间、网络类型、操作系统、客户端版本等。
- user特征 ,也就是常说的用户画像,可以共享其他兄弟APP或者同一APP不同场景内的,用户各个维度的特征,主要包括 三部分 :
- 静态特征 : userid、性别、年龄、城市、职业、收入水平、是否大学生、是否结婚、是否有小孩、注册时间、是否vip、是否新用户等。 静态特征一般区分度还是挺大的,比如不同性别、年龄的人,兴趣会差异很大。 再比如是否有小孩,会直接决定母婴类目商品是否有兴趣。
- 统计特征 : 比如user近30天、14天、7天的pv、vv、CTR、完播率、单vv时长等,最好同时包括绝对值和相对值。 毕竟2次曝光1次点击,和200次曝光100次点击,CTR虽然相同,但其置信度天差地别。 统计特征大多数都是后验特征,对模型predict帮助很大。 统计特征一定要注意 数据穿越 问题,构造特征时千万不要把当天的统计数据也计算进去了。
- 行为序列特征 : 这一块目前研究很火,也是精排模型提升的关键。 可以构建用户短期点击序列和长期购买序列,也可以构建用户正反馈点击购买序列和负反馈曝光未点击序列。 序列长度目前是一个痛点,序列过长时,Transformer等模型计算量可能很大,导致模型RT和P99等指标扛不住,出现大量超时。
- item特征 ,这一块不像用户画像容易兄弟APP共享,不同APP可能itemid等重要特征不能对齐,导致无法领域迁移。 主要有如下特征:
- 统计特征 : 如item近14天、7天、3天的pv、vv、CTR、完播率、单vv时长等,最好同时包括绝对值和相对值。 跟user侧统计特征一样,要注意数据穿越问题。
- 交叉特征 : item与user交叉特征,比如item在不同性别年龄用户上的统计特征。 虽然模型可以实现自动特征交叉,但是否交叉得好就要另说了。 手工构造关键的交叉特征,还是很有意义的。
(二)怎么处理特征
特征的处理主要有如下几种情况:
- 离散值 :直接embedding,注意高维稀疏id特征,比如itemid和userid的收敛问题。
- 连续值 :主要有两种方式:
- 直接与其他embedding concat: 操作简单,但泛化能力差。
- 正样本等频分桶 ,再离散化: 泛化能力较强,是目前通用的解决方案。
- 多值特征 : 最典型的就是用户行为序列,主要方法有:
- mean-pooling (youtube)、 sum-pooling : 将行为序列中item特征,逐个进行mean-pooling或者sum-pooling,比如youtube的论文。 这个方法十分粗糙,完全没有考虑序列中不同item对当前的打分,以及行为的时序转化关系。
- att-pooling : 将行为序列中各item,与待打分target item,进行attention计算再平均,也就是加权平均,比如DIN。 这个方法考虑了item的重要程度,也支持引入item的重要side info,通过引入item index,其实也可以带有一定的时序信息,可以作为序列建模的baseline。
- 序列建模 : 将行为序列中各item,通过GRU等RNN模型,进行建模,取出最后一个位置的输出即可,比如DIEN。 此方法考虑了用户行为的时序关系和兴趣迁移,目前基本都使用Transformer来进行时序建模,可以缓解反向传播梯度弥散、长序列建模能力差、串行耗时高等问题。
四、模型
精排模型从线性时代,已经完全步入深度学习时代。线性时代主要有三大类:
- CF协同过滤类:比如userCF、itemCF、MF等。
- LR逻辑回归类:LR、FM、FFM、双线性FM、LS-PLM等。
- 多模型融合类:GBDT+LR。
- CF协同过滤类
- userCF: 利用user向量,找到与当前user相似的其他user,再将他们感兴趣的item推荐给当前user。
- itemCF:同理利用item向量,找到与当前user历史行为topK中的item相似的其他item,将它们推荐给当前用户。
- userCF需要user行为较为丰富,itemCF则需要item被行为比较丰富。所以对于新闻类等item实时性要求高的场景, 由于冷启item很多,所以可以考虑userCF 。
- 一般来说用户量要远大于推荐池的item数量,也就是user向量远多于item向量,故userCF的存储压力和向量检索压力都要大于itemCF。同时也导致user向量远比item向量要稀疏,相似度计算准确性不如itemCF。
- 由于大部分user只对很少一部分item有行为,导致user与item的 行为矩阵十分稀疏 ,甚至有些user根本没有任何行为,影响了向量相似度计算准确性。
- user和item数量都很大,行为矩阵存储压力很大。
- 矩阵稀疏也带来一个问题,就是头部热门item容易与大多数item均相似,导致极其严重的 马太效应 。
由于不像CF中向量是基于行为产生的,有比较明确的含义,故MF中的向量也叫user隐向量和item隐向量。通过MF,可以解决CF向量过于稀疏的问题,同时由于K远小于M和N,使得高维稀疏向量实现了低维稠密化,大大减小了存储压力。
MF矩阵分解有哪些实现方法呢,可以基于SVD和梯度下降来计算。由于SVD有一定限制条件,基于梯度下降的比较多。因此MF也被称为model-based CF。
MF本质上仍然是基于用户行为来构建的,没有充分利用user和item的各种feature,比如用户性别年龄,导致有大量的信息丢失。LR和FM就应运而生。
- LR逻辑回归类
FFM则引入了field的概念,将n个特征归入f个filed内,同一个特征在不同的filed,其向量不同。相比FM,能够更好的捕捉每个域内的交叉特征。
- 多模型融合GBDT+LR
GBDT梯度提升决策树,每一颗树都是拟合前一颗树和目标之间的loss,从而使得最终loss不断缩小。如下图所示:
进入深度模型时代后,精排模型发展更为迅猛,借用王喆老师的一张图,如下:
- DNN类 :DeepCrossing、FNN、PNN等
- Wide&Deep异构模型 类:优化记忆和泛化问题,主要包括四大类:
- wide&deep: 开启了异构模型时代,优化记忆和泛化问题。
- wide侧改进:deep&cross(DCN)、deepFM等。
- deep侧改进: AFM、NFM等。
- 加入新的子网络: xDeepFM等。
- Attention和序列建模类 :
- 注意力机制建模:AFM、autoInt、FiBiNet、DIN等。
- 序列建模: DIEN、MIMN、SIM等。
- DNN类
- DeepCrossing
- embedding层:将高维稀疏id特征,进行低维稠密化。对于非id类特征,则不进行embedding处理,直接进入下一层。
- stacking层:把不同embedding和数值型特征,直接concat起来,进行特征融合。
- DNN层:采用类似于ResNet的残差连接方式,构建了三层DNN,使用relu作为激活函数。利用DNN拟合能力强的优点,实现多特征交叉。FM只能实现二阶交叉,三阶则参数量爆炸,而DNN则可以做到高阶特征交叉。
- 输出层:分类问题的输出一般都是使用一个softmax,将logits转化为0~1之间,代表每个类别的概率,取概率大的则为最终的输出。也可以基于逻辑回归,将输出logits取sigmod,转化为0~1之间的概率。
- PNN
- FNN
- WDL异构模型类
- wide&deep
- wide侧改进:DeepFM等
- deep侧改进:NFM等
- 加入子分支:xDeepFM等
- attention和序列建模
- Attention :AFM、autoInt、FiBiNet、DIN等。
- 序列建模:DIEN等
- 行为序列层(蓝色部分) :id类特征进行embedding。
- 兴趣抽取层(黄色部分) :利用GRU序列建模,抽取用户兴趣,每个position会有一个输出。
- 兴趣进化层(红色部分) :加入注意力机制,与待打分item进行target attention,再利用GRU得到序列最后一个位置输出。
五、精排优化
- 记忆和泛化 :高频靠记忆,低频靠泛化,WDL类的异构模型主要就是为了解决这个问题。
- 特征 交叉 :包括手动交叉和自动交叉两类。特征工程中手动构造user和item交叉统计特征,就是手动交叉的典范,目前这种方法仍然使用很普遍。而自动交叉则可分为线性和深度模型两种。线性模型就是FM、FFM这种,深度模型则采用DNN进行特征交叉。
- embedding :embedding实现了高维稀疏向量的低维稠密化,作为精排模型的第一层,已经成为了基本范式。
- 高维稀疏id特征 : 高维id特征区分度很大,对模型贡献高,但它们一般都比较稀疏,特别是中长尾的item和user样本少,加上其embedding维度高,比较难收敛。 高维稀疏id特征的收敛问题也是一个待优化的关键问题。
- 个性化行为建模 :基于用户历史行为进行个性化推荐,是目前推荐算法的一大热点。行为序列如何建模是一个关键问题,multi-head attention和序列模型给出了各自解决方案。同时序列过长会导致计算和存储压力很大,带来线上延迟,MIMN和SIM对这方面有一定优化。
作者简介
谢杨易
腾讯应用算法研究员