mahout中map-reduce版的itembased推荐算法思想

时间:2022-12-07 17:28:55
mahout中map-reduce版的itembased推荐算法思想
最近想写一个map-reduce版的userbased,于是先研究mahout中已实现的itembased算法。itembased看起来简单,但是深入到实现细节还是有点复杂的,用map-reduce实现就更复杂了。

 

itembased的本质:

预测某用户user对某物品item的打分,

看看该用户对其他item的打分,如果其他item跟该item越相似,则权重越高。

最后加权平均。

 

itembased核心步骤:

1 计算item相似度矩阵(利用两个矩阵相乘)

2 user打分矩阵 乘以 item相似度矩阵  = user评分预测矩阵

 mahout中map-reduce版的itembased推荐算法思想

当然,这里所谓的矩阵相乘,并不是数学意义上的相乘。数学意义上的相乘,前面矩阵的行向量和后面的列向量是算内积。而这里,往往不仅仅是内积,有可能做了normalize,有可能做了downsample等等。

 

 

输入文件数据格式:        userID,itemID,pref

user1,item1,pref

user2,item1,pref

user2,item2,pref

user3,item1,pref

 

 

USER_VECTORS:      userID,vector[(itemID,pref)]

user1,vector[(item1,pref)]

user2,vector[(item1,pref),(item2,pref)]

user3,vector[(item1,pref)]

 

RATING_MATRIX:    itemID,vector[(userID,pref)]

item1,vector[(user1,pref),(user2,pref),(user3,pref)]

item2,vector[(user2,pref)]

 

 

RATING_MATRIX-> similarityMatrix

通过计算RATING_MATRIX行与行之间的相似性,得出itemsimilarity

 

Item1

Item2

Item1

 

 

Item2

 

 

 

 

MAPPER:

similarityMatrix->    itemID,vector[(itemID,sim)]

item1,vector[(item2,sim)]

item2,vector[(item1,sim)]

 

USER_VECTORS-> itemID,(userID,pref)

item1,(user1,pref)

item1,(user2,pref)

item2,(user2,pref)

item1,(user3,pref)

(格式跟输入文件一直,但是存储的数据结构不同)

 

REDUCER:itemID,(vector[(itemID,sim)],(vector[userID],vector[pref]))

当前ITEM,与当前ITEM相似的item的列表(取topK),对当前ITEM打过分的user列表及其打分。

item1,(vector[(item2,sim)],(vector[user1,user2,user3],vector[pref,pref,pref]))

item2,(vector[(item1,sim)],(vector[user2],vector[pref]))

 

 

MAPPER:userID,(pref(cur_item),vector[(itemID,sim)])

表示userID对cur_item的打分是pref,与cur_item相似的item列表及其相似度是vector。

 

user1,(pref(item1),vector[(item2,sim)])

user2,(pref(item1),vector[(item2,sim)])

user3,(pref(item1),vector[(item2,sim)])

user2,(pref(item2),vector[(item1,sim)])

 

比如第一行表示的意思,到时要预测user1对未评分item的打分,因为item1与她相似,所以要考虑user1对item1的评分。

 

REDUCE:userID,itemID,pref

通过上面的mapper,同一user的数据都落在一个reducer中,

就可以得到一个用户所有的打分item,以及这些item跟其他item的相似度。

UserID

Item1

Item2

Item1,pref

NULL

sim

Item2,pref

Sim

NULL

 

 

User1

Item1

Item2

Item1,pref

NULL

sim

Item2,unkownPref

Sim

NULL

 

User2

Item1

Item2

Item1,pref

NULL

sim

Item2,pref

Sim

NULL

 

User3

Item1

Item2

Item1,pref

NULL

sim

Item2,unkownPref

Sim

NULL

 

 

根据这个(user,item),item的矩阵,就可以预测出该user对未打分的item的打分了。

p(u,n)=sum(pref(u,i)*sim(n,i))/sum(sim(n,i))

表达的意思是,想预测u对n的偏好,

遍历u之前看过的i,

参考对这些i的偏好,

和这些n跟i的相似度,

加权平均。

 

值得一提的是,mahout为了考虑性能,并没有真正做了一个完整的矩阵乘法。

比如就itemsimilarity,只保留了topK,其他都没有存(其实就是相似度太小,可以忽略不计)。

因此,对于某个user,要预测的item集合,并不是item全集减去该user已评分的item集合。而是该user已评分的item各自最为相似topK的item集合。对于不在这集合里面的item,表明与当前user已评分的item相似性太小,直接表明该user不感兴趣,于是预测的分就是0了,就不用计算了。

至于这个最为相似的topK怎么取,我没有仔细研究,可能是约定K为一个常数,可能是定一个阈值,相似度小于这个阈值的就不要了。对于这两者,后者更靠谱一些,具有对称性。



本文链接:http://blog.csdn.net/lingerlanlan/article/details/42656161 本文作者:linger