ItemCF_基于物品的协同过滤_MapReduceJava代码实现思路
2017-03-02 23:34
1236 查看
ItemCF_基于物品的协同过滤
1. 概念
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/f46edd718573325883479f2aae39d52a.jpg)
2. 原理
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/033cfc41906d1bfeac2ca46dddd33a39.jpg)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/d4b464023aeb278f7d584af3993c0dc5.jpg)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/493be4a064d9bdf0a31195771c835c3f.jpg)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/7b20476a43eb9599091ccb860f6e0db5.jpg)
如何给用户推荐?
给用户推荐他没有买过的物品--103
3. java代码实现思路
数据集:![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/c9eef10296ca95226178127c5a84533c.jpg)
第一步:构建物品的同现矩阵
第二步:构建用户的得分矩阵
第三步:同现矩阵*评分矩阵
第四步:拿到最终结果,排序,得到给用户的推荐列表
问题一:物品同现矩阵和用户得分矩阵如何构建?
问题二:矩阵相乘如何来做?
六个MapReduce
step1_第一个MapReduce: 目的-->去重去除数据集中重复的数据第一个MapReduce最终运行的结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/09d6c586bbe684970ae70aeae022312b.png)
Mapper端:key:LongWritable(偏移量) value:一行数据
步骤一:context.write(value, NullWritable.get());
Reducer端:key:一行数据 value:NullWritable
步骤一:context.write(key, NullWritable.get());
step2_第二个MapReduce:目的-->按用户分组,计算所有物品出现的组合列表,得到用户对物品的喜爱度得分矩阵
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/e285d5844e8d71f7c53f40b7886c88c8.jpg)
第二个MapReduce最终运行的结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/6bd1dd0d9fb4f58713a598047ed4f822.png)
Mapper端:key:LongWritable(偏移量) value:i1,u2723,click,2014/9/14 9:31 || i1,u2723,pay,2014/9/14 9:31
步骤一:按照“,”切割,得到item(i1), user(u2723), action(click)
步骤二:构建输出的key和value(key:user, value:item:物品的得分【根据用户action得到】)
步骤三:输出key,value
Reducer端:key:user(u2723)value:{i1:1, i1:2, i3:2}
步骤一:遍历{i1:1, i1:2, i3:2},对于迭代器中的每一个Text(i1:1),按照“:”切割,分别得到item(i1)和action(1),对同一物品的action进行累加,将结果存储到map对象中(map.put(item, action))
步骤二:构建StringBuffer,key:user(u2723),value:{i1:3, i2:4, i3:5}, 并输出
step3_第三个MapReduce:目的-->对物品组合列表进行计数,建立物品的同现矩阵
第三个MapReduce最终运行的结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/18c3a8e938fd757e16ae27f62485d00c.png)
Mapper端:key:LongWritable(偏移量) value:u26 i276:1,i201:1,i348:1,i321:1,i136:1,
步骤一:切割"\t",得到tokens[1]
步骤二:双重for循环,得到每一个物品和其他物品的同现的次数
步骤三:输出,(key=itemA:itemB,value=1)这里只是得到了单用户的物品同现,在Reducer端得到的是所有用户--同一物品对其他物品的同现次数
Reducer端:第一种--key:itemA:itemBvalue:{1,1,1}
步骤一:对Iterable<IntWritable>遍历,统计sum,得到itemA:itemB同现的次数
step4_第四个MapReduce:目的-->把物品同现矩阵和用户得分矩阵相乘
第四个MapReduce最终运行的结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/82c766f7ec9562fde05fbbfdbda924cc.png)
Mapper端:key:LongWritable(偏移量) value: u14 i25:1,i223:1 || i100:i105 1
步骤一:因为Mapper读取了第二次输出(用户得分矩阵)和第三次输出的结果(物品同现矩阵),所以要对maptask所对应的split进行判断,判读所读的数据集属于哪一个,这里采用了重写了setup(Context context)方法,定义了flag来进行标识
步骤二:
如果为同现矩阵(step3)// 样本: i100:i181 1
key:i100 value:A:i181,1 输出
如果为得分矩阵(step2)// 样本: u24 i64:1,i218:1,i100:2,
遍历得分矩阵--key:i100 value:B:u24,2, 输出
Reducer端:key:i100 value: {A:i181,1, A:i180,1 A:i167,3} || {B:u24,2,B:u25,3, B:u26,3}
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/9d5ee0f34e358df74b8b3d7c91aee83a.jpg)
步骤一:因为value中的A:B:标识同现矩阵,得分矩阵
val.startWith("A:")
某一个物品i100,针对它和其他物品的同现次数,存在mapA-->value: {A:i181,1, A:i180,1 A:i167,3} mapA.put(i181,1),map.put(i180,1)...
val.startWith("B:")
该物品(key中的itemID),所有用户的推荐权重分数mapB--{B:u24,2,B:u25,3, B:u26,3}
mapB.put(u24,2),mapB.put(u25,3)...
步骤二:进行矩阵相乘运算,对于物品i100,它的同现商品以及对应的次数存放到了mapA,而物品对于i100,所有用户的评分已经存放到了mapB,只需要遍历mapA,将其中同现的每一个商品乘以对应的mapB中每一个用户对i100的评分
步骤三:输出,key=userId, value=itemId,result (u24 i101,8.0)
step5_第五个MapReduce:目的-->把相乘后的矩阵相加,获得结果矩阵
第五个MapReduce最终运行的结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/f131a3777eeae606b2007babefd3ec80.png)
Mapper端:key:LongWritable(偏移量) value:u13 i9,5.0
步骤一:key=u13,value=i9,5.0 输出
Reducer端:key:u13 value:{i101,2.0, i103,4.5, i101, 5.7}
步骤一:利用map对同一itemId矩阵求和
步骤二:输出,key=userId, value=itemId,score(样本: u13 i9,5.0)
step6_第六个MapReduce:目的-->按照推荐得分降序排序,取前十条(二次排序)
第六个MapReduce最终运行的结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/55617b5c0e307b8c7d3074b3b8ea6549.png)
Mapper端:key:LongWritable(偏移量) value:u13 i9,5.0
步骤一:将用户id,物品和得分封装到一个对象
PairWritable,
步骤二:输出,key:(PairWritable) value:(item:num)
Shuffle中Sort:
注意:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/a3af3850f58601a4dcff6b0dad9cc4b9.png)
重写compare()方法,先比较Uid,相等的话,再比较Num
Shuffle中Group:
注意:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202003/24/24aba54c36e7d21d48144d0312dd3e93.png)
重写compare()方法,Uid相同的为一组
Reducer端:key: PairWritable value:Text{i160:58.0,i352:9.0,i192:8.0,i455:7.0...}
步骤一:取前十个,利用StringBuffer拼接
步骤二:输出,key=uid,value=sb.toString()
相关文章推荐
- TF-IDF_MapReduceJava代码实现思路
- 基于物品的协同过滤ItemCF的mapreduce实现
- TF-IDF_MapReduceJava代码实现思路
- PageRank_网页排名_MapReduceJava代码实现思路
- mapreduce实现ItemCF——基于物品的协同过滤
- 基于物品的协同过滤算法itemCF原理及python代码实现
- 基于物品的协同过滤ItemCF的mapreduce实现
- 基于用户的协同过滤和基于物品的协同过滤推荐算法原理和实现
- 通过mapReduce实现基于项目的协同过滤推荐
- 数据挖掘笔记-基于用户协同过滤推荐的简单实现
- 基于jquery的选择标签至文本域效果,可多选/可过滤重复/可限制个数的实现代码
- Java 图片压缩实现思路及代码
- MapReduce:基于物品的协同过滤算法的MapReduce实现
- 基于Java实现的Base64加密、解密原理代码
- 基于物品的协调过滤算法(ItemCF)
- 基于水平投影,垂直投影的字符图像分割思路和代码实现
- java基于swing实现的五子棋游戏代码
- 用Java实现断点续传的基本思路和代码
- 快速构建基于代码级性能测试方法的一种思路和简单实现
- 基于数论变换的大整数乘法Java代码实现