简介
本文以问题为导向介绍推荐算法。
问题一
问题定义:假设U={u1,u2,...,un}表示用户集合, P={p1,p2,...,pm}表示物品集合,S∈Rn×m表示用户对物品的评分组成的矩阵,例如sij表示用户ui对物品pj的评分,如果用户ui没有对物品pj没有评过分数,则对应的矩阵项为空。我们的目标是为用户生成个性化的TopN推荐列表。
1. 基于用户的协同过滤
按照基于用户的协同过滤算法,我们需要找到目标用户的相似用户,首先可以用用户各自的评分组成的向量表示用户,比如要计算两个用户的ua,ub的相似度,则ua=[sa1,sa2,...,sam],ub=[sb1,sb2,...,sbm],然后计算用户向量间的相似度。向量相似度的计算方式有很多,比如欧式距离、协方差、余弦相似、Pearson相关系数、Jaccard系数等。
d(x,y)=i=1∑n(xi−yi)2
欧式距离的取值范围是0到正无穷,取值越小表示相似度越高,取值为零表示两个向量完全相等。
-
协方差的计算公式为:
Con(x,y)=E[(x−E[x])(y−E[y])]=E[xy]−E[x]E[y]
-
Pearson相似度的计算公式为:
ρ(x,y)=σxσyCon(x,y)=σxσyE[x−E[x]])(y−E[y]
其中σx,σy分别表示x,y的标准差。
cos(x,y)=∣x∣∣y∣∑xiyi=∑ixi2∑iyi2∑xiyi
那么如何选择相似度的计算方法呢?这些相似度计算方法之间满足下面的关系
定理一:数据标准化之后(均值为0,标准差为1),Pearson相关系数等于余弦相似度
证明如下:
ρ(x,y)=σxσyCon(x,y)
=σxσyE[(x−E[x]])(y−E(y))
E[x]=0,E[y]=0,σx=1,σy=1带入以上公式得到;
ρ(x,y)=E(xy)=N∑ixiyi
又因为:
cos(x,y)=∑ixi2∑iyi2∑ixiyi
=N∗∑ixi2/N∑iyi2/N∑ixiyi
=N∑ixiyi
=ρ(x,y)
定理二:数据标准化之后(均值为0,标准差为1),Pearson相关系数有欧式距离的平方满足线性关系
证明如下:
d(x,y)2=i∑n(xi−yi)2
=i∑n(xi2−2xiyi+yi2)
=i∑nxi2+i∑nyi2−2i∑nxiyi
=ni∑nnxi2+ni∑nnyi2−2i∑nxiyi
=nσx2+nσy2−2i∑nxiyi
=n+n−2nρ(x,y)
=2n(1−ρ(x,y))
定理三:数据标准化之后(均值为0,标准差为1),预选相似度与欧式距离平方满足线性关系
回到推荐算法,我们以Pearson相似度计算为例,用户ua,ub之间的相似度计算公式为;
sim(a,b)=∑i∈P(a,b)(sai−μa)2∑i∈P(a,b)(sbi−μb)2∑i∈P(a,b)(sai−μa)(sbi−μb)
其中P(a,b)表示a,b用户共同评过分的物品集合,μa,μb分为表示用户a,b评分的均值。
有了用户相似度计算方法之后,就可以利用相似用户的评分,预测目标用户的评分,比如a用户对物品p的评分可以通过下面公式预测:
Pred(a,p)=μa+∑b∈U(a,K)sim(a,b)∑b∈U(a,K)sim(a,b)(sbp−μb)
其中U(a,K)表示与用户相似度最高的TopK个用户组成的集合。
以上是最基本的基于相似用户的推荐算法,实践中可以有几个方向的改进:
- 在计算用户相似度的时候,并没有考虑热门物品的影响,显然喜爱这类热门物品,并不表示两位用户的兴趣比较相似,相反,共同喜爱某些冷门物品,更能表示两个用户的兴趣比较类似。
- 在计算用户相似度的时候,并没有考虑用户有多少个共同评分的物品。显然当用户虽然评分非常一致,但是只对极少数物品评分,也并不能表示两位用户的兴趣类似。
改进算法就不在这里展开了,可以通过设计一些加权算法赋予不同的物品以不同的权重来改进基本版本的算法。
2. 基于物品的协同过滤
类似的,有了评分矩阵后,物品a,b的评分表示为pa=[s1a,s2a,...,sna],pb=[s1b,s2b,...,snb]。我们可以直接通过相似度计算方法计算两个物品的相似度,比如余弦相似度为:
sim(a,b)=∑i∈U(a,b)sia2∑i∈U(a,b)sib2∑i∈U(a,b)siasib
其中U(a,b)表示对物品a,b都评过分的用户的集合。
有了物品的相似度后,可以预测某个用户对某个物品的评分值:
Pred(u,p)=sim(i,p)∑i∈P(u,p)sim(i,p)sui
其中P(u,p)表示用户u评过分的与物品p相似的物品集合。
以上的相似度计算方法,在实践中与几个方向的改进:
- 在计算物品相似度的时候,各个纬度是同等加权的,实际中不同用户对物品相似度的贡献不一样的。活跃用的兴趣可能比较宽泛,这类用户喜欢物品,并不能说明两类物品比较类似。
- 在计算物品相似度的时候,并没有考虑共同评分的用户数量。显然被极少数用户评论过并不能代表物品比较相似。
3. 基于奇异值分解(SVD)
奇异值分解的原理是将原始的评分矩阵分解为3个矩阵乘积的形式:
S=UΣVT
其中U,V称为左右奇异向量,Σ对角线墒的值称为奇异值。
分解矩阵之后,如何对目标用户进行推荐呢?
拿到目标用户的评分向量uv,首先计算目标用户在低位空间的位置:
uv′=uvUΣ−1
有了目标用户子低维空间的位置,可以有不同的策略为她推荐物品,比如可以在低维空间寻找相似用户,用相似用户的物品评分预测目标用户的物品评分。
对以上的基本算法可以有几个方向的改进:
4. 基于隐语义学习(LFM)
首先基础的LFM通过下面的公式计算用户对物品的评分:
sui=puqiT=k=1∑Kpu,kqi,k
其中pu,k,qi,k称为模型的参数。那么如何得到模型的参数呢?可以通过最小化下面的损失函数来计算模型的参数:
C=∑(sui−sui)2
一般为了防止过拟合,我们会在损失函数上加上正则化:
C=∑((sui−sui)2+λ∣pu∣2+λ∣qi∣2)
关于机器学习的内容我们在其他文章里有详细的介绍,这里就不展开了。
我们来对基础的LFM做一些改进:
sui=puqiT+bu+bi+μ
其中bu,bi,μ分别表示用户评分的偏置,物品评分的偏执,全局平均分。
如此则损失函数变成:
C=∑((puqiT+bu+bi+μ−sui)2+λ(∣pu∣2+∣qi∣2+∣bu∣2+∣bi∣2))
- 我们将用户的属性加入到模型,比如用户的年龄、地域等,每一个属性值都对应一个隐因子
sui=(pu+∑au)qiT+bu+bi+μ
- 我们将用户的消费过的物品加入模型,每个消费过的物品都对应一个隐因子
sui=(pu+∑au+∣N(u)−0.5∣k∈N(u)∑yk)qiT+bu+bi+μ
- 加入时间的考虑,或对样本进行时间的加权,或将重要的时间特征对应隐因子加入模型,或将样本按时间分类,不同时间段对应不同的参数。
有了这些隐因子之后,如何对目标用户进行推荐呢?很简单,有了隐因子之后,我们可以直接估算用户对某个物品的评分了,按评分的高低生成TopN推荐列表。
问题二
问题定义:假设U={u1,u2,...,un}表示用户的集合,P={p1,p2,...,pm}表示物品的集合,P(ui),ui∈U表示用户i的所以有正反馈的物品组成的集合。这里的正反馈可以是隐式反馈。目标是为用户生成TopN推荐列表。
1. 基于用户协同过滤
Jaccard相似度计算:
sim(u,v)=J(u,v)=∣P(uu)∪P(uv)∣∣P(uu)∩P(uv)∣
余弦相似度计算:
sim(u,v)=Cos(u,v)=∣P(uu)∣∣P(uv)∣∣P(uu)∩P(uv)∣
有了相似用户之后,就可以预测目标用户对目标物品的兴趣程度:
Pred(u,p)=∑v∈U(u,K)∩U(p)sim(u,v)∑v∈U(u,K)∩U(p)sim(u,v)rvp
其中U(u,k)表示与用户u最相似的K个用户组成的集合,U(p)表示对物品p有个正反馈的用户集合。
我们对以上的基本算法做一下改进:
- 我们在计算用户相似度的时候,没有考虑热门物品的影响,热门和非热门物品度对用户相似度的影响程度一样。显然这事不太对的,因为共同喜欢热门物品,并不能表示两个用户的兴趣比较类似,只能说明这个物品比较热门,被大多数人喜欢。
所以我们改进用户相似度的计算方法:
sim(u,v)=ImprovedCos(u,v)
=∣P(uu)∣∣P(uv)∣∑p∈P(uu,uv)log(1+∣U(p)∣)1
其中U(p)表示对物品p有过正反馈的用户集合。
2. 基于物品协同过滤
物品的余弦相似度计算法公式为:
sim(i,j)=∣U(i)∣∣U(j)∣∣U(i)∩U(j)∣
有了物品相似度之后可以预测用户对物品的兴趣程度:
Pred(u,p)=∑i∈P(p,K)∩P(u)sim(p,i)∑i∈P(p,K)∩P(u)sim(p,i)rui
其中P(p,K)表示物品p最相似的K个物品的集合,P(u)表示用户u正反馈过的物品集合。
下面我们对上面的基本算法做个改进:
- 在上面计算物品相似度的时候,所有用户对物品相似度的贡献值是一样的。这个假设不太合理,活跃用户对相似度的影响应该小于非活跃用户,这个概念被称为反用户频率(Inverse Uesr Frequence)。因为被活跃用户感兴趣的物品,不一定很相似。
改进后的相似度计算方式为:
sim(i,j)=ImprovedCos(i,j)=∣U(i)∣∣U(j)∣∑u∈U(i)∩U(j)log(1+∣P(u)∣)1
3. LFM模型
LFM模型在评分预测类的任务中表现很好,同样在行为预测类的任务中也可以使用:
sui=(pu+∑au+∣N(u)−0.5∣k∈N(u)∑yk)qiT+bu+bi+μ
正样本总取sui=1,负样本则取sui=0. 在这类任务中,训练数据只有正样本,而没有负样本。所以首先需要解决的问题是如何为用户生成负样本数据。
负样本的采样策略可以是简单的,随机的从用户没有过行为的数据中选取。但是也有一些改进的方法,比如偏重热门物品,因为热门的物品用户大概率看到过,但是没有正反馈,这表示是一个负样本。
4. 基于图的算法
基于图的推荐算法中,我们首先需要将用户的行为数据表示成图的形式。
定义:我们将用户的行为表示为图G=(Vu,VI,E),其中Vu表示用户顶点集合,每一个顶点表示一个用户,VI表示物品顶点集合,每一个顶点表示一个物品。用户的历史行为可以表示为[用户,物品]二元组的形式,对于每一个这样的二元组,图G中都存在一条连接对应用户和物品的边,构成集合E.
例如有用户u1,u2,u3,u4,分别有各自的历史行为,他们的历史行为表示为图的形式如下:

用户的行为表示为图的形式之后,推荐过程就是在图中寻找与目标用户顶点具有相关性的物品顶点。那么首先需要解决的是如何衡量图中顶点间的相关性。
实践中研究人员设计了很多计算图中顶点相关性的算法。这里介绍一种基于随机游走的PersonalRank算法。对于每一个目标用户vu,我们通过下面的公式计算顶点的权重:
Rank(v)=αv′∈in(v)∑∣out(v)∣Rank(v′) if(v=vu)
Rank(v)=(1−α)+αv′∈in(v)∑out(v)Rank(v′) if(v=vu)
经过若干次的迭代后顶点的权重会收敛,此时的权重值可以作为物品推荐的分数。
5. 基于内容的算法
基于内容的推荐算法的基本思想是给目标用户推荐他喜欢的物品的相似物品,但与基于物品的协同的过滤算法不同,物品间的相似度由物品的属性(物品类别、标签等等)决定,而不是由物品上积累的用户行为决定。由于不需要物品上积累的用户行为,基于内容的推荐算法在物品冷启动阶段非常有用。
基于内容的推荐可以分成三个阶段:
- 物品的分析阶段,生成物品画像,包括物品的类别、标签、价格、品牌等等。物品画像的维度同时也定义了用户画像的维度。
- 用户兴趣点提取阶段,生成用户兴趣点画像
- 根据用户的兴趣点生成推荐列表
第一阶段我在其他的文章中有详细介绍过,涉及的算法根据物品的不同,可能会涉及文本处理、图像处理、人工生成标签等等,这里不展开,重点介绍一下二三阶段。
首先遇到的问题是什么是兴趣点?前面已经提到了,物品画像的维度定义了用户的兴趣点。
第二个问题是如何提取用户的兴趣点?基本是方式是通过用户与物品的交互行为历史(浏览、点击、收藏、购买、分享、屏蔽等)生成用户的兴趣点。
一般来说,兴趣点的提取可以从考虑以下的量化指标:
我们来对兴趣点的提取做一些改进:
- 上面在提取兴趣点的时候,没有考虑兴趣点本身的热门程度,我们加入反兴趣点自身频率的考虑,因为这样才会捕捉到用户的非热门的兴趣点。
- 加入时间衰减的考虑,最近的正向反馈行为的权重要大于一段时间前的正向反馈行为
- 分时间段的兴趣点提取
在第三个阶段,有了用户的兴趣点之后,如何为用户生成推荐内容呢?这里可以有不同的推荐策略,比如简单的可以将兴趣点作为检索关键词直接检索出相关的物品。也可以加入一些实时兴趣点筛选逻辑,根据用户当时的状态实时决定用哪些兴趣点。
6. 排行榜推荐策略
排行榜可能是最容易被忽视的非个性化的推荐策略,但在很多情况下不失为一种很好的推荐策略。
常见的排行榜有:
我们在基本的排行榜策略里,加入用户的人口统计学特征,比如性别、年龄、 地域、职业等特征,可以生成半个性化的排行榜。
7. 社会化推荐
社会化推荐是指利用用户的社交关系进行推荐的策略。有了用户的社交关系,最简单的推荐策略就是给目标用户推荐其好友喜欢的物品集合:
sui=v∈Related(u)∑wuvsvi
其中Related(u)表示用户u的好友集合。svi表示用户v对物品i的兴趣程度。wuv表示用户u,v间的熟悉程度的权重。
还有一些社会化推荐算法,将用户间的好友关系以及用户与物品间的兴趣关系通过图的形式表示,然后采用基于图的推荐算法。
8. 深度学习的实践
深度神经网络、多目标训练、增强学习等深度学习在推荐系统中的实践,在其他的文章中有过专门介绍,这里不展开了。