最近在做mahout源码调用的时候,发现一个参数:startPhase和endPhase,这两个参数是什么意思呢?比如运行RecommenderJob时,可以看到10个MR任务,所以猜测是否是一个phase代表一个MR?
带着这样的疑问进行了实验:
$Hadoop_HOME/bin/hadoop jar mahout-0.7/core/target/mahout-core-0.7-job.jar org.apache.mahout.cf.taste.hadoop.item.RecommenderJob --input input/intro.csv --output date1129/cf00 --tempDir date1129/cftemp00 --booleanData false --similarityClassname SIMILARITY_COOCCURRENCE --startPhase 0 --endPhase 4
但是,实验结果却还是那样,仍然运行了10个MR,然后就去google了,网上看到这个一个观点:The first MR job is index 0. So setting –startPhase 1 will execute the 2nd
job onwards. Putting in –endPhase 2 would stop after the 3rd job. ,来自http://lucene.472066.n3.nabble.com/RowSimilarity-startphase-and-endphase-parameters-td2119682.html。这个的意思其实就是说MR job 和phase是同一个意思,但是我实验后却证明不是这样;
而且网上这个话题比较少涉及到,没办法只能看源码了。
看 mahout的源码可以看到基本的算法Job都继承来AbstractJob这个类,而AbstractJob这个类里面有一个 shouldRunNextPhase方法,这个方法是和startPhase和endPhase这两个参数有关的,所以如果 RecommenderJob里面有这个方法的话,那么应该就可以说startPhase和endPhase两个参数是有作用的;
我没有继 续分析源码了,下面说下我的做法:我在AbstractJob这个类的shouldRunNextPhase里面加入了打印currentPhase和 startPhase,endPhase以及这个方法返回的boolean值,不过这个如果在终端运行(也就是上面提及的在命令行运行)的话,是看不到打 印的内容的。同时也可以不打印,而是选择用log,写入log,不过这个要去slave节点机才能看到,比较麻烦,所以就没有使用Log.
如 何才能打印出结果呢?使用mvn编译mahout的源代码(修改过的),然后在$MAHOUT_SOUCE/core/targe里面有mahout- core-0.7-job.jar文件,把这个文件拷贝到eclipse,然后直接编写代码调用这个jar文件里面的RecommenderJob类就可 以在Console里面看到我们打印的信息了,这样就可以看出来MR Job和phase的区别了。
那么,phase的意义到底是什么呢?其实pahse的含义就是几个MR的一个集合,不定数目的MR job视为一个phase。这个有什么好处呢?比如你运行RecommenderJob时前面的两个phase都运行成功了,但是后面的运行出错,那么是 否要继续从第一个phase开始运行呢,其实完全没有必要,可以设置startPhase和endPhase这两个参数,直接跳过前面两个Phase。
那么回到最开始的问题,为什么我设置了那两个参数,但是却没有作用呢?因为RecommenderJob只有四个phase,而我设置0-4超过了最大值3,所以所有的MR job仍照常运行。
推荐系统相关
- 第一步,利用上面的数据建立一个co-occurrence矩阵。矩阵主要作用是告诉我们2个项目同时被用户购买的发生次数。它基本上是一个以n×n的方形矩阵(n是用户购买的所有项目的总数)。
- 下一步,计算用户购买了哪些项目的向量,以单列矩阵实现。
- 最后一步,把第一步生成的co-occurrence矩阵与用户向量相乘得到推荐数据。我们把最大非零值的项目推荐给用户。
下面让我们来分析一下航班预订系统。当一个用户需要购买到达某地的机票的时候,我们就会基于他之前购买过的航班记录和其他相似乘客的订票记录,给他推荐航班。假设MySQL里面存在这样的数据,我们可以使用sqoop脚本把数据导入到HDFS:
1 |
sqoop import --connect jdbc:mysql: //localhost/reservation --username krishna --password pass123 --table useritem |
在Hadoop中运行以下mashout脚本
1 |
hadoop jar mahout-core- 0.6 -job.jar org.apache.mahout.cf.taste.hadoop.item.RecommenderJob -Dmapred.input.dir=input/input.txt -Dmapred.output.dir=output --usersFile input/users.txt --booleanData --similarityClassname SIMILARITY_COOCCURRENCE |
最后,运行sqoop脚本把分析结果导回到mysql中:
1 |
sqoop export --connect jdbc:mysql: //localhost/reservation --username krishna --password pass123 --table useritem --export-dir useritem/part-m-00000 |