协同过滤利用了用户对标的物的行为相似性来推荐。
# 原理
协同过滤1 24(Collaborative Filter,CF)主要用于召回,主要分为ItemCF和UserCF。
协同过滤的核心是怎么计算标的物之间的相似度以及用户之间的相似度。我们可以采用非常朴素的思想来计算相似度。我们将用户对标的物的评分(或者隐式反馈,如点击、收藏等)构建如下用户行为矩阵(见下面图2),矩阵的某个元素代表某个用户对某个标的物的评分(如果是隐式反馈,值为1),如果某个用户对某个标的物未产生行为,值为0。其中行向量代表某个用户对所有标的物的评分向量,列向量代表所有用户对某个标的物的评分向量。有了行向量和列向量,我们就可以计算用户与用户之间、标的物与标的物之间的相似度了。具体来说,行向量之间的相似度就是用户之间的相似度,列向量之间的相似度就是标的物之间的相似度。
为了避免误解,这里简单解释一下隐式反馈,只要不是用户直接评分的操作行为都算隐式反馈,包括浏览、点击、播放、收藏、评论、点赞、转发等等。有很多隐式反馈是可以间接获得评分的,后面会讲解。如果不间接获得评分,就用0、1表示是否操作过。
在真实业务场景中用户数和标的物数一般都是很大的(用户数可能是百万、千万、亿级,标的物可能是十万、百万、千万级),而每个用户只会操作过有限个标的物,所以用户行为矩阵是稀疏矩阵。正因为矩阵是稀疏的,会方便我们进行相似度计算及为用户做推荐。
相似度的计算可以采用cosine余弦相似度算法来计算,可以是行或列的相似度:
# 基于标的物的协同过滤
类似地,通过将用户操作过的标的物最相似的标的物推荐给用户,这就是基于标的物的协同过滤的核心思想。
用户u对标的物$$s$$的喜好度$$sim(u,s)$$可以采用如下公式计算,其中$$S$$是所有用户操作过的标的物的列表,$$score(u, s_i)$$是用户$$u$$对标的物$$s_i$$的喜好度,$$sim(s_i, s)$$是标的物,$$s_i$$与$$s$$的相似度。
实际应用中,采用一个session 内的用户行为来计算 两个商品的pair对。
modified 算法
余弦相似度过于粗暴,容易出现哈利波特效应,改良版将会降低热门用户对商品的权重
- wbcos i2i (weighted bin)
- swing i2i
- expectaion i2i
最小化目标函数算法
- WALS
- SGD
SGD优点:非常灵活:适用于其他损失函数;可以并行化。
SGD缺点:较慢,收敛速度不那么快;难以处理未观察到的项(entries),需要使用负采样或gravity。
WALS优点:可以并行化;收敛速度比SGD更快;更容易处理未观察到的项(entries)。
WALS缺点:仅适用于平方损失;
ranki2i
背景:上面都是基于统计产生的i2i,实际展示的时候不是要最相似原商品的,还有考虑该商品的ctr 和 cvr 等综合产出
过程:利用模型,离线训练和离线预测,右i的点击率,并进行重排。
- 分别预测ctr,cvr
类似于线上rank,这里采用左i的feature和右i的feature,模型可采用现有rank模型,(gbdt,lr,dnn皆可) - 一步到位
利用pairwise或者listwise 作为损失函数
将gmv或者点击率转化为预测目标,label为多分类,指标为ndcg.
# 基于用户的协同过滤
根据上面算法思想的介绍,我们可以将与该用户最相似的用户喜欢的标的物推荐给该用户。这就是基于用户的协同过滤的核心思想。
用户$$u$$对标的物s的喜好度$$sim(u,s)$$可以采用如下公式计算,其中$$U$$是与该用户最相似的用户集合(我们可以基于用户相似度找到与某用户最相似的K个用户),$$score(u_i, s)$$是用户$$u_i$$对标的物s的喜好度(对于隐式反馈为1,而对于非隐式反馈,该值为用户对标的物的评分),$$sim(u, u_i)$$是用户$$u_i$$与用户$$u$$的相似度。
有了用户对每个标的物的评分,基于评分降序排列,就可以取topN推荐给用户了。
# 工程
虽然协同过滤算法原理非常简单,但是在大规模用户及海量标的物的场景下,单机是难以解决计算问题的,我们必须借助分布式技术来实现,让整个算法可以应对大规模数据的挑战。在本节,我们基于主流的Spark分布式计算平台相关的技术来详细讲解协同过滤算法的离线(批处理)实现思路,供大家参考(读者可以阅读参考文献1、2、3、4了解协同过滤算法原理及工业应用),同时会在下一节讲解在近实时场景下怎么在工程上实现协同过滤算法。
在这里我们只讲解基于标的物的协同过滤算法的工程实现方案,基于用户的协同过滤思路完全一样,不再赘述。
为了简单起见,我们可以将推荐过程拆解为2个阶段,先计算相似度,再为用户推荐。下面分别介绍这两个步骤怎么工程实现。
- 计算topK相似度
本步骤我们计算出任意两个标的物之间的相似度,有了任意两个标的物之间的相似度,那么我们就可以为每个标的物计算出与它最相似的K个标的物了。