###################################################################################################
##第一步,建立物品的共現矩陣:對用戶分組,找到每個用戶所選的物品,單獨出現計數,及兩兩一組計數。
###################################################################################################
##加載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 |