ItermCF的MR并行实现
ItermCF的MR并行实现
@(Hadoop)
ItermCF的基本思想
基于物品相似度的协同过滤推荐的思想大致可分为两部分:
1.计算物与物之前的相似度
2.根据用户的行为历史,给出和历史列表中的物品相似度最高的推荐
通俗的来讲就是:
对于物品 A,根据所有用户的历史偏好,喜欢物品 A 的用户都 喜欢物品 C,得出物品 A 和物品 C 比较相似,而用户 C 喜欢物品 A,那么可以推断出 用户 C 可能也喜欢物品 C。
ItermCF的算法实现思路
对于以下的数据集:
| UserId | ItermId | Preference | 
|---|---|---|
| 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 | 
| 6 | 102 | 4 | 
| 6 | 103 | 2 | 
| 6 | 105 | 3.5 | 
| 6 | 107 | 4 | 
用户评分矩阵
首先可以建立用户对物品的评分矩阵,大概长这个样子:
列为UserId,行为ItermId,矩阵中的值代表该用户对该物品的评分。
从列的方向看,该矩阵的每一个列在mr程序中可以用一行简单的字符串来表示:
1   101:5,102:3,103:2.5 ...   
这样一来,上面的矩阵5个列就可以由5行类似的字符串来构成。 
那么第一个mr任务的功能就是一个简单的数据转换过程:
1.输入的key为行偏移量,value为每行内容,形如:1,101,5.0
2.在map阶段,分割每行内容,输出的key为1,value为101:5.0
3.在reduce阶段,将UserId相同的所有评分记录进行汇总拼接,输出的key仍然为1,value形如:101:5,102:3,103:2.5 …
如此一来通过第一个mr任务得到了用户的评分矩阵。
物品同现矩阵
该矩阵大概长这个样子:
矩阵的值表示,两个物品同时被用户喜欢(评过分)的次数,例如:101和102这个组合被1,2,5三个用户喜欢过,那么在矩阵中101和102对应的值就是3。
这个矩阵的意义就是各个物品之间的相似度,为什么可以这么说? 
如果两个物品经常同时被很多用户喜欢,那么可以说这两个物品是相似的,同时被越多的用户喜欢(即为通同现度,上面矩阵中的值),这两个物品的相似度就越高。 
其实观察可以发现,行和列上相同的(比如101和101)相比其他值(比如101和102,101和103)都是最大的,因为101和101就是同一个物品,相似度肯定是最大的。
从列的方向上看,这个同现矩阵的每一列在mr程序中可以通过下面简单的字符串来表示:
101:101 5
101:102 3
101:103 4
...
m*n的同现矩阵就由m个以上的字符串(n行)组成。
那么第二个mr任务的功能就是在第一个mr任务的输出结果上得到物品同现矩阵:
1.输入的key为偏移量,输入的value为UserId+制表符+ItermId1:Perference1,ItermId2:Perference2…
2.输入的value中,UserId和Perference是不需要关心的,观察物品的同现矩阵,map阶段的工作就是将每行包含的ItermId都解析出来,全排列组合作为key输出,每个key的value记为1。
3.在reduce阶段所做的就是根据key对value进行累加输出。
如此一来便能够得到物品的同现矩阵。
物品同现矩阵和用户评分矩阵的相乘
物品同现矩阵*用户评分矩阵=推荐结果:
为什么两个矩阵相乘可以得到推荐结果? 
物品1和各个物品的同现度*用户对各个物品的喜好度,反应出用户对物品1的喜好度。
例如,要预测用户3对103物品的喜好度,我们需要找到和103相似的物品,比如101物品,和103的同现度为4,是很类似的物品,用户3对101的评分为2,那么一定程度上可以反映出用户对103的喜好度,101和103的相似度(即同现度)*用户3对101的评分可以得到用户3对103的喜好度权重,将用户3对各个物品的权重相加,可以反映出用户3对103的喜好度。
了解矩阵相乘的意义之后,第三个mr任务的功能就是实现两个矩阵的相乘,并将结果输出。
在这个mr任务中,这两个矩阵的相乘可以这样来计算:
将同现矩阵存入一个Map中,形如:
Map<String, Map<String, Double>> colItermOccurrenceMap = new HashMap<String, Map<String, Double>>();
同现矩阵中的每一行就是大Map中的一条记录,每行对应的每列都在该记录的小Map中。
在map阶段的开始的时候初始化这个Map,输入的value形如101:101 5,101:102 3,将101作为大Map的key,value为小Map,小Map的key为101/102,value为5/3。
由于map函数读取文件是并发读取的,不能保证两个输入文件的读取顺序(在同一个文件中也不能保证),所以这里使用Hadoop提供的分布式缓存机制来对同现矩阵进行共享。
关于Hadoop的分布式缓存机制请看: 
Hadoop的DistributedCache机制
初始化同现矩阵之后,读取评分矩阵的每一行,输入的value为1 101:5,102:3,103:2.5 … 
将每行的itermIds和对应的评分数提取出来,遍历itermId,根据itermId到itermOccurrenceMap中找到对应的List集合,找到每个itermId在该集合中对应的itermId2记录,将评分数*同现度,之后进行累加,以UserId:ItermID作为key,累加值作为value输出。
reduce的工作就很简单了,根据key对value进行累加输出即可。
项目代码
作者:@小黑
ItermCF的MR并行实现的更多相关文章
- Kafka (一)
		
