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

anqiang专栏

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

 
 
 

日志

 
 

BayesTfIdfMapper  

2010-04-06 16:43:31|  分类: Hadoop & Mahout |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

import java.io.IOException;

import java.util.HashMap;

import java.util.Map;

 

import org.apache.hadoop.io.DefaultStringifier;

import org.apache.hadoop.io.DoubleWritable;

import org.apache.hadoop.mapred.JobConf;

import org.apache.hadoop.mapred.MapReduceBase;

import org.apache.hadoop.mapred.Mapper;

import org.apache.hadoop.mapred.OutputCollector;

import org.apache.hadoop.mapred.Reporter;

import org.apache.hadoop.util.GenericsUtil;

import org.apache.mahout.common.StringTuple;

import org.apache.mahout.math.map.OpenObjectDoubleHashMap;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

/**

 * Naive Bayes Tfidf Mapper. Calculates per document statistics

 *

 */

public class BayesTfIdfMapper extends MapReduceBase implements

    Mapper<StringTuple,DoubleWritable,StringTuple,DoubleWritable> {

 

  private static final Logger log = LoggerFactory.getLogger(BayesTfIdfMapper.class);

 

  private static final StringTuple VOCAB_COUNT = new StringTuple(BayesConstants.FEATURE_SET_SIZE);

 

  private static final DoubleWritable ONE = new DoubleWritable(1.0);

 

  private final OpenObjectDoubleHashMap<String> labelDocumentCounts = new OpenObjectDoubleHashMap<String>();

 

  /**

   * We need to calculate the Tf-Idf of each feature in each label

   *

   * 这里的IDF是用料当前这个特征在特定类别下的IDF进行计算,原则上说是有问题的。

   * 但是这里为了使其与TFkey label, word)相搭配,所以使用了这种方式,不管怎么样,还是需要引起注意的

   *

   * @param key

   *          The label,feature pair (can either be the freq Count or the term Document count

   */

  @Override

  public void map(StringTuple key,

                  DoubleWritable value,

                  OutputCollector<StringTuple,DoubleWritable> output,

                  Reporter reporter) throws IOException {

   

    if (key.length() == 3) {

      if (key.stringAt(0).equals(BayesConstants.WEIGHT)) {

        reporter.setStatus("Bayes TfIdf Mapper: Tf: " + key);

        //得到TF

        output.collect(key, value);

      } else if (key.stringAt(0).equals(BayesConstants.DOCUMENT_FREQUENCY)) {

        String label = key.stringAt(1);

       

        //获得当前类别中的文档数量

        Double labelDocumentCount = labelDocumentCounts.get(label);

        double logIdf = Math.log(labelDocumentCount / value.get());

        key.replaceAt(0, BayesConstants.WEIGHT);

        //在这里将DOCUMENT_FREQUENCY转换为了WEIGHT便于后面 TF*Log(IDF)

        output.collect(key, new DoubleWritable(logIdf));

        reporter.setStatus("Bayes TfIdf Mapper: log(Idf): " + key);

      } else {

        throw new IllegalArgumentException("Unrecognized Tuple: " + key);

      }

    } else if (key.length() == 2) {

    //BayesFeatureMapper Reducer中计算的Feature_Count是一个和值,及每个词在全文档集中的DF

    //由于这里仅仅是为了得到特征值的个数,所以这一步可以用于去掉这个DF,仅仅得到特征的个数

    //获得整个数据集中的特征数量

      if (key.stringAt(0).equals(BayesConstants.FEATURE_COUNT)) {

        output.collect(VOCAB_COUNT, ONE);

        reporter.setStatus("Bayes TfIdf Mapper: vocabCount");

      } else {

        throw new IllegalArgumentException("Unexpected Tuple: " + key);

      }

    }

   

  }

 

  @Override

  public void configure(JobConf job) {

    try {

      this.labelDocumentCounts.clear();

      Map<String,Double> labelDocCountTemp = new HashMap<String,Double>();

     

      DefaultStringifier<Map<String,Double>> mapStringifier = new DefaultStringifier<Map<String,Double>>(job,

          GenericsUtil.getClass(labelDocCountTemp));

     

      String labelDocumentCountString = mapStringifier.toString(labelDocCountTemp);

      labelDocumentCountString = job.get("cnaivebayes.labelDocumentCounts", labelDocumentCountString);

     

      labelDocCountTemp = mapStringifier.fromString(labelDocumentCountString);

     

      //获得每个类别中的文档数量

      for (Map.Entry<String, Double> stringDoubleEntry : labelDocCountTemp.entrySet()) {

        this.labelDocumentCounts.put(stringDoubleEntry.getKey(), stringDoubleEntry.getValue());

      }

     

    } catch (IOException ex) {

      log.warn(ex.toString(), ex);

    }

  }

 

}

  评论这张
 
阅读(716)| 评论(0)
推荐 转载

历史上的今天

评论

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

页脚

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