作者:pikachu
知乎:https://zhuanlan.zhihu.com/p/513522302
赛题描述
H&M是我们熟知的服饰购物平台,他拥有53个网上市场和大约4850家商店。赛题提供了2018年9月到2020年9月的用户购买记录(包括线上线下的购买记录)以及商品及用户的一些元数据,希望参赛选手预测接下来一周最有可能购买的衣物(评价指标为MAP@12)。题目描述中说明了构建优秀的推荐系统,不仅对于提高平台营收,还可以减少“退换货”等造成的物流损失。
EDA中发现,这个赛题大致有以下特点,商品侧的信息较为丰富,商品的最小粒度article_id, 是除了一些品类、颜色等基本属性外,还给出了商品的图像以及描述文本,值得一提的是多个article_id可能同属于同一个product_code,例如同一个商品有不同的颜色及尺寸。用户侧的信息猜测由于隐私保护的关系,给的相对较少,普遍被关注的是年龄(age)及邮编(postal_code),存在大比例的低活用户以及冷启动用户。商品量级大约在十万左右,用户量级在百万左右。购买记录还提供了成交时间以及当时成交价等关键信息。
问题分析
区别于以往比赛,只针对推荐系统的某个环节(如精排)设计赛题,往往给定训练与测试的样本,这个比赛最有趣的部分是需要我们构建一个较为完整的推荐系统,也就说需要我们自己构建训练与测试的样本。具体而言以下问题可能会比较令人关注的问题。
1. 如何构建一个pipeline,构建一个怎么样的pipeline
2. 如何为大量的冷启动用户或者低活用户,以及存在商品新上市的情况
对于第一个问题,一般而言,为解决从海量候选商品中,选出用户最后可能购买的商品,平衡性能与效率,工业推荐系统比较常见的思路是先用较为简单的模型高效地召回一些用户可能购买的候选商品,然后使用复杂的模型对候选商品进行排序,具体的召回策略与排序特征在下文前排方案分享中介绍。这往往是在商品候选集比较大的情况下的这种这种选择,大多数选手,包括前排的选手,都采用这种思路,当然也有选手尝试召回-粗排-精排的方案。而另一种思路则是考虑由于H&M场景下候选的商品较少,可以构建端到端的模型,使用基于类似DIN的target attention来去建模候选商品与用户历史购买商品的关系,借助较为巧妙的矩阵运算,实现高效地端到端的推荐
对于第二问题,由于用户侧的属性信息较少,常见的策略是将热门的商品推荐给冷启动用户,更加细致地可以根据用户属性信息分年龄、地区等推荐热门商品。对于新上市的商品,商品侧的内容理解(包括商品的一些品类、颜色等信息,以及图文信息)便显得比较重要。
前排方案总结
top1[3]
第一名方案的思路非常流畅,他们尝试了不同的召回策略,排序阶段使用了特征工程+GBDT的搭配,看上去非常简单,但是效果却很惊艳。
在他们理解中,衣物的消费有随潮流变化快、具有明显的季节性等特点,所以他们主要通过召回最急流行度(销量)比较高的商品,另一方面,他们也尝试了召回一批新品,但是排序模型并不能把这些新品排到top12,给出的解释是这些新品缺乏历史的交互信息。
如下图所示,他们的召回策略包括:
复购,交互数据中可以发现有很多用户复购的行为,根据用户历史购买行为,召回购买数量topN的商品。
itemCF,经典的协同过滤方法,把与用户购买过的商品“相似的”商品推荐出来
同款商品不同型号,有些用户有换货的行为,比如换一个大一号的鞋子等。
流行度topN,按销量推荐topN
Graph embedding召回,使用deepwalk, node2vec, LINE, ProNE来产生用户与商品的embedding,然后使用embedding进行向量召回。
logistic regression with categorical information, 训练一个罗辑回归模型,从hot-1000中粗排出topN的商品
top1 framework
如何理解用户与商品的交互信息一般被认为是推荐系统中最重要的问题,所以他们的在特征工程阶段做的最主要的特征是用户与商品的交互特征,他们也提到图文信息的理解并没有帮助他们排序模型的提升,但是在真实的场景中,这些图文信息对于冷启动的投放有着重要的意义。
大约有50%的用户在过去三个月没有在平台买过任何商品,对于这些用户,考虑历史累积的统计特征(比如历史上购买过某种品类衣服的数量),而对于活跃的用户,则统计其近期(上礼拜,上个月,上个季度)的消费情况。排序的详细特征如下:
1. count类特征,例如用户购买过候选商品的数量、次数,用户某买过候选商品品类的特征,统计的时间窗口大小可以是上礼拜,上个月,上个季度,统计数量时,也有按照时间加权(购买时间越久的,权重越小)
2. time类特征,用户上一次消费的时间与当前的时间差,用户上一次购买该商品的时间当前的时间差(如果很短,可以刻画用户的退换货的期望,比如一般来演电商平台都有七天无理由,超过了七天,用户退换货的可能就会很小)。对应地,商品侧地时间特征同样重要,比如商品上次成交的时间到现在的时间差(可以看出商品是否下架),最早交易的时间差(预估上市时间)等。
3. Mean/Max/Min特征,即用户侧与商品侧的聚合特征,如用户历史购买的商品的价格的均值、最值(刻画用户的消费能力),购买某商品的用户年龄的均值、最值。
4. Difference/Ratio特征,如用户年龄与购买候选商品的用户平均年龄之间的差值,用户历史购买候选商品所属品类占所有购买商品数量的比例。
5. Similarity,来自召回侧的特征,例如item2item的协同过滤的分数,item2vec产生的cosine similarity,user2item(ProNE)产生的similarity。
对于排序模型他们使用了六周的数据来训练模型,最后一周的数据用来作为验证集,为每个用户召回100个候选商品,这样的实验设置,可以保持交叉验证与线上公榜的成绩变动基本稳定, 所以工作的重点就可以放在优化单个lightgbm模型。在这里详细说明一下整个召回以及排序的流程,整个流程虽然简单,但是很多细节却可圈可点。
为了简化,假设交易数据给定的最后一周为第17周,那么我们需要为未来的一周(即第18周)进行推荐,第17周则用来作为验证集,11-16周作为训练集。
有如下几个有意思的问题:
1. 怎么为这11-18周(共8周)的用户召回产生候选集,又怎么产生特征呢?
> 简单来说,对于第N周,使用N周以前(谨防穿越)的用户历史记录来进行召回,以及构建特征。
2. 实际上,这样以来所有的召回策略以及特征需要跑8次,那能不能使用第10周及以前的数据一下子为11-18周推荐呢? 我觉得可能不太可以,但是效果不会很好,原因如下:
> - 特征分布不一致,对于第11周而言,特征(包括召回策略)来自前一周,而对于第18周而言,特征来自八周前。
> - 不能充分利用用户的历史交互数据,这在原本用户行为比较稀疏的场景下是不能接受的。比如说,对于第18周而言,就11-17周的用户历史交易记录就白白被忽视了。
3. 在跑的8次中,有六次是为训练集的六周跑的,那只用第16周作为训练集呢?实际上是可以的,但是效果可能会退化,原因如下:
> - 还是数据量比较小,过少数据模型容易过拟合
> - 如果精排模型使用基于神经网络的模型,如石塔西老师所说,类别特征是”一等公民“[4],userid的embedding必然是重要的特征,如果在第16周用户没有购买过商品,那么他的userid的embedding就抓瞎了。当然基于GBDT的模型,userid作为类别特征也会有类似的问题,也会有类似的问题。
> - 正样本稀疏,召回率较低(recall100item~18%)
4. 一般电商推荐的排序的场景下,平台会曝光给用户部分商品,这些商品往往是推荐系统上一次迭代产生的,往往具有一定合理性,排序训练的负样本一般选用曝光未购买的商品。但是本赛题只提供了用户的交易记录,即没有负样本,另一个点是,这些购买记录有一些是线下实体店发生的。那么排序的负样本怎么来呢?
> 使用召回未购买的样本作为负样本作为排序的负样本。一个原因是在对测试集进行排序时,我们拿过来的也是召回过来的样本,需要从其中把正样本排到前面来,训练时把召回未购买的商品作为负样本就比较合理了;另一个原因这些召回未购买的样本是有一些合理性的,属于比较难的负样本,这有利于帮助排序模型的学习。
5. 为什么不能用随机负采样作为排序的负样本呢?
> 这个问题,其实跟上个问题关系很大,简单而言,排序模型排的是召回过来的样本,使用随机采样的样本作为负样本会导致训练与测试时的样本分布不一致。有一个比较相似的经典问题是:训练召回模型能不能使用曝光未点击的样本作为负样本。答案是也不行,原因也类似,召回是从全量的商品候选池中选出较为合理的候选商品,只使用曝光未点击作为负样本也会导致训练与测试时的样本分布不一致。
6. 来自召回侧的分数特征,为什么奏效?
> 把召回侧的分数特征作为排序的特征,可以看作把召回专家的意见告诉排序模型。在精排特征比较相对粗糙的时候,来自召回的意见可以保证排序模型的效果不差于召回模型。另一方面,来自召回侧的分数本身具有实际意义,例如一些双塔模型给出的user与item的打分等等,都是重要性很高的特征。当然这些特征也可以放在排序的过程中做,具体做法如下个问题,在第三名的方法中,也详细介绍了这一思路,并且据作者描述,其提升很大。
boost my LB score
from 0.02855 to 0.03262,
In addition, if I only increase the recall num and don't adding the recall features, the CV score is very very poor.
[5]7. Similarity特征如果具体是如何做的
可以分基于模型的方法以及基于协同过滤的方法两方面介绍
1. 基于模型的方法,一般通过一些方法(MF,graph embedding类的方法)得到user与item的表征embedding,然后在召回时使用dot product为候选商品打分。第三名的方法[6]中同样提到这个方法:
大致思路是当为target week的(user,item)打分时,使用target week之前的交互数据训练一个BPR matrix factorization model 然后,计算target week的(user,item)的分数,据第三名的作者描述,在这个特征的加持下,提升明显(0.0336->0.03510).
This BPR model is trained with all the transactions before the target week (I've trained one BPR for each week) using
implicit
. The auc of BPR similarity is ~0.720, while the auc of the whole ranking model is ~0.806 and the best auc of other single feature is ~0.680. At last, this single similarity feature boost my LB score
from 0.03363 to 0.03510,
2. 基于协同过滤的方法,以itemCF为例,给一个(user,item)的pair打分时,考虑用户购买过的商品序列,计算序列中每一item与候选item之间的相似度,然后按照权重进行聚合。计算两个item之间相似度的方法可以是:
item之间tag(品类,颜色等)的相似度(jaccard)
item之间图文的相似度(使用Bert、MobileNet提出title、图片的embedding,然后计算embedding的cosine similarity)
购买过两个item的用户序列之间的相似度(jaccard)
来自item2vec等network embedding方法产生的embedding的相似度。
...
其他方案里的一些亮点或技巧
MMOE来增强排序模型对冷启动用户或者低活用户的推荐效果[7],使用用户的活跃信息来gate不同的expert
使用FIL对lightgbm进行推理加速,据说可以快10x
catboost-gpu比lightgbm快30x,但是效果貌似往往差于lightgbm
构建feature store,防止重复创建特征耗费时间
inference时,可以分批处理,缓解内存压力
reduce_mem_usage 以及对类别特征进行label encoder
反思与感悟
该赛题确实是一个很棒的比赛,在比赛中收获了不仅知识上的积累,更重要的是,锻炼了自己对某个业务场景的思考。当然,其实也有一些反思:
1. 参赛队伍的方法或有或无的在预测用户是否“退换货”,这其实并不是我们想要的结果。用户购买了一件不满意的商品,所以需要退换,在大多数方案中,这些不满意的商品被作为“正样本”来训练模型,这其实是不合理,在真实的推荐场景中,这应该是hard negative example, 是精排模型需要重点学习的样本。
2. 没有给一批曝光未购买的商品,作为hard negative example,这其实限制了排序性能的进一步提升。
参考
^DIN https://arxiv.org/abs/1706.06978
^e2e_nn https://www.kaggle.com/code/aerdem4/h-m-pure-pytorch-baseline
^top1 https://www.kaggle.com/competitions/h-and-m-personalized-fashion-recommendations/discussion/324070
^五环之歌 https://zhuanlan.zhihu.com/p/336643635
^top3 solution https://www.kaggle.com/competitions/h-and-m-personalized-fashion-recommendations/discussion/324129
^top3 https://www.kaggle.com/competitions/h-and-m-personalized-fashion-recommendations/discussion/324129
^mmoe https://www.kaggle.com/competitions/h-and-m-personalized-fashion-recommendations/discussion/324094