使用Kafka最新版本0.9 Kafka 配置 1. 安装 首先需要安装Java,推荐安装Java8,不然会出现一些莫名其妙的错误 kafka_2.11-0.9.0.0.tgz tar -xzf ka ...
 - Hive2.2.1概述(待重写)
		
概述 hive 是一个包裹着 hdfs 的壳子,hive 通过 hql,将 sql 翻译成 MR ,进行数据查询. Hive是⼀个构建在Hadoop之上的数据仓库 hive的数据存在hdfs上,元信息 ...
 - 为集群配置Impala和Mapreduce
		
FROM: http://www.importnew.com/5881.html -- 扫描加关注,微信号: importnew -- 原文链接: Cloudera 翻译: ImportNew.com ...
 - requirejs:性能优化-及早并行加载
		
为了提高页面的性能,通常情况下,我们希望资源尽可能地早地并行加载.这里有两个要点,首先是尽早,其次是并行. 通过data-main方式加载要尽可能地避免,因为它让requirejs.业务代码不必要地串 ...
 - 串行移位锁存并行输出可级联器件74HC595
		
一.背景 老同学今天突然咨询关于74HC595,自己没用过,同学说可以级联10级!10级?我艹,这么叼,级联又是 什么鬼,这勾起了我极大兴趣,二话不说,手册down下来研究,并在此做个记录. 二.正文 ...
 - Java:并行编程及同步使用方法
		
知道java可以使用java.util.concurrent包下的 CountDownLatch ExecutorService Future Callable 实现并行编程,并在并行线程同步时,用起 ...
 - (九)串行口方式0 拓展并行输出端口 02    74LS164芯片
		
1.先讲解74LS164 移位芯片: 74HC164.74HCT164 是 8 位边沿触发式移位寄存器,串行输入数据,然后并行输出. 数据通过两个输入端(DSA 或 DSB)之一串行输入:任一输入端可 ...
 - SQL Server并行死锁案例解析
		
并行执行作为提升查询响应时间,提高用户体验的一种有效手段被大家所熟知,感兴趣的朋友可以看我以前的博客SQL Server优化技巧之SQL Server中的"MapReduce", ...
 - 基于MongoDB分布式存储进行MapReduce并行查询
		
中介绍了如何基于Mongodb进行关系型数据的分布式存储,有了存储就会牵扯到查询.虽然用普通的方式也可以进行查询,但今天要介绍的是如何使用MONGODB中提供的MapReduce功能进行查询. ...
 
随机推荐
- 关于在vue里使用脚手架空行、空格会报错的问题
			
第一种方法: 重新用脚手架安装项目,在命令行里选择Use ESLint to lint your code?这项是输入 n 第二种方法: 找到build文件夹下的 webpack.base.conf ...
 - 《java虚拟机》----虚拟机字节码执行引擎
			
No1: 物理机的执行引擎是直接建立在处理器.硬件.指令集合操作系统层面上的,而虚拟机的执行引擎则是由自己实现的,因此可以自行制定指令集与执行引擎的结构体系,并且能够执行那些不被硬件直接支持的指令集格 ...
 - EOJ 3261 分词
			
字典树,$dp$. 记录$dp[i]$为以$i$为结尾获得的最大价值.枚举结尾一段是哪个单词,更新最大值.可以将字典中单词倒着建一棵字典树. 这题数据有点不严谨. 下面这组数据答案应该是负的. 3 a ...
 - SQL Server附加数据库提示“版本为661,无法打开,支持655版本……”
			
在我们使用别人导出的数据库的时候,有时候我们会通过附加数据库的方法,把别人导出的数据库附加到我们的电脑中,这时,或许你会遇到这种问题,附加时,提示版本为XXX,无法打开,支持AAA版本. 这是怎么回事 ...
 - 【BZOJ1098】[POI2007]办公楼biu
			
题目一开始看以为和强联通分量有关,后来发现是无向边,其实就是求原图的补图的联通块个数和大小.学习了黄学长的代码,利用链表来优化,其实就是枚举每一个人,然后把和他不相连的人都删去放进同一个联通块里,利用 ...
 - 【推导】zoj3981 Balloon Robot
			
题意:一个桌子有m个位置(首尾相接),有n支队伍坐在其中的n个位置上.有个机器人会从某个起始位置出发,每个时刻会依次发生以下三个事件: 机器人顺时针转一个单位: 某些队伍通过了题目(如果存在): 如果 ...
 - 权限验证AuthorizeAttribute
			
/// <summary> /// 权限验证属性. /// </summary> public class AuthorizeExAttribute : AuthorizeAt ...
 - codevs 1060 搞笑运动会 dp
			
1060 搞笑世界杯 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codevs.cn/problem/1060/ Description ...
 - 把json格式的字符串转换成javascript对象或数组
			
第一种 JSON.parse(jsonString) 第二种 eval("("+jsonString+")") 第三种 var obj=(function ...
 - 读书笔记_Effective_C++_条款二十八:避免返回handlers指向对象内部成分
			
举个例子: class Student { private: int ID; string name; public: string& GetName() { return name; } } ...