mahout中bayes分类分析—2

2、 模型

以上训练部分的四个job 执行完毕后,整个 bayes 模型就建立完毕了,总共生成并保存三个目录文件:

trainer-tfIdf

trainer-weights

trainer-thetaNormalizer

我们可以将模型从分布式上Sequence 文件导成本地的 txt 文件进行查看。

3、测试

调用类:TestClassifier

所在包:package org.apache.mahout.classifier.bayes;

根据命令行参数会选择顺序执行还是并行map/reduce 执行,这里只分析并行 map/reduce ,执行时会调用 BayesClassifierDriver

分析BayesClassifierDriver

runjob runjob 中先运行 BayesClassifierMapper 再是 BayesClassifierReducer job 执行完毕后会调用混合矩阵: ConfusionMatrix 函数显示结果

BayesClassifierMapper

首先, 运行configure algorithm=new BayesAlgorithm() datastore=new InMemoryDatastore params) datastore InMemoryDatastore params) 方法将模型装入到 datastore 中即装入 Sigma_j Sigma_ k Sigma_ k Sigma_j thetaNormalizer weight=TfIdf alpha_i=1.0 ); classifier=new classifierContext(algorithm,datastore) classifier.initialize() ,即初始化 classifier ,初始化 classifier datastore.initialize() algorithm.initialize this.datastore )。

datastore的初始化:

调用SequenceFileModelReader loadModel 方法(五个 Load 方法):

loadFeatureWeights(装入的是 Sigma_j )生成hashmap  Sigma_j {0 weight 1 weight  }其中 0 1 等是属性的标号,weight Sigma_j value

loadLabelWeights(装入的是 Sigma_ k)生成 hashmap  Sigma_ k{0 weight 1 weight  }其中 0 1 等是label 即类标签的标号, weight Sigma_ k value

loadSumWeight (装入的是 Sigma_ k Sigma_j )使datastore 的成员变量 Sigma_ j Sigma_ k=value(训练得到的所有 tfidf 总和)。

loadThetaNormalizer (装入的是 ThetaNormalizer )生成 hashmap thetaNormalizerPerlabel{0 weight 1 weight  }其中 weight 是传进来的 value ,使 datastore 的成员变量 thetaNormalizer=Max(1.0 |weight|)

loadWeightMatrix (装入的是 weight tfidf )生成 weightMatrix SparseMatrix ,其中行是属性的标号,列是 label 的标号,行列交叉的地方是 tfidf

algorithm的初始化:

调用datastore.getKeys getKeys 返回 labeldicionary.Keys 即返回一个集合,里面放的是所有的 label

其次, 运行map :开始分类 classifier.classifyDocument(),classifyDocument() 调用 algorithm.classifyDocument new result{unkonwm,0} categories= label weight 即所有的label 集合; 开始循环:针对每一个类进行循环,调用documenWeight :先计算文档中每个词的次数( frequency ),生成一个 Map wordlist ,针对 wordlist each pair 计算:∑ [frequenc y×featureweight(datastore,label,word) ]。其中 featureweight共四个,都调用datastore.getWeight,以下分别分析:

①double result = 调用datastore.getWeight,稀疏矩阵的getQuick,取出矩阵的Tfidf值;

②double vocabCount =属性总数;

③double sumLableWeight =Sigma_k的值;

④double numerator =result + 1.0;

⑤double denominator = sumLableWeight + vocabCount;

⑥double weight =log(numerator/denominator)也就是=log[(Tfidf+1.0)/(Sigma_k+属性个数)];

返回的是result = -weight;

所以说, documenWeight返回的值是测试文档属于某类的概率的大小,即所有属性的在某类下的 frequenc y×result之和与在其他类下的和值进行比较,最大值的,取出它的label,文档就属于此类。

key=_CT 正确 label  分类 label  value=1.0

BayesClassifierReducer

只是合并map的结果。

key=_CT 正确 label  分类 label  value= 正确分类的文档数

根据对以上∑(frequenc y×result)进行分析,参照贝叶斯多项式模型, frequency 是对weight中取对数时转移到前面的,即log(numerator/denominator) frequency  frequency ×log(numerator/denominator),weight是条件概率,即log[(numerator/denominator) frequency

×(numerator/denominator) frequency  ] =  log(numerator/denominator) frequency 因为按贝叶斯原理来说,后验概率=先验概率×条件概率,据我理解,此处为什么没有乘先验概率,可能是因为所用的20个新闻的数据每类中的文档数大致一样,先验概率几乎一样,所以没必要乘(个人猜测)。

ConfusionMatrix函数显示结果

key=正确 label  value={key= 分类 label value= }

猜你喜欢

转载自lbxhappy.iteye.com/blog/1736154