mahout协同过滤算法

一直使用mahout的RowSimilarity来计算物品间的相似度,今晚仔细看了其实现,终于搞明白了他的计算逻辑。

上篇中介绍了整个itemBaseCF的mapreducer过程,主要有三个大的步骤吧,我把他称为prepare阶段,计算相似阶段和利用相似性计算推荐阶段。

prepare阶段主要完成的是矩阵转换变换以及统计一些相似及推荐时用到的一些属性。

第二阶段是计算相似性:有几个数据较为重要,如下所示。

  • norms.bin:是用来存放所有用户对一个商品的平方和,数据存储为itemA:double
  • numNonZeroEntries.bin:存放itemID对应的不为零的用户评分个数
  • maxValues.bin:最大的那个用户评分

之后经过一次矩阵的转置以userID为行itemID为列,计算一个用户评分过的所有商品的乘积,(一个自循环计算其与其他商品评分的乘积)

接下来就是计算相似度了,以欧氏距离为例:d = sqrt( (x1-x2)x1+(y1-y2)^2+(z1-z2)^2 )...三维空间中的算法

他是和x12+x22+y12+y22+z12+z22-2(x1*x2+y1*y2+z1*z2)...同理扩展到多维空间中,而mahout中的相似度算法就是这么搞的,先统计所有用户对此商品(A)的评分的平方和,然后在计算所有用户对此商品(A)与要计算相似的商品(B)的所有乘积之和,这样计算相似时直接获取以上结果,也就是平方和减去2倍的乘积之和,再开方。最后转化成相似的表示形式【1/(1+d)】。完成相似度的计算。

太晚了明天继续预测评分。

====================================================================================================================

接着昨天的,下面是预测评分。

经过前面两步的工作已经将以user为key的矩阵写入userVectors目录下,而相似矩阵也已经有了,下面应该是将用户A已经评过分的商品的相似商品找出来,这些就应该是要推荐的备选商品了。现在要根据相似度预测备选商品的评分了。

  • 利用相似矩阵和用户的评分数据,得到以下形式的数据结构:
user1 pref1 similarityColumn1
user1 pref2 similarityColumn2
user2 ... ...

在程序里也就是以userID为key,value为PrefAndSimilarityColumnWritable的Vector,这样就得到,某个用户评过分的商品评分和与其相似的商品的矩阵,这些就是为此用户做推荐的备选商品。下一步就是预测这些商品的评分,有个细节就是在此就已经过滤掉此用户已经评过分的商品,也就是预测评分时评过分的商品不会出现在推荐列表中,以上图第一行为例,mahout是采用将similarityColumn1中pref1评分的商品的相似度设置为Double.NAN,这很巧妙,NAN的话以后进行任何计算得出的结果都是NAN,也就不会出现在最后的推荐列表中了。预测评分采用的也是简单(相似向量*评分再做加权)/(相似向量加权),mahout为了减少预测次数,他是只预测某个商品在这些similarityColumn的中出现两次以上的。

最后的推荐列表是推预测的商品做个倒排序,推荐列表就生成了。    

原文地址:https://www.cnblogs.com/zeng-wei/p/3258702.html