mahout基于Hadoop的CF代码分析(转)
来自:http://www.codesky.net/article/201206/171862.html
mahout的taste框架是协同过滤算法的实现。它支持DataModel,如文件、数据库、NoSQL存储等,也支持Hadoop的MapReduce。这里主要分析的基于MR的实现。
基于MR的CF实现主要流程就在 org.apache.mahout.cf.taste.Hadoop.item.RecommenderJob类中(注意mahout有两个 RecommendJob,要看清楚是哪一个包)。这 个类的run方法就包含了所有的步骤。从上到下,完整的其实有10步(中间计算item相似度其实拆分成了3个job,我们也当做是一个phase吧), 也就是说,如果指定了所有的必要参数,运行一次item-based CF算法,会执行12个JOB,当然有的步骤是可以忽略的,下面会讲。以下就是详细的每一步骤的分析:
phase1: itemIDIndex
这步主要是将itemId转成一个int。这里设计上其实有点小问题,如果item的数量非常多,比如超过int的最大值,那就有可能会出现重合了。所以用long其实更为合适。
input:用户评分文件(这也是我们最原始的输入了),格式一般为:userId t itemId t score。注意输入必须是textfile的。可能是为了方便测试吧,mahout的很多包默认输出都是textfile格式的。
map:(index, itemId)
reduce: (index, itemId)
phase2: toUserVector
input:用户评分文件
param: --userBooleanData如果这个参数为true,则会忽略评分列,对于买或不买这类数据有时需要指这定这个值。
map: (userId, itemId,pref)
reduce: 以用户为key,输出成向量形式è (userId, VectorWritable<itemId, pref>)
phase3: countUser,计算用户数
map: (userId)
reduce: 输出总用户数count
phase4: maybePruneAndTranspose
input: phase2的输出:userVector
param: --maxCooccurrences
map: (userId,Vector<itemId, pref>) è(itemId,DistributedRowMatrix<userId,pref>),注意如果指定了—maxCooccurrences参数,这里会有裁剪,www.codesky.net 每个userId最多对maxCooccurrences的itemId打分
这里的DistributedRowMatrix,分布式行矩阵:行:itemId, 列:userId
reduce: (itemId, VectorWritable<userId,pref>)
phase5: RowSimilarityJob
这一步比较关键,计算item相似度,它拆分成了三个JOB。
param: --numberOfColumns, --similarityClassname,--maxSimilaritiesPerRow(默认:100)
job1:weight
input:phase4的输出
map: (itemId, VectorWritable <userId, pref>) ==>(userId, WeightedOccurrence<itemId, pref, weight>)
这里的weight,对于欧氏向量距离,或者Pearson距离等,均为Double.NaN,即无效。在LoglikelihoodVectorSimilarity中有用到weight的值。
reduce:(userId, WeightedOccurrenceArray<itemId, pref, weight>)
job2:pairwise similarity *item相似度计算*
map: 对同一用户的所有item-rating,输出两两item之间的关系 ==>(WeightedRowPair<itemA, itemB, weightA, weightB>, coocurrence<userId,valueA, valueB>) (同上,这里的权重weightA,B对于欧氏距离等可以忽略)
reduce: 在这端,以<itemA,itemB>为key聚合了来自不同map的所有用户的 打分,最后输出itemA和B的对称相似度(即以itemA为key或以itemB为key)==> (SimilarityMatrixEntryKey<itemA,similarity>, MatrixEntryWritable<WeightedRowPair<itemA, itemB,weightA, weightB>>) , (SimilarityMatrixEntryKey<itemB,similarity>, MatrixEntryWritable<WeightedRowPair<itemB, itemA,weightB, weightA>>)
job3:entries2vectors *汇总item的相似items*
param: --maxSimilaritiesPerRow
map: (itemA, itemB, similarity) & (itemB,itemA, similarity) 这里在group的时候按相似度降序做了排序,如果有--maxSimilaritiesPerRow参数,则会做裁剪。
reduce: (itemA, VectorWritable <item,similarity>)
至此,item相似度计算完毕。
phase6: prePartialMultiply1
input: phase5的最后输出(即item相似度)
map: 直接输出item对应的相似items,这里用VectorOrPrefWritable做了封装,表明有可能是相似度向量,也有可能是对item的打分,并且对item为自己的,将相似度设为Double.NaN,以过滤自身。è(itemId,VectorOrPrefWritable<item, similarity>)
reduce: IdentityReducer
phase7: prePartialMultiply2
input: phase2的输出userVectors
map: 输出:(itemId, VectorOrPrefWritable<userId, pref>)
这里默认考虑用户对10个item的评分,可以通过maxPrefsPerUserConsidered参数调整。
如果指定了usersFile,则在setup时会把所有的userId读入内存,用于过滤。如果map输入数据的userID不在usersFile中,则会被忽略。注意,这是mahout的设计bug,对于比较大的数据集,很有可能造成OOM(事实上在我的测试程序中已经出现OOM了…),这种bug下面还会出现。输出的是用户的评分,同phase6的VectorOrPrefWritable的封装。
reduce: IdentityReducer
phase8: partialMultiply
input: 6和7的输出:prePartialMultiply1, prePartialMultiply2
map: Identity。由于6和7的输出的key均为itemId,因而在reduce端同一item的相似item以及对应的用户评分会聚合到一起。
reduce:(itemId, VectorAndPrefsWritable<similarityMatrix, List<userId>,List<pref>>) 没做特殊处理,直接合在一起,输出相似度矩阵,所有的userId及对item的打分。
phase9: itemFiltering
将过滤文件输出成<userId, itemId>。如果指定了--filterFile参数,则在最后的聚合推荐中会过滤userId对应的items。这一步在实际中多数是可以忽略的,只要不指定这个参数即可。
phase10: aggregateAndRecommend
map: 对每个用户,输出对当前item的评分,以及与当前item的所有相似 itemsè(userId, PrefAndSimilarityColumnWritable<pref,vector<item, similarity>>)
reduce: 聚合了这个用户所有的评分历史,以及相似items,计算对该用户的推荐结果 è (userId, List<itemId>)。
注意在reduce的setup中,会将phase1产生的所有itemId到index的映射读入内存,这里只要Item数据集稍大,就会OOM。这是比较严重的设计bug。
事实上,如果item是正规的整数,而不是guid之类的,phase1和这一步的读入内存是完全可以略掉的。这样的话 就完全可以在企业级的数据集上使用(我的测试数据集是15亿+的user-item-rating,1.5亿+的用户,在最后这一步挂掉了,前面所有 phase都能跑成功)。
至此,已经形成了推荐结果,CF完成。
以上的所有步骤中,phase5的计算item相似度是最慢的(这个其实也很直觉)。
mahout基于Hadoop的CF代码分析(转)的更多相关文章
- 【Machine Learning】Mahout基于协同过滤(CF)的用户推荐
一.Mahout推荐算法简介 Mahout算法框架自带的推荐器有下面这些: l GenericUserBasedRecommender:基于用户的推荐器,用户数量少时速度快: l GenericI ...
- Hive -- 基于Hadoop的数据仓库分析工具
Hive是一个基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库 ...
- 【转】阿里巴巴技术专家杨晓明:基于Hadoop技术进行地理空间分析
转自:http://www.csdn.net/article/2015-01-23/2823687-geographic-space-base-Hadoop [编者按]交通领域正产生着海量的车辆位置点 ...
- 基于hadoop分析,了解hive的使用
一.Hadoop理论 Hadoop是一个专为离线和大规模数据分析而设计的,并不适合那种对几个记录随机读写的在线事务处理模式. Hadoop=HDFS(文件系统,数据存储技术相关)+ Mapreduce ...
- 开源项目kcws代码分析--基于深度学习的分词技术
http://blog.csdn.net/pirage/article/details/53424544 分词原理 本小节内容参考待字闺中的两篇博文: 97.5%准确率的深度学习中文分词(字嵌入+Bi ...
- Hadoop基础-HDFS数据清理过程之校验过程代码分析
Hadoop基础-HDFS数据清理过程之校验过程代码分析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 想称为一名高级大数据开发工程师,不但需要了解hadoop内部的运行机制,还需 ...
- mahout demo——本质上是基于Hadoop的分步式算法实现,比如多节点的数据合并,数据排序,网路通信的效率,节点宕机重算,数据分步式存储
摘自:http://blog.fens.me/mahout-recommendation-api/ 测试程序:RecommenderTest.java 测试数据集:item.csv 1,101,5.0 ...
- (转)基于FFPMEG2.0版本的ffplay代码分析
ref:http://zzhhui.blog.sohu.com/304810230.html 背景说明 FFmpeg是一个开源,免费,跨平台的视频和音频流方案,它提供了一套完整的录制.转换以及流化音视 ...
- 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)
构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...
随机推荐
- Step Detector and Step Counter Sensors on Android
Step Detector and Step Counter Sensors on Android 时间 2014-03-31 11:56:00 Tech Droid 原文 http://techd ...
- ASP.NET :Virtual Application vs Virtual Directory
原文地址:http://blogs.msdn.com/b/wenlong/archive/2006/11/22/virtual-application-vs-virtual-directory.asp ...
- ArrayList的总结
1.ArrayList的特点 主要特点:按照插入顺序来保存元素,可以利用下标来查找值 2.ArrayList的优点: 按照下标访问元素最快 3.ArrayList的缺点: 在中间插入元素很慢 删除元素 ...
- PyCharm 配置远程python解释器
配置过程 本机环境 操作系统:win10 IDE:Pycharm 远程服务器 操作系统:ubuntu14.04 配置了ssh,可以使用ssh进行远程登陆 配置Deployment 首先,在pychar ...
- 使用Bootstrap后,关于IE与Chrome显示字体的问题
在做日志系统时,使用了Bootstrap,然后通过浏览器查看的页面效果如下 对比可以看到,同样的字体,IE显示的圆润些,而Chrome字体则丑很多.因为Chrome默认用宋体 在http://v3.b ...
- 基于JAVA原生HTTP请求工具类 httphelper
原文地址;http://lushuifa.iteye.com/blog/2313896 import java.io.BufferedReader; import java.io.BufferedWr ...
- 数据库savepoint
保存点(savepoint)是事务过程中的一个逻辑点,我们可以把事务回退到这个点,而不必回退整个事务. 语法 编辑 savepoint savepoint_name 这个命令就是在事务语句之间创建一个 ...
- Oracle简单的备份和恢复-导出和导入(2)
ylbtech-Oracle:Oracle简单的备份和恢复-导出和导入(2) 简单的备份和恢复-导出和导入(2) 1. 用户导入导出文件中的一张表(emp)返回顶部 0.1, 我们在sql plus中 ...
- Binary Tree Maximum Path Sum leetcode java
题目: Given a binary tree, find the maximum path sum. The path may start and end at any node in the tr ...
- CentOS 6和CentOS 7防火墙的关闭
CentOS6.5查看防火墙的状态: 1 [linuxidc@localhost ~]$service iptable status 显示结果: 1 2 3 4 5 [linuxidc@localho ...