文章目录
7 评分预测
7.1 评分预测算法
7.1.1 平均值
7.1.2 基于邻域的方法
7.1.3 隐语义模型及矩阵分解
7.1.4 加入时间信息
7.2 模型融合
7.2.1 级联融合
7.2.2 加权融合
7 评分预测
前面的推荐算法都是给用户推荐TopN物品的算法,而也有一部分推荐会把问题转化为评分预测问题,即预测用户会给物品打多少分。
一般采用RMSE度量预测的精度,即均方根误差:
RMSE=∑(u,i)∈T(rui−rˆui)2√∣Test∣
RMSE=∣Test∣∑(u,i)∈T(rui−r^ui)2
其中rui
rui为预测的用户u对物品i的评分,rˆui
r^ui为实际的用户u对物品i的评分。
7.1 评分预测算法
7.1.1 平均值
代码链接:https://github.com/Magic-Bubble/RecommendSystemPractice/blob/master/Chapter8/评分预测算法.ipynb
最简单的评分预测算法是利用平均值预测用户对物品的评分。
全局平均值
定义为训练集中所有评分记录的评分平均值:
rˆui=μ=∑(u,i)∈Trainrui∑(u,i)∈Train1
r^ui=μ=∑(u,i)∈Train1∑(u,i)∈Trainrui
用户评分平均值
定义为用户u在训练集中所有评分的平均值:
rˆui=r¯u=∑i∈N(u)rui∑i∈N(u)1
r^ui=rˉu=∑i∈N(u)1∑i∈N(u)rui
物品评分平均值
定义为物品i在训练集中所有评分的平均值:
rˆui=r¯i=∑u∈N(i)rui∑u∈N(i)1
r^ui=rˉi=∑u∈N(i)1∑u∈N(i)rui
用户分类对物品分类的平均值
假设有两个分类函数,一个是用户分类函数ϕ
ϕ ,一个是物品分类函数ψψ。ϕ(u)ϕ(u) 定义了用户u所属的类,ψ(i)
ψ(i)定义了物品i所属的类。则可以利用训练集中同类用户对同类物品评分的平均值预测用户对物品的评分,即:
rˆui=∑(v,j)∈Train,ϕ(u)=ψ(v),ϕ(i)=ψ(j)rvj∑(v,j)∈Train,ϕ(u)=ψ(v),ϕ(i)=ψ(j)1
r^ui=∑(v,j)∈Train,ϕ(u)=ψ(v),ϕ(i)=ψ(j)1∑(v,j)∈Train,ϕ(u)=ψ(v),ϕ(i)=ψ(j)rvj
其实前面所有的平均值都是这种类类平均值的特例。除了这3种特殊的平均值,在用户评分数据上还可以定义很多不同的分类函数。
用户和物品的平均分 对于一个用户,可以计算他的评分平均分。然后将所有用户按照评分平均分从小到大排序,并将用户按照平均分平均分成N类。物品也可以用同样的方式分类。
用户活跃度和物品流行度 对于一个用户,将他评分的物品数量定义为他的活跃度。得到用户活跃度之后,可以将用户通过活跃度从小到大排序,然后平均分为N类。物品的流行度定义为给物品评分的用户数目,物品也可以按照流行度均匀分成N类。
7.1.2 基于邻域的方法
基于用户的邻域算法和基于物品的邻域算法都可以应用到评分预测中。
基于用户的邻域算法
该算法认为预测一个用户对一个物品的评分,需要参考和这个用户兴趣相似的用户对该物品的评分,即:
rˆui=r¯u+∑v∈S(u,K)⋂N(i)wuv(rvi−r¯v)∑v∈S(u,K)⋂N(i)∣wuv∣
r^ui=rˉu+∑v∈S(u,K)⋂N(i)∣wuv∣∑v∈S(u,K)⋂N(i)wuv(rvi−rˉv)
这里,S(u,K)
S(u,K)是和用户u兴趣最相似的K个用户的集合,N(i)N(i)是对物品i评过分的用户集合, rvirvi是用户v对物品i的评分,r¯v
rˉv是用户v对他评过分的所有物品评分的平均值。
用户之间的相似度wuv
wuv可以通过皮尔逊系数计算:
wuv=∑i∈I(rui−r¯u)⋅(rvi−r¯v)∑i∈I(rui−r¯u)2∑i∈I(rvi−r¯v)2√
wuv=∑i∈I(rui−rˉu)2∑i∈I(rvi−rˉv)2
∑i∈I(rui−rˉu)⋅(rvi−rˉv)
基于物品的邻域算法
该算法在预测用户u对物品i的评分时,会参考用户u对和物品i相似的其他物品的评分,即:
rˆui=r¯i+∑j∈S(i,K)⋂N(u)wij(ruj−r¯i)∑j∈S(i,K)⋂N(u)∣wij∣
r^ui=rˉi+∑j∈S(i,K)⋂N(u)∣wij∣∑j∈S(i,K)⋂N(u)wij(ruj−rˉi)
这里,S(i,K)
S(i,K)是和i最相似的物品集合,N(u)N(u)是用户u评过分的物品集合, wijwij是物品之间的相似度,r¯i
rˉi是物品i的平均分。
至于如何计算物品之间的相似度,有如下三种方式:
a. 余弦相似度
wij=∑u∈Urui⋅ruj∑u∈Ur2ui∑u∈Ur2uj√
wij=∑u∈Urui2∑u∈Uruj2
∑u∈Urui⋅ruj
b. 皮尔逊系数
wij=∑u∈U(rui−r¯i)⋅(ruj−r¯j)∑u∈U(r2ui−r¯i)2∑u∈U(r2uj−r¯j)2√
wij=∑u∈U(rui2−rˉi)2∑u∈U(ruj2−rˉj)2
∑u∈U(rui−rˉi)⋅(ruj−rˉj)
c. 被Sarwar称为修正的余弦相似度
wij=∑u∈U(rui−r¯u)⋅(ruj−r¯u)∑u∈U(r2ui−r¯u)2∑u∈U(r2uj−r¯u)2√
wij=∑u∈U(rui2−rˉu)2∑u∈U(ruj2−rˉu)2
∑u∈U(rui−rˉu)⋅(ruj−rˉu)
7.1.3 隐语义模型及矩阵分解
用户的评分行为可以表示成一个评分矩阵R,其中R[u][i]就是用户u对物品i的评分。但是,用户不会对所有的物品评分,所以这个矩阵里有很多元素都是空的,这些空的元素称为缺失值(missing value)。因此,评分预测从某种意义上说就是填空,如果一个用户对一个物品没有评过分,那么推荐系统就要预测这个用户是否是否会对这个物品评分以及会评几分。
传统SVD分解
学过矩阵论的读者应该都知道,矩阵分解可以用SVD(奇异值)分解方法。给定m个用户和n个物品,和用户对物品的评分矩阵R∈Rm×n
R∈Rm×n。首先需要对评分矩阵中的缺失值进行简单地补全,比如用全局平均值,或者用户/物品平均值补全,得到补全后的矩阵R’。接着,可以用SVD分解将R′
R′分解成如下形式:
R′=UTSV
R′=UTSV
其中U∈Rk×m
U∈Rk×m,V∈Rk×nV∈Rk×n是两个正交矩阵, S∈Rk×kS∈Rk×k是对角阵,对角线上的每一个元素都是矩阵的奇异值。为了对R′R′进行降维,可以取最大的ff个奇异值组成对角矩阵SfSf,并且找到这ff个奇异值中每个值在UU、VV矩阵中对应的行和列,得到UfUf、Vf
Vf,从而可以得到一个降维后的评分矩阵:
R′f=UTfSfVf
Rf′=UfTSfVf
其中,R′f(u,i)
Rf′(u,i)就是用户u对物品i评分的预测值。
这种早期的方法有如下两个缺点:
a. 该方法首先需要用一个简单的方法补全稀疏评分矩阵,,这种空间的需求在实际系统中是不可能接受的。
b. 该方法依赖的SVD分解方法的计算复杂度很高,特别是在稠密的大规模矩阵上更是非常慢。
Simon Funk的SVD分解
其实就是LFM,针对上面两个问题进行解决,直接将评分矩阵R
R分解为两个低维矩阵相乘:
Rˆ=PTQ
R^=PTQ
其中P∈Rf×m
P∈Rf×m和Q∈Rf×nQ∈Rf×n是两个降维后的矩阵。那么,对于用户u对物品i的评分的预测值Rˆ(u,i)=rˆui
R^(u,i)=r^ui ,可以通过如下公式计算:
rˆui=∑fpufqif
r^ui=f∑pufqif
其中puf=P(u,f)
puf=P(u,f),qif=Q(i,f)
qif=Q(i,f)。得到这个公式之后,就直接通过训练集中的观察值利用最小化RMSE学习P、Q矩阵,损失函数如下:
C(p,q)=∑(u,i)∈Train(rui−∑Ff=1pufqif)2+λ(∣∣pu∣∣2+∣∣qi∣∣2)
C(p,q)=(u,i)∈Train∑(rui−f=1∑Fpufqif)2+λ(∣∣pu∣∣2+∣∣qi∣∣2)
可以用经典的SGD进行优化,其梯度公式为:
∂C∂puf=−2qik+2λpuk
∂puf∂C=−2qik+2λpuk
∂C∂pif=−2puk+2λqik
∂pif∂C=−2puk+2λqik
则优化公式如下,其中α
α是学习率:
puf=puf+α(qik−λpuk)
puf=puf+α(qik−λpuk)
qif=qif+α(puk−λqik)
qif=qif+α(puk−λqik)
加入偏置项后的LFM(BiasSVD)
相比于上面的LFM,这里为预测公式加入了偏置项,如下:
rˆui=μ+bu+bi+pTu⋅qi
r^ui=μ+bu+bi+puT⋅qi
公式中加入了三项偏置,μ
μ、bubu和bibi。其中μμ是训练集中所有记录的评分的全局平均数,表示网站本身对用户评分的影响;bubu是用户偏置项,表示用户的评分习惯中和物品没有关系的那种个人因素;bi
bi是物品偏置项,表示了物品接受的评分中和用户没有什么关系的因素。
考虑邻域影响的LFM(SVD++)
可以将之前的ItemCF预测算法改为如下形式:
rˆui=1∣N(u)∣√∑j∈N(u)wijruj
r^ui=∣N(u)∣
1j∈N(u)∑wijruj
这里,wij
wij不再是根据ItemCF算法计算出的物品相似度矩阵,而是一个和PP、Q
Q一样的参数,它可以通过优化如下的损失函数进行优化:
C(w)=∑(u,i)∈Train(rui−∑j∈N(u)wijruj)2+λw2ij
C(w)=(u,i)∈Train∑(rui−j∈N(u)∑wijruj)2+λwij2
这个模型有一个缺点,就是w将是一个比较稠密的矩阵,存储它需要比较大的空间。此外,如果有n个物品,那么该模型的参数个数就是n2
n2个,这个参数个数比较大,容易造成结果的过拟合。因此可以对ww矩阵也进行分解,将参数个数降低到2∗n∗F
2∗n∗F个,模型如下:
rˆui=1∣N(u)∣√∑j∈N(u)xTiyj=1∣N(u)∣√xTi∑j∈N(u)yj
r^ui=∣N(u)∣
1j∈N(u)∑xiTyj=∣N(u)∣
1xiTj∈N(u)∑yj
这里,xi
xi和yjyj是两个F维的向量。由此可见,该模型用xTiyjxiTyj代替了wij
wij ,从而大大降低了参数的数量和存储空间。
再进一步,可以将前面的LFM和上面的模型相加,从而得到如下模型:
rˆui=μ+bu+bi+pTu⋅qi+1∣N(u)∣√xTi∑j∈N(u)yj
r^ui=μ+bu+bi+puT⋅qi+∣N(u)∣
1xiTj∈N(u)∑yj
为了防止太多参数造成过拟合,可以令x=q
x=q,这样就得到了最终的SVD++模型:
rˆui=μ+bu+bi+qTi⋅(pu+1∣N(u)∣√∑j∈N(u)yj)
r^ui=μ+bu+bi+qiT⋅(pu+∣N(u)∣
1j∈N(u)∑yj)
7.1.4 加入时间信息
基于邻域的模型融合时间信息(TItemCF)
通过如下公式预测用户在某一个时刻会给物品什么评分:
rˆuit=∑j∈N(u)⋂S(i,K)f(wij,Δt)ruj∑j∈N(u)⋂S(i,K)f(wij,Δt)
r^uit=∑j∈N(u)⋂S(i,K)f(wij,Δt)∑j∈N(u)⋂S(i,K)f(wij,Δt)ruj
其中,Δt=tui−tuj
Δt=tui−tuj是用户u对物品i和物品j评分的时间差,wijwij是物品i和j的相似度,f(wij,Δt)f(wij,Δt)是一个考虑了时间衰减后的相似度函数,可以用如下公式:其中的σ
σ是sigmoid函数。
f(wij,Δt)=σ(δ⋅wij⋅exp(−∣Δt∣β)+γ)
f(wij,Δt)=σ(δ⋅wij⋅exp(β−∣Δt∣)+γ)
可以发现,随着Δt
Δt增加,f(wij,Δt)
f(wij,Δt)会越来越小,也就是说用户很久之前的行为对预测用户当前评分的影响越来越小。
基于矩阵分解的模型融合时间信息(TSVD)
这里其实就是对(User, Item, Time)三维矩阵进行分解,前面的BiasSVD模型为:
rˆui=μ+bu+bi+pTu⋅qi
r^ui=μ+bu+bi+puT⋅qi
则加入时间信息的可以变为TSVD:
rˆuit=μ+bu+bi+bt+pTu⋅qi+xTu⋅yt+sTi⋅zt+∑fgu,fhi,flt,f
r^uit=μ+bu+bi+bt+puT⋅qi+xuT⋅yt+siT⋅zt+f∑gu,fhi,flt,f
这里bt
bt建模了系统整体平均分随时间变化的效应,xTu⋅ytxuT⋅yt建模了用户平均分随时间变化的效应,sTiztsiTzt建模了物品平均分随时间变化的效应,而∑fgu,fhi,flt,f
∑fgu,fhi,flt,f建模了用户兴趣随时间影响的效应。
同样的,对SVD++模型也可以加入时间信息为:
rˆui=μ+bu(t)+bi(t)+qTi⋅(pu(t)+1∣N(u)∣√∑j∈N(u)yj)
r^ui=μ+bu(t)+bi(t)+qiT⋅(pu(t)+∣N(u)∣
1j∈N(u)∑yj)
bu(t)=bu+αu⋅devu(t)+but+bu,period(t)
bu(t)=bu+αu⋅devu(t)+but+bu,period(t)
devu(t)=sign(t−tu)⋅∣t−tu∣β
devu(t)=sign(t−tu)⋅∣t−tu∣β
bi(t)=bi+bit+bi,period(t)
bi(t)=bi+bit+bi,period(t)
puf(t)=puf+putf
puf(t)=puf+putf
这里,tu
tu是用户所有评分的平均时间,period(t)
period(t)考虑了季节效应,可以定义为时刻t所在的月份。
7.2 模型融合
一般模型融合都是数据比赛最后的大杀器。
7.2.1 级联融合
代码链接:https://github.com/Magic-Bubble/RecommendSystemPractice/blob/master/Chapter8/级联融合评分预测算法.ipynb
这个有点儿像AdaBoost,即每次产生一个新模型,按照一定的参数加到旧模型上去,从而使训练集误差最小化。不同的是,这里每次生成新模型时并不对样本集采样,针对那些预测错的样本,而是每次都还是利用全样本集进行预测,但每次使用的模型都有区别,用来预测上一次的误差,并最后联合在一起预测。
假设已经有一个预测器rˆ(k)
r^(k),对于每个用户—物品对(u, i)都给出预测值,那么可以在这个预测器的基础上设计下一个预测器rˆ(k+1)
r^(k+1)来最小化损失函数:
C=∑(u,i)∈Train(rui−rˆ(k)ui−rˆ(k+1)ui)2
C=(u,i)∈Train∑(rui−r^ui(k)−r^ui(k+1))2
7.2.2 加权融合
上面那个是串行的,这个就是并行的。假设有K个不同的预测器rˆ(1),rˆ(2),...,rˆ(K)
r^(1),r^(2),...,r^(K),最简单的融合算法是线性融合,即最终的预测器rˆ
r^是这K个预测器的线性加权:
rˆ=∑Kk=1αkrˆ(k)
r^=k=1∑Kαkr^(k)
系数的选取一般采用如下方法:
假设数据集已经被分为了训练集A和测试集B,那么首先需要将训练集A按照相同的分割方法分为A1和A2,其中A2的生成方法和B的生成方法一致,且大小相似。
在A1上训练K个不同的预测器,在A2上作出预测。因为我们知道A2上的真实评分值,所以可以在A2上利用最小二乘法计算出线性融合系数αk
αk。
在A上训练K个不同的预测器,在B上作出预测,并且将这K个预测器在B上的预测结果按照已经得到的线性融合系数加权融合,以得到最终的预测结果。
除了线性融合,还有很多复杂的融合方法,比如利用人工神经网络的融合算法。
对于评分预测的算法就介绍到这里。