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. Openstack: Single node Installation and External Network Accessing Configuration Guide

    Summary of installation Step 0: Prerequisites Step 1: Create Openstack hostsystem Step 2: Config Ope ...

  2. 深入Java虚拟机(2)——Java的平台无关性

    一.平台无关性的好处 Java技术在网络环境下非常有用,其中一个关键理由是,用Java创建的可执行二进制程序,能够不加改变地运行于多个平台. 这样的平台无关性随之带来许多的好处.这将极大地减轻系统管理 ...

  3. Windows 10下Markdown不能显示预览

    Windows 10下Markdown不能显示预览 结局办法 下载awesomium的SDK,安装后重启Markdown即可 实测最新版本的SDK不行,建议安装1.6.6 下载地址:http://ww ...

  4. 给pdf文件添加防伪水印logo(附工程源码下载)

    pdf添加水印logo这种需求场景确实很少,有些时候一些销售单据生成pdf添加一个水印logo,做一个简单的防伪效果,虽然实际上并没有太大作用,但是产品经理说要,巴拉巴拉--省略一万字. 下面将源码分 ...

  5. Android使用HttpClient以Post、Get请求服务器发送数据的方式(普通和json)

    讲这个之前,我们先来说说get和post两种请求的区别吧!!! 1. GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.jsp?name=te ...

  6. JAVA面向对象-----instanceof 关键字

    instanceof 关键字 1:快速演示instanceof Person p=new Person(); System.out.println( p instanceof Person); 2:i ...

  7. JAVA面向对象-----java面向对象的六大原则

    现在编程的主流语言基本上都是面向对象的.如C#,C++,JAVA.我们在使用时,已经构造了一个个的类.但是往往由于我们在类内部或外部的设计上存在种 种问题,导致尽管是面向对象的语言,却是面向过程的逻辑 ...

  8. OpenCV相机标定

    标签(空格分隔): Opencv 相机标定是图像处理的基础,虽然相机使用的是小孔成像模型,但是由于小孔的透光非常有限,所以需要使用透镜聚焦足够多的光线.在使用的过程中,需要知道相机的焦距.成像中心以及 ...

  9. 16 Content Provider总结

    第16天 Content Provider 一, 什么是Content Provider? 内容提供者 Android四大主件之一 :短信记录 通讯录 联系人 自定义 >Content Prov ...

  10. Android开发学习之路--百度地图之初体验

    手机都有gps和网络,通过gps或者网络可以定位到自己,然后通过百度,腾讯啊之类的地图可以显示我们的地理位置.这里学习下百度地图的使用.首先就是要申请开发者了,这个详细就不多讲了.http://dev ...