Mahout朴素贝叶斯文本分类算法

Mahout贝叶斯分类器按照官方的说法,是按照《Tackling the PoorAssumptions of Naive Bayes Text Classiers》实现的。分为三个模块:训练、测试和分类。该文档首先简要介绍朴素贝叶斯的基本原理,然后介绍MapReduce实现的思路。

一、MapReduce 朴素贝叶斯算法实现

(一)预处理

在训练和分类之前都需要将小文档合并,以及分词处理。大量的小文档会让NameNode占用太多的内存空间存储元数据,另一方面在执行MapReduce时会占用太多的Map槽。

(二)训练

将训练数据组织成下图的结构。子文件夹的名字为类型名,子文件夹下为该类的文档。子文件夹下不能有文件夹。

训练数据目录结构

该过程将训练数据生成model,生成三个目录:trainer-tfidf、trainer-weights和trainer-thetaNormalizer 。有四个Job完成该过程。抽取正则化的特征,计算TFIDF,计算权重和计算正则化因子。

(1)特征抽取

输入数据格式:

clazzlable

文档内容



Map:

对每一篇文档分词后计算该片文档中的词频(wordcount)、、。

输出:

(1)归一化的词频

key:<_WT,lable,token>

value :

(2)词的文档频率

Key:  <_DF,lable,token>

Value: 1

(3)特征数量

Key:<_FC,lable,token>

Value:1

(4)TF

Key:<"_FF”,lable,token>

Value:wordcount

(5)类型数

Key:<_LC,lable>

Value:1

Combiner:

在Map计算完之后value值求和。

Reduce:

在reduce计算主要做特征选择。过滤掉小于最小词频数和最小文档数的词。

最终输出:

trainer-wordFreq,存储归一化的词频。

       trainer-termDocCount,存储文档词的文档频率。

trainer-featureCount,存储特征数量。

trainer-docCount,存储类型数量,每个类型的文档数。

(2)计算TFIDF

输入:

trainer-termDocCount,trainer-wordFreq和trainer-featureCount文件。

将trainer-docCount添加到configuration中。

Map:

Configure(JobConf job){

从configuration中加载trainer-docCount数据。

}

map(StringTupleDoubleWritable,StringTuple,DoubleWritable){

1.对于TF ,直接输出。

2.对于DF=Log(该词对应的类型的总文档数/df)。输出:Key <_WT,lable, token>   value:DF

3.对于特征总数,特征词的数量

输出:key <_FS> ,  value 1

}

Reduce:

1.对于特征集数量,求和,输出 key: <_FS>  value: 特征数

2.对于TF和IDF。由于对同一个类型中的同一个词,hadoop会将其值合并在一起,这样reduce传入的同一key的迭代器中只有两个值,一个是TF值,一个是IDF值。计算tfidf =TF*IDF .

输出:key <_WT,lable,token>  value :tfidf

最终输出:

trainer-tfidf 文档,key <_WT,lable,token>  value :tfidf

(3)计算权重和

该过程为特征和类表计算权重。

输入:

trainer-tfidf文件。格式为key <_WT,label ,token> ,value <tfidf>

Map:

1.特征和,计算全局词特征权重和

从key中拿到token 输出其tfidf值。

输出:key <_SJ,token>   value <tfidf>

2.类型label和,计算全局类型权重和

从key中拿到label,输出其tfidf。

输出: key<_SK,label>  value <tfidf>

3.特征及label和,计算所有特征所有类型的和

从key中拿到tfidf,输出。

输出: key <_SJSK>  value <tfidf>

Reduce:

对map的结果求和,输出。输出格式和map的一样。

(4)计算正则化因子

输入:

trainer-tfidf文件。格式为key <_WT,label ,token> ,value <tfidf>

将trainer-vocabcount 中的数据写入configuration。

Map:

setup(){

从configuration中读取trainer-vocabcount数据。

}

Map{

对输入的每一个词

W=Log(tfidf/(该词的类型的特征和+总特征数))

输出:key <_LTN,label> , value<W>

}

Reduce:

对Map结果求和。

输出:key<_LTN,label>  value <SUM(W)>

输出:

trainer-thetaNormalizer文件.格式Key  <_LTN,label>   value <W>

(三)分类

训练好模型之后,最终会生成如下图的文档结构:

首先将模型信息存储到内存中,InMemoryBayesDatastore 负责。

分类时传入分好词的词数组document,InMemoryBayesDatastore 的实例,没有分出来时默认的类型名(默认为unknow)。

public ClassifierResult classifyDocument(String[] document,

Datastore datastore,

String defaultCategory){

maxWeight =Double.MAX_VALUE;

ClassifierResult  clazz =new ClassifierResult ();

For(int i  = 0 ;i <类型总数;i++){

Label =datastore.get(i);

Frequency=document中计算词频

TFIDF: 该词在当前类型中的TFIDF

Sigma_ k 该类型的tfidf和VocabCount 总特征词个数

Weight= frequency*log[(TFIDF +1.0) /(Sigma_ k +VocabCount)]

If(Weight<maxWeight){

maxWeight=Weight;

clazz.setLable(Label);

}

}

clazz.setScore(maxWeight);

return  clazz;

}

