注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

anqiang专栏

不要问细节是怎么搞的,源码说明一切

 
 
 

日志

 
 

Mahout分布式推荐引擎源码分析  

2010-03-02 00:45:37|  分类: Hadoop & Mahout |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

上一节介绍了基本原理,这里我将代码展示跟大家。最新以及以前版本的源码都可以在http://svn.apache.org/repos/asf/lucene/mahout/trunk这个SVN地址下载。这是我这段时间看源码的一个新发现。以前都是将代码倒来倒去,显得非常繁琐。

 

我在这里分析的是Mahout 1.0版本中的代码,这个代码支持0.19版本的hadoop。感兴趣的可以去看看Mahout 2.0的代码。

 

根据上篇文章我们知道,解决这个推荐问题的方法可以有两种,一种直接在Map中进行计算,这种方法时就不需要Reduce了。Mahout就是这样实现的。但是我不知道它是否会出现Map分布均衡的问题,但愿不会。希望大家使用Mahout的时候,注意这个问题,如果不小心的话,单个Map节点的压力就会过大。

 

 

@Override

  public void map(LongWritable key,

                  Text value,

                  OutputCollector<Text, RecommendedItemsWritable> output,

                  Reporter reporter) throws IOException {

    //从这里我们知道,其实需要找相似对象的userIDS都是以每行一个userID的形式放在HDFS上的

      String userID = value.toString();

    List<RecommendedItem> recommendedItems;

    try {

    //使用推荐引擎对每一个userID进行处理,

      recommendedItems = recommender.recommend(userID, recommendationsPerUser);

    } catch (TasteException te) {

      throw new RuntimeException(te);

    }

    RecommendedItemsWritable writable = new RecommendedItemsWritable(recommendedItems);

    output.collect(new Text(userID), writable);

    reporter.incrCounter(ReducerMetrics.USERS_PROCESSED, 1L);

    reporter.incrCounter(ReducerMetrics.RECOMMENDATIONS_MADE, recommendedItems.size());

  }

 

  @Override

  public void configure(JobConf jobConf) {

    String dataModelFile = jobConf.get(DATA_MODEL_FILE);

    String recommenderClassName = jobConf.get(RECOMMENDER_CLASS_NAME);

    FileDataModel fileDataModel;

    try {

      FileSystem fs = FileSystem.get(jobConf);

      //hadoop上的数据文件拷贝到本地

      File tempDataFile = File.createTempFile("mahout-taste-hadoop", "txt");

      tempDataFile.deleteOnExit();

      fs.copyToLocalFile(new Path(dataModelFile), new Path(tempDataFile.getAbsolutePath()));

      //构建数据模型

      fileDataModel = new FileDataModel(tempDataFile);

    } catch (IOException ioe) {

      throw new RuntimeException(ioe);

    }

    try {

    /**

     * 通过数据模型构建推荐引擎,整个过程中将会把数据模型中的数据全部导入到内存中去,

     * 这个对内存的依赖是可想而知的了。

     * 不过根据笔者的经验看,只要是推荐引擎Item的维度控制的够好,一般还是可以正常在Hadoop上运行的

     */

      Class<? extends Recommender> recommenderClass = Class.forName(recommenderClassName).asSubclass(Recommender.class);

      Constructor<? extends Recommender> constructor = recommenderClass.getConstructor(DataModel.class);

      recommender = constructor.newInstance(fileDataModel);

    } catch (NoSuchMethodException nsme) {

      throw new RuntimeException(nsme);

    } catch (ClassNotFoundException cnfe) {

      throw new RuntimeException(cnfe);

    } catch (InstantiationException ie) {

      throw new RuntimeException(ie);

    } catch (IllegalAccessException iae) {

      throw new RuntimeException(iae);

    } catch (InvocationTargetException ite) {

      throw new RuntimeException(ite.getCause());

    }

    recommendationsPerUser = Integer.parseInt(jobConf.get(RECOMMENDATIONS_PER_USER));

  }

 

后面有机会我会对推荐引擎内部实现原理或者其它的分布式数据挖掘算法做一些简单介绍。
  评论这张
 
阅读(1006)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017