基于Item的推荐系统-使用RHadoop运算

来源:互联网 发布:巨人网络 神魔 编辑:程序博客网 时间:2024/05/18 00:33

一、基本想法

    基于物品的推荐系统是基于用户对物品的偏好找到相似的物品,然后根据用户的历史偏好,推荐相似的物品给他。从计算的角度来看,就是将所有用户对某个物品的偏好作为一个向量来计算物品之间的相似度,得到物品的相似物品后,根据用户历史的偏好预测当前用户还没有表示偏好的物品,计算得到一个排序的物品列表作为推荐。

 

二、算法

    Item-based 推荐系统根据用户对相似物品的评分预测目标物品的评分,然后给用户推荐预测评分值最高的Top-N个物品。

  • 这个过程有三个步骤:

1.构建用户—物品评分矩阵

2.寻找目标物品的若干个最近邻居-建立相似矩阵

3.预测目标物品的评分,并向用户产生推荐

本文使用Rhadoop进行运算,并以Mahout in Action一书中的small.csv数据集测试,得出以下结果:

 

表一:推荐结果

用户(user)

物品(item)

价值(value)

1

104

33.5

2

106

20.5

3

103

24.5

4

102

37.0

5

107

11.5

 

 

三、特点

1.以用户的角度而言,基于物品的推荐系统所推荐的物品一般都和用户过去所喜爱的商品内容或特性高度相似,很难开发出用户潜在的喜好,多样性较差。

2. 以系统的多样性(覆盖率)而言,基于物品的推荐系统的多样性好于基于用户的推荐系统, 因为基于用户的推荐系统总是倾向于推荐热门的商品,而基于物品的推荐系统由于用户本身的多样性,总和来看其推荐的商品较具新颖性。

3.对于一个商城网站(例如亚马逊、京东),其物品的增长速度远不如用户的增长速度,且物品之间的相似性远不如用户之间的相似性那么敏感,同时物品的数据相对稳定,因此可以离线完成工作量最大的相似性计算步骤,从而大大降低了在线计算量,提高推荐效率。

4. 基于物品的推荐系统有一个基本假设,就是用户会喜欢和他以前喜欢的东西相似的东西,因此用户若不符合这个基本假设,推荐对于用户便失去作用。

 

 

四、推荐决策建议

因此使用上主要考虑如下问题:

1.用户是否对该领域有固定长期的兴趣

2.用户的规模

3.物品的规模

4.新增用户的速度

5.新增物品的速度

6.实时性要求

 

 

 

五、用处

    基于Item的推荐系统是当今很多大型网站都在采用的核心算法之一。比如在购书网站上,当你看一本书的时候,推荐引擎会给你推荐相关领域的书籍,在这样的情况下,基于物品的推荐系统便成为了引导用户浏览的重要手段。

    以我在京东购物的经验而言,我所查看、关注及放入购物车的商品,都会出现在往后京东的广告上。这样的推荐系统有好有坏,好处是如果我一直都需要这个商品,这样的广告就对我有提醒作用,如果我非常喜爱某样商品,在不断看到这个商品的情况下,我也可能抵挡不了强烈的购买欲望。但就反面来看,如果我已在经过比较的情形下买了某一牌的产品,推荐广告却一再出现我已不再需要的他牌相似商品,此刻就会令消费者感到厌烦;如果我是一个喜爱尝鲜、喜好广泛、喜新厌旧的消费者,同样基于商品的推荐系统就不能满足我的需求。因此,好的推荐引擎应该视实际情况将基于商品及基于用户的推荐混合使用。

 

六、实际操作步骤及代码

1.安装Hadoop

2..安装R

3安装RHadoop

 

 

# 载入rmr2

library (rmr2)

 

# 加载数据

train <-read.csv (file = "small.csv", header = FALSE)

names (train) <-c ("user", "item","pref")

 

# 使用hadoop rmr格式

rmr.options (backend = 'hadoop')

 

# 将数据转成HDFS

train.hdfs = to.dfs (keyval (train$user, train))

from.dfs (train.hdfs)

 

#相似矩阵-mapreducejob1

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_function计算商品组和频率

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)

  }

)

#从HDFS加载数据

from.dfs(step2.mr)

 

#MapReducejob2建立用户-商品得分矩阵

train2.mr <-mapreduce (

  train.hdfs,

  map = function(k, v) {

    # Df <- v[which (v$user== 3),]

    df <- v

    key <-df $ item#item为KEY

    val <-data.frame (item= df$item, user = df$user, pref = df$pref)#(item,偏好)为value

    keyval(key, val)

  }

)

from.dfs(train2.mr)

 

#运行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")

)

from.dfs (eq.hdfs)

 

#mapreduce_job从equijoined数据中获取推荐结果列表

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$kl, val)

  }

  , Reduce = function (k, v) {

    val <-ddply (v,. (kl,vl, user.r), summarize, v = freq.l * pref.r)

    keyval (val $ kl, val)

  }

)

from.dfs (cal.mr)

 

#mapereduce_job对推荐结果排序

result.mr <-mapreduce (

  input = cal.mr,

  map = function (k, v) {

    keyval (v $ user.r, v)

  }

  , Reduce = function (k, v) {

    val <-ddply (v,.(user.r, vl), 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)

0 0
原创粉丝点击