在map中做分类,输出分类结果。

输入:输入文件格式:文档路径\t分词后的文档内容

Map:

setUp(){

加载模型。

}

Map(Text key,Text value){//key为文档路径  ,value为分词后的文档内容

(1)对分词后的文档内容计算N-Gram

(2)计算词频

(3)类型=classifyDocument(String[] document,

Datastore datastore,

String defaultCategory)

输出分类结果 key: 文档路径,value:类型

}

(四)测试

测试本身就是分类后统计分类的正确率。

测试数据的格式为:文档类型 \t 分词后的文档内容

 Map:key 正确的标签,value 分词后的文档内容

分类后的类型标签=classifyDocument();

输出:key <_CT,正确的标签,分类后的标签>  value  1

Reduce:对map的value求和。

二、API

第一部分叙述了Mahout 朴素贝叶斯分类算法的实现原理。下面叙述API的使用。在说API之前先说说文本预处理,一般来说需要训练或分类的文本都不太可能是TXT格式的,pdf、word ,html网页等等。首先要做的就是从各种格式的文件中抽取出文本。然后要将文本分词。

(一)训练

对于训练数据,需要组织成如图的目录结构。

art248 ,computer200等都是类型信息,每一类中有若干文本。各类中文本的数量保持基本一致。

每一类中都是大量的小文件,而如果需要用MapReduce做训练,需要合并小文件,组成一个或多个大文件。组合后的文件格式为:

类型名

\t

分词后的一个小文件内容

参数说明

TrainClassfier.main(args [])

--gramSize (-ng)

Ngram 个数,默认为1。5以上运算量大,存储空间多,精度提高小,建议不要使用。

--input (-i)

训练数据路径。(注意:是HDFS路径)

--output (-o)

模型输出路径。(注意:是HDFS路径)

--classifierType (-type)

分类器类型。bayes ,默认。

--dataSource (-source)

模型存储位置,默认是hdfs。实际上Mahout并没有实现其它的存储方式。

--alpha (-a)

平滑因子,默认为1。

--minDf (-mf)

最小df值,默认为1。

--minSupport (-ms)

最小tf值,默认为1。

训练后生成的文件:

(二)分类

文类数据和训练数据一样,需要抽取和分词。处理后的待分类数据存放在HDFS的一个目录下。

同样待分类数据再分之前也需要合并,原理同上。

合并后的文件格式(SequenceFile)为:

文件路径

\t

分词后的一个小文件内容

参数说明:

ClassifyClassifier.main(args  []);

--defaultCat (-default)

默认的类型,unknown。这种情况出现在模型数据为空。若分类数据出现unknown,需要检查模型。

--testDir (-d)

分类数据存放路径

--encoding (-e)

编码格式 (UTF-8)

--gramSize (-ng)

Ngram大小,默认为1。建议和训练的ngram值一样。

--model (-m)

模型路径

--classifierType (-type)

默认bayes.

--dataSource (-source)

默认hdfs

--method (-method)

默认MapReduce

--verbose (-v)

是否显示文档分类正确或者错误。注意:该参数在分类时作用不大,分类数据不知道原始的类型信息。

--alpha (-a)

平滑因子,默认为1。

--outputDir (-o)

分类后输出路径。

结果文件是SequenceFile,格式如下:

文件路径(Text)

类型(Text)

(三)测试

测试数据和训练数据的组织一样,合并后的文件格式如下:

真实类型

\t

分词后的文档内容

参数说明

TestClassifier.main(args);

--defaultCat (-default)

默认的类型,unknown。这种情况出现在模型数据为空。若分类数据出现unknown,需要检查模型。

--testDir (-d)

分类数据存放路径

--encoding (-e)

编码格式 (UTF-8)

--gramSize (-ng)

Ngram大小,默认为1。建议和训练的ngram值一样。

--model (-m)

模型路径

--classifierType (-type)

默认bayes.

--dataSource (-source)

默认hdfs

--method (-method)

默认MapReduce

--alpha (-a)

平滑因子

--verbose (-v)

是否显示分类正确或者错误。

测试结果,模糊矩阵

三、参考文档

1.《Tackling the Poor Assumptions of Naive Bayes Text Classiers》

Mahout朴素贝叶斯文本分类的更多相关文章

  1. 朴素贝叶斯文本分类-在《红楼梦》作者鉴别的应用上(python实现)

    朴素贝叶斯算法简单.高效.接下来我们来介绍其如何应用在<红楼梦>作者的鉴别上. 第一步,当然是先得有文本数据,我在网上随便下载了一个txt(当时急着交初稿...).分类肯定是要一个回合一个 ...

  2. 朴素贝叶斯文本分类(python代码实现)

    朴素贝叶斯(naive bayes)法是基于贝叶斯定理与特征条件独立假设的分类方法. 优点:在数据较少的情况下仍然有效,可以处理多分类问题. 缺点:对入输入数据的准备方式较为敏感. 使用数据类型:标称 ...

  3. 朴素贝叶斯文本分类实现 python cherry分类器

    贝叶斯模型在机器学习以及人工智能中都有出现,cherry分类器使用了朴素贝叶斯模型算法,经过简单的优化,使用1000个训练数据就能得到97.5%的准确率.虽然现在主流的框架都带有朴素贝叶斯模型算法,大 ...

  4. 详解使用EM算法的半监督学习方法应用于朴素贝叶斯文本分类

    1.前言 对大量需要分类的文本数据进行标记是一项繁琐.耗时的任务,而真实世界中,如互联网上存在大量的未标注的数据,获取这些是容易和廉价的.在下面的内容中,我们介绍使用半监督学习和EM算法,充分结合大量 ...

  5. 朴素贝叶斯文本分类java实现

    package com.data.ml.classify; import java.io.File; import java.util.ArrayList; import java.util.Coll ...

  6. Naive Bayes(朴素贝叶斯算法)[分类算法]

    Naïve Bayes(朴素贝叶斯)分类算法的实现 (1) 简介: (2)   算法描述: (3) <?php /* *Naive Bayes朴素贝叶斯算法(分类算法的实现) */ /* *把. ...

  7. 【甘道夫】通过Mahout构建贝叶斯文本分类器案例具体解释

    背景&目标: 1.sport.tar 是体育类的文章,一共同拥有10个类别.    用这些原始材料构造一个体育类的文本分类器,并測试对照bayes和cbayes的效果:    记录分类器的构造 ...

  8. 芝麻HTTP:记scikit-learn贝叶斯文本分类的坑

    基本步骤: 1.训练素材分类: 我是参考官方的目录结构: 每个目录中放对应的文本,一个txt文件一篇对应的文章:就像下面这样 需要注意的是所有素材比例请保持在相同的比例(根据训练结果酌情调整.不可比例 ...

  9. Python机器学习算法 — 朴素贝叶斯算法(Naive Bayes)

    朴素贝叶斯算法 -- 简介 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法.最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型(Naive Baye ...

随机推荐

  1. PHP 实例 AJAX RSS 阅读器

    RSS 是一种描述和同步网站内容的格式,是目前使用最广泛的XML应用. RSS 搭建了信息迅速传播的一个技术平台,使得每个人都成为潜在的信息提供者. RSS 阅读器用于阅读 RSS Feed. AJA ...

  2. Python3 MySQL 数据库连接

    什么是 PyMySQL? PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb. PyMySQL 遵循 Python 数据库 AP ...

  3. TensorFlow实验环境搭建

    初衷: 由于系统.平台的原因,网上有各种版本的tensorflow安装教程,基于linux的.mac的.windows的,各有不同,tensorflow的官网也给出了具体的安装命令.但实际上,即使te ...

  4. 谈一谈CloudBlog的系统架构

    ---------------------------------------------------------------------------------------------[版权申明:本 ...

  5. MyEclipse如何全局搜索

    1全局搜索的启动方式 CTRL+H 2全局搜索自己选择搜索方式 自己选择要搜索的东西,简单吧,里面还有很多好玩的东西需要你去发现,加油! [正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之 ...

  6. 【安卓开发】Facebook工程师是如何改进他们Android客户端的

    原文出处: Facebook   译文出处:penkzhou   欢迎分享原创到伯乐头条 作为世界上最大的社交网络,Facebook的Android客户端面临着各种各样的使用环境(地理环境.Andro ...

  7. JVM基础知识GC

    在网上看到一篇很不错的讲解JVM GC的文章,看完之后觉得可以留着以后多看几遍便转载了下来.但是找了半天也没有找到原作者地址.抱歉不能标明原文地址了.以下是文章内容. 几年前写过一篇关于JVM调优的文 ...

  8. linux中查看现在使用的shell是ksh还是bash?以及怎样修改?

    查看系统支持的shell: cat  /etc/shells 查看现在使用的shell:  修改默认shell: 另外,修改了系统默认shell之后不会立即生效,之后再次登录系统修改的shell才会生 ...

  9. java中遍历map的几种方法介绍

          喜欢用Java写程序的朋友都知道,我们常用的一种数据结构map中存储的是键值对,我们一般存储的方式是: map.put(key, value); 而提取相应键的值用的方法是: map.ge ...

  10. 05 Activity 回传数据

    当从一个Activity跳转到第二个Activity后然 让其处理完业务逻辑回传数据给第一个Activity: 回传调用方法顺序: onActivityResult--->>onResta ...