BiasSVD是FunkSVD较为成功的改进版算法。BiasSVD假设评分系统包括三部分的偏置因素:一些和用户物品无关的评分因素。用户有一些和物品无关的评分因素,称为用户偏置项。而物品也有一些和用户无关的评分因素,称为物品偏置项。这很好理解,对于乐观的用户来说,它的评分行为普遍偏高,而对批判性用户来说,他的评分记录普遍偏低,即使他们对同一物品的评分相同,但是他们对该物品的喜好程度却并不一样。同理,对物品来说,以电影为例,受大众欢迎的电影得到的评分普遍偏高,而一些烂片的评分普遍偏低,这些因素都是独立于用户或产品的因素,而和用户对产品的的喜好无关。
假设评分系统平均分为μ,第i个用户的用户偏置项为\(b_i\),而第j个物品的物品偏置项为\(b_j\),则加入了偏置项以后的优化目标函数\(J(p_i,q_j)\)是这样的:
\[
\underbrace{argmin}_{p_i,q_j}\sum_{i,j}{(m_{ij}-p^T_iq_j-u-b_i-b_j)^2+\lambda({\Arrowvert{p_i}\Arrowvert}^2_2+{\Arrowvert{q_i}\Arrowvert}^2_2+{\Arrowvert{b_i}\Arrowvert}^2_2+{\Arrowvert{b_j}\Arrowvert}^2_2)}
\]
这个优化目标也可以采用梯度下降法求解。和·FunkSVD不同的是,此时我们多了两个偏执项\(b_i\)和 \(b_j\),\(p_i\)和\(q_j\)的迭代公式和FunkSVD类似,只是每一步的梯度导数稍有不同而已。\(b_i\)和 \(b_j\)一般可以初始设置为0,然后参与迭代。迭代公式为:
\[
p_i = p_i +\alpha((m_{ij}-p^T_iq_j-u-b_i-b_j)q_j-\lambda{p_i})
\]
\[ q_j = q_j+\alpha((m_{ij}-p^T_iq_j-u-b_i-b_j)p_i-\lambda{q_j}) \]
\[ b_i=b_i+\alpha(m_{ij}-p^T_iq_j-u-b_i-b_j-\lambda{b_i}) \]
\[ b_j=b_j+\alpha(m_{ij}-p^T_iq_j-u-b_i-b_j-\lambda{b_j}) \]
通过迭代我们最终可以得到P和Q,进而用于推荐。BiasSVD增加了一些额外因素的考虑,因此在某些场景会比FunkSVD表现好。
为读者进一步理解,笔者实现了基于MovieLens数据集实现了该方法。代码详见github:BiasSVD算法实现
小结LFM 是一种基于机器学习的方法,具有比较好的理论基础,通过优化一个设定的指标建立最优的模型。它实质上是矩阵分解应用到推荐的方法,其中FunkSVD更是将矩阵分解用于推荐方法推到了新的高度,在实际应用中使用非常广泛。当然矩阵分解方法也在不停的进步,目前矩阵分解推荐算法中分解机方法(matrix factorization, MF)使用最为广泛。
对于矩阵分解用于推荐方法本身来说,它容易编程实现,实现复杂度低,预测效果也好,同时还能保持扩展性。这些都是其宝贵的优点。但是LFM无法给出很好的推荐解释,它计算出的隐类虽然在语义上确实代表了一类兴趣和物品,却很难用自然语言描述并生成解释展现给用户。
LFM 在建模过程中,假设有 M 个用户、 N 个物品、 K 条用户对物品的行为记录,如果是 F 个隐类,那么它离线计算的空间复杂度是$ O(F(M+N))$ ,迭代 S次则时间复杂度为\(O(K * F * S)\)。当 M(用户数量)和 N*(物品数量)很大时LFM相对于ItemCF和UserCF可以很好地节省离线计算的内存,在时间复杂度由于LFM会多次迭代上所以和ItemCF、UserCF没有质的差别。
同时,遗憾的是,LFM无法进行在线实时推荐,即当用户有了新的行为后,他的推荐列表不会发生变化。而从 LFM的预测公式可以看到, LFM 在给用户生成推荐列表时,需要计算用户对所有物品的兴趣权重,然后排名,返回权重最大的 N 个物品。那么,在物品数很多时,这一过程的时间复杂度非常高,可达 \(O(M*N*F)\) 。因此, LFM 不太适合用于物品数非常庞大的系统,如果要用,我们也需要一个比较快的算法给用户先计算一个比较小的候选列表,然后再用LFM 重新排名。另一方面,LFM 在生成一个用户推荐列表时速度太慢,因此不能在线实时计算,而需要离线将所有用户的推荐结果事先计算好存储在数据库中。
参考:
协同过滤算法总结---by刘建平
推荐系统实战---项亮
推荐算法-基于矩阵分解的CF算法实现(二):BiasSvd