###################################################################################################
##第一步,建立物品的共现矩阵:对用户分组,找到每个用户所选的物品,单独出现计数,及两两一组计数。
###################################################################################################
##加载plyr和rmr2包
library(plyr)
library(rmr2)
##输入数据文件
train <- read.csv(file="/home/hyxy/Downloads/small.csv",header=FALSE)
names(train) <- c("user","item","pref")
##使用rmr的hadoop格式,hadoop是默认设置
rmr.options(backend='hadoop')
##设置数据到HDFS上
train.hdfs=to.dfs(keyval(train$user,train))
##从hdfs上查看数据
from.dfs(train.hdfs)
#########################################################
##记录重要点:
##train.mr:这是MapReduce任务的key-value信息模型
##key:这是物品向量列表
##value:这是物品联合向量
#########################################################
##MapReduce任务1:物品共现矩阵
train.mr <- mapreduce(
train.hdfs,
map=function(k,v){
keyval(k,v$item)
},
##识别共现物品
reduce=function(k,v){
m <- merge(v,v)
keyval(m$x,m$y)
}
)
##########################################################
##对物品组合列表进行计数,建立物品的同现矩阵。
##定义MapReduce任务,step2.mr被用来计算联合物品的频率。
##Step2.mr:这是MapReduce任务的key-value信息模型
##key:这是物品向量列表
##value:这是数据框value(item,item,Freq)的共现矩阵
##########################################################
##MapReduce函数:计算联合物品频率
step2.mr <- mapreduce(
train.mr,
map=function(k,v){
d <- data.frame(k,v)
d2 <- ddply(d,.(k,v),count)
key <- d2$k
val <- d2
keyval(key,val)
}
)
##########################################################
##第二步,建立用户对物品的评分矩阵
##train2.mr:这是MapReduce任务的key-value信息模型
##key:这是物品向量列表
##value:这是用户物品评分矩阵的值
##########################################################
##MapReduce任务:建立用户对物品的评分矩阵
train2.mr <- mapreduce(
train.hdfs,
map=function(k,v){
df <- v
##物品的key
key <- df$item
##[item,user,pref]的value
val <- data.frame(item=df$item,user=df$user,pref=df$pref)
##颁布(key,value)对
keyval(key,val)
}
)
##从HDFS加载数据
from.dfs(train2.mr)
###########################################################
##以下是合并和共现评分矩阵:
##eq.hdfs:这是MapReduce任务的key-value信息模型
##key:key在这里是NULL
##value:这是合并的数据框值
###########################################################
##运行equi连接两个数据-step2.mr和train2.mr
eq.hdfs <- equijoin(
left.input=step2.mr,
right.input=train2.mr,
map.left=function(k,v){
keyval(k,v)
},
map.right=function(k,v){
keyval(k,v)
},
outer=c("left")
)
##从HDFS加载数据
from.dfs(eq.hdfs)
############################################################
##第三步,生成推荐部分,我们将获得结果的推荐列表
##Cal.mr:这是MapReduce任务的key-value信息模型
##key:这是物品向量列表
##value:这是被推荐的结果的数据框值
############################################################
##MapReduce任务:从equi连接数据中获得被推荐的结果列表
cal.mr <- mapreduce(
input=eq.hdfs,
map=function(k,v){
val <- v
na <- is.na(v$user.r)
if(length(which(na))>0) val <- v[-which(is.na(v$user.r)),]
keyval(val$k.l,val)
},
reduce=function(k,v){
val <- ddply(v,.(k.l,v.l,user.r),summarize,v=freq.l*pref.r)
keyval(val$k1,val)
}
)
##从HDFS加载数据
from.dfs(cal.mr)
############################################################################
##第四步:定义结果:获得被推荐物品相关值得列表,评分进程被应用到推荐结果上
##result.mr:这是MapReduce任务的key-value信息模型
##key:这是用户ID
##value:这是被推荐的结果,数据框value
###################################################################
##MapReduce任务:评分推荐输出
result.mr <- mapreduce(
input=cal.mr,
map=function(k,v){
keyval(v$user.r,v)
},
reduce=function(k,v){
val <- ddply(v,.(user.r,v.l),summarize,v=sum(v))
val2 <- val[order(val$v,decreasing=TRUE),]
names(val2) <- c("user","item","pref")
keyval(val2$user,val2)
}
)
from.dfs(result.mr)
small.csv数据集:
1 | 101 | 5 |
1 | 102 | 3 |
1 | 103 | 2.5 |
2 | 101 | 2 |
2 | 102 | 2.5 |
2 | 103 | 5 |
2 | 104 | 2 |
3 | 101 | 2 |
3 | 104 | 4 |
3 | 105 | 4.5 |
3 | 107 | 5 |
4 | 101 | 5 |
4 | 103 | 3 |
4 | 104 | 4.5 |
4 | 106 | 4 |
5 | 101 | 4 |
5 | 102 | 3 |
5 | 103 | 2 |
5 | 104 | 4 |
5 | 105 | 3.5 |
5 | 106 | 4 |