1.基于内容的推荐算法(Content-based recommendations)
基于内容的推荐算法大概思路如下:
1) 根据用户A喜欢的商品提取商品的特征值集合setA
2)根据setA寻找相似的商品,将商品推荐给A
对于文档来说,可以提取文档里词的TF.IDF值,来找出能够代表这个文档的特征词汇:
TF意思是词频(Term Frequency),即该词出现在此文章中的频率
TF公式:
IDF意思是逆文本频率指数(Inverse Document Frequency),即总文件数与出现该词文件数的比值
IDF公式:
TF.IDF值就是TF与IDF的乘积,所得的分数越高,相应的该特征就越明显,越具有辨识度。
对于基于内容的推荐算法,寻找出合适的特征值非常的必要,但是特征值的选取往往很困难,所以该方法存在一定的局限性。
2.协同过滤算法(Collaborative Filtering)
协同过滤算法的大概思路如下:
1)对于用户B,根据用户B的评分找出和用户B相似的用户集合setB
2)通过setB预测出用户B对别的商品的评分,把高分商品推荐给用户B
上面这种思路又叫做User-User Collaborative Filtering,当然还有Item-Item Collaborative Filtering的思路:
1)对于商品C,根据全体用户集合setALL对商品C的评分,寻找出和商品C相似的商品集合setC
2)通过商品C与setC的相似度预测某用户对别的商品的评分,把高分商品推荐给别人
协同过滤不需要找出商品的特征值,而只需要分析用户的行为就可以为用户推荐相应的产品。这个行为指的是用户对某些商品感兴趣的行为,例如对商品的评分,对商收藏量等行为判断。但是协同过滤方法也有相应的缺点,如不能给新用户推荐产品,不能把新产品推荐给用户等。
这里有篇国外的博客把CF算法写得很好 点击这里
协同过滤算法理论虽然很简单,但是实践起来就一点也不轻松了,这里把博客里的思路捋一捋:
1)首先是数据集准备,这里使用的用户对电影的评分
2)一般来说,数据集都是一条一条地用户对电影的评分,这里要将这些数据导入一个矩阵中,行为用户,列为电影。
3)计算矩阵的稀疏率(判断用户的评价数目)
4)将数据分为训练集和测试集(训练集用来训练,测试集用来评价结果)
5)使用余弦相似度将数据进行相似度评价,这里如果检测用户相似度,则把一个用户对不同电影的评分当成是一个向量,通过余弦相似度公式计算得出一个用户相似度矩阵,不用说这个矩阵是一个关于主对角线对称的矩阵。商品相似度矩阵也是同理可以求出。
6)将相似矩阵与训练集相乘求和并标准化(即加权求和再标准化)预测出所有用户对所有商品的评分。
7)计算预测的评分与测试集评分(即真实值)的MSE,判断预测模型的好坏。
8)为了提高MSE值,通过排序找出最相似的前K个用户(商品),进行topK预测
3.基于矩阵分解(Matrix Factorization)
大致思路如下:对于一个用户-物品评分的稀疏矩阵,我们可以将其分解为用户-特性P矩阵和,物品-特性矩阵Q。即:
在这里每一个R^矩阵中每一个元素可以表示为:
这里的k值,指的是分解出来的特征的个数,即P的列数和Q的行数,这样通过分解再相乘我们就可以得到一个预测的用户-评分矩阵。
2.例子
例子如下,假如对于一个用户和电影的矩阵R:
分为K=5个特征的矩阵P和Q:
这里的s1、s2、s3、s4、s5就是电影隐藏的特征,假设这些隐藏的特征分别为:动作、冒险、惊悚、喜剧、解谜,用户-特征代表了用户对这些特征的喜好,而电影-特征代表了电影具有这些特征的程度。通过计算:
我们就能得到每个用户的所有评分了。
3.分解步骤
这里详细讲一下分解的方法:(迭代的方法)
1.将矩阵随机分成K个特征的P和Q
2.分解之后,计算P×Q与原矩阵R的误差:
3.通过误差可以得到p和q的梯度,有了梯度就能缩小误差:
4.通过梯度获得新的矩阵:
5.重复步骤2,3,4 计算总体误差小于某个值时,迭代停止,总体误差如下:
当然,上面的步骤只是最基本的分解步骤,还要加上一个正则项,避免分解出来的矩阵P、Q相乘等于原矩阵R,这样分解就白做了。如下,在误差里加入正则项:
通过新梯度获得新的矩阵为:
继续迭代找出最优解。
推荐使用sklearn库里的函数,根本不用想那么多\捂脸
总结:今天还算是比较舒服的一天,MF算法没有想象中的那么难,而且自己也用代码实现了出来了,所以感觉成就感满满,写代码能力直线上升,继续加油。
4.杂交算法(Hybrid Methods)
将上面三种方法混合使用
混合得到的结果:
这里我保证了所有的训练集和测试集都是相同的。可以看出,混合算法确实起到了一点效果,其中MF_CB混合算法的MSE值最低,但是混合算法并不混的越多越好(可能是误差的原因,混合得越多,相应的引入的误差就越多)。当然算法每次实现MSE值都会有一点点的不同