原文链接:http://itzzq.tumblr.com/post/56774167758/r
R语言实现协同过滤算法
library(plyr)
user<-c(1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,5,5)
item<-c(101,102,103,101,102,103,104,101,104,105,107,101,103,104,106,101,102,103,104,105,106)
pref<-c(5.0,3.0,2.5,2.0,2.5,5.0,2.0,2.0,4.0,4.5,5.0,5.0,3.0,4.5,4.0,4.0,3.0,2.0,4.0,3.5,4.0)
train<-data.frame(user,item,pref)
#计算用户列表
usersUnique<-function(){
users<-unique(train$user)
users[order(users)]
}
#计算商品列表方法
itemsUnique<-function(){
items<-unique(train$item)
items[order(items)]
}
# 用户列表
users<-usersUnique()
# 商品列表
items<-itemsUnique()
#建立商品列表索引
index<-function(x) which(items %in% x)
data<-ddply(train,.(user,item,pref),summarize,idx=index(item))
#同现矩阵
cooccurrence<-function(data){
n<-length(items)
co<-matrix(rep(0,n*n),nrow=n)
for(u in users){
idx<-index(data$item[which(data$user==u)])
#每个用户的商品两两出现的集合
m<-merge(idx,idx)
for(i in 1:nrow(m)){
#根据商品的索引找到同现矩阵中的位置进行次数累加
co[m$x[i],m$y[i]]=co[m$x[i],m$y[i]]+1
}
}
return(co)
}
#推荐算法
recommend<-function(udata=udata,co=coMatrix,num=0){
n<-length(items)
# all of pref
pref<-rep(0,n)
pref[udata$idx]<-udata$pref
# 用户评分矩阵
userx<-matrix(pref,nrow=n)
# 同现矩阵*评分矩阵
r<-co %*% userx
# 推荐结果排序
# 把该用户评分过的商品的推荐值设为0
r[udata$idx]<-0
idx<-order(r,decreasing=TRUE)
topn<-data.frame(user=rep(udata$user[1],length(idx)),item=items[idx],val=r[idx])
# 推荐结果取前num个
if(num>0){
topn<-head(topn,num)
}
#返回结果
return(topn)
}
#生成同现矩阵
co<-cooccurrence(data)
#计算推荐结果
recommendation<-data.frame()
for(i in 1:length(users)){
udata<-data[which(data$user==users[i]),]
recommendation<-rbind(recommendation,recommend(udata,co,0))
}
recommendation<-recommendation[which(recommendation$val>0),]
输出结果:
> recommendation user item val 1 1 104 33.5 2 1 106 18.0 3 1 105 15.5 4 1 107 5.0 8 2 106 20.5 9 2 105 15.5 10 2 107 4.0 15 3 103 24.5 16 3 102 18.5 17 3 106 16.5 22 4 102 37.0 23 4 105 26.0 24 4 107 9.5 29 5 107 11.5
具体细节参考:
http://blog.fens.me/rhadoop-mapreduce-rmr/