Mahout朴素贝叶斯文本分类
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朴素贝叶斯文本分类的更多相关文章
- 朴素贝叶斯文本分类-在《红楼梦》作者鉴别的应用上(python实现)
朴素贝叶斯算法简单.高效.接下来我们来介绍其如何应用在<红楼梦>作者的鉴别上. 第一步,当然是先得有文本数据,我在网上随便下载了一个txt(当时急着交初稿...).分类肯定是要一个回合一个 ...
- 朴素贝叶斯文本分类(python代码实现)
朴素贝叶斯(naive bayes)法是基于贝叶斯定理与特征条件独立假设的分类方法. 优点:在数据较少的情况下仍然有效,可以处理多分类问题. 缺点:对入输入数据的准备方式较为敏感. 使用数据类型:标称 ...
- 朴素贝叶斯文本分类实现 python cherry分类器
贝叶斯模型在机器学习以及人工智能中都有出现,cherry分类器使用了朴素贝叶斯模型算法,经过简单的优化,使用1000个训练数据就能得到97.5%的准确率.虽然现在主流的框架都带有朴素贝叶斯模型算法,大 ...
- 详解使用EM算法的半监督学习方法应用于朴素贝叶斯文本分类
1.前言 对大量需要分类的文本数据进行标记是一项繁琐.耗时的任务,而真实世界中,如互联网上存在大量的未标注的数据,获取这些是容易和廉价的.在下面的内容中,我们介绍使用半监督学习和EM算法,充分结合大量 ...
- 朴素贝叶斯文本分类java实现
package com.data.ml.classify; import java.io.File; import java.util.ArrayList; import java.util.Coll ...
- Naive Bayes(朴素贝叶斯算法)[分类算法]
Naïve Bayes(朴素贝叶斯)分类算法的实现 (1) 简介: (2) 算法描述: (3) <?php /* *Naive Bayes朴素贝叶斯算法(分类算法的实现) */ /* *把. ...
- 【甘道夫】通过Mahout构建贝叶斯文本分类器案例具体解释
背景&目标: 1.sport.tar 是体育类的文章,一共同拥有10个类别. 用这些原始材料构造一个体育类的文本分类器,并測试对照bayes和cbayes的效果: 记录分类器的构造 ...
- 芝麻HTTP:记scikit-learn贝叶斯文本分类的坑
基本步骤: 1.训练素材分类: 我是参考官方的目录结构: 每个目录中放对应的文本,一个txt文件一篇对应的文章:就像下面这样 需要注意的是所有素材比例请保持在相同的比例(根据训练结果酌情调整.不可比例 ...
- Python机器学习算法 — 朴素贝叶斯算法(Naive Bayes)
朴素贝叶斯算法 -- 简介 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法.最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型(Naive Baye ...
随机推荐
- 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 ...
- 深入Java虚拟机(2)——Java的平台无关性
一.平台无关性的好处 Java技术在网络环境下非常有用,其中一个关键理由是,用Java创建的可执行二进制程序,能够不加改变地运行于多个平台. 这样的平台无关性随之带来许多的好处.这将极大地减轻系统管理 ...
- Windows 10下Markdown不能显示预览
Windows 10下Markdown不能显示预览 结局办法 下载awesomium的SDK,安装后重启Markdown即可 实测最新版本的SDK不行,建议安装1.6.6 下载地址:http://ww ...
- 给pdf文件添加防伪水印logo(附工程源码下载)
pdf添加水印logo这种需求场景确实很少,有些时候一些销售单据生成pdf添加一个水印logo,做一个简单的防伪效果,虽然实际上并没有太大作用,但是产品经理说要,巴拉巴拉--省略一万字. 下面将源码分 ...
- Android使用HttpClient以Post、Get请求服务器发送数据的方式(普通和json)
讲这个之前,我们先来说说get和post两种请求的区别吧!!! 1. GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.jsp?name=te ...
- JAVA面向对象-----instanceof 关键字
instanceof 关键字 1:快速演示instanceof Person p=new Person(); System.out.println( p instanceof Person); 2:i ...
- JAVA面向对象-----java面向对象的六大原则
现在编程的主流语言基本上都是面向对象的.如C#,C++,JAVA.我们在使用时,已经构造了一个个的类.但是往往由于我们在类内部或外部的设计上存在种 种问题,导致尽管是面向对象的语言,却是面向过程的逻辑 ...
- OpenCV相机标定
标签(空格分隔): Opencv 相机标定是图像处理的基础,虽然相机使用的是小孔成像模型,但是由于小孔的透光非常有限,所以需要使用透镜聚焦足够多的光线.在使用的过程中,需要知道相机的焦距.成像中心以及 ...
- 16 Content Provider总结
第16天 Content Provider 一, 什么是Content Provider? 内容提供者 Android四大主件之一 :短信记录 通讯录 联系人 自定义 >Content Prov ...
- Android开发学习之路--百度地图之初体验
手机都有gps和网络,通过gps或者网络可以定位到自己,然后通过百度,腾讯啊之类的地图可以显示我们的地理位置.这里学习下百度地图的使用.首先就是要申请开发者了,这个详细就不多讲了.http://dev ...