Mahout版本:0.7,hadoop版本:1.0.4,jdk:1.7.0_25 64bit。
接上篇,先来说说上篇最后的bestIg和bestIndex的求法。在说这个前,要首先明确一个数组的熵的求法,按照mahout中的源码针对这样的一个数组a=[1,3,7,3,0,2]其熵为:

设sum=1+3+7+3+0+2,则其中pi对应于1/sum、3/sum、7/sum、3/sum、2/sum(其中若数组中的元素为0,则不参与计算),这个是数组熵的计算。
假如我有这样的一个数组counts:
[1,3,5,3,0]
[0,9,2,4,2]
[7,2,1,3,4]
[4,3,6,8,3]
[3,2,1,4,5]
那么首先我把对应的数字相加得到countAll=[15,19,15,22,14],然后求得countAll的熵hy,作为一个常数。然后把counts数组分为两部分前面i行和后面的5-i行分别为一组,然后求得这两组的熵分别是ig(i)、ig'(i),这两组对应的size(i)=所有元素相加值,size'(i)也等于所有元素相加值。比如size(1)=12。Size=counts所有元素相加,是一个常数。然后得到这样的一个常数Ig(i)=hy-size(i)*ig(i)/Size-size'(i)*ig'(i)/Size。i从0到4,这样就得到了5个Ig。最后bestIg=max(Ig(i)),bestIndex=bestIg对应的i值。
然后到返回值了return new Split(attr, bestIg, values[best]);这个Split有三个值,attr对应是属性的标识,bestIg是属性的衡量值,用于和其他属性做对比,values[best]是属性attr的分水岭,用于attr属性内部的比较。
代码继续往下看:
Split best = null;
for (int attr : attributes) {
Split split = igSplit.computeSplit(data, attr);
if (best == null || best.getIg() < split.getIg()) {
best = split;
}
}
上面随机选择了三个属性,然后这里则取出其Ig值比较高的那个属性的Split。
代码继续:
Node childNode;
if (data.getDataset().isNumerical(best.getAttr())) {
boolean[] temp = null;
Data loSubset = data.subset(Condition.lesser(best.getAttr(), best.getSplit()));
Data hiSubset = data.subset(Condition.greaterOrEquals(best.getAttr(), best.getSplit()));
if (loSubset.isEmpty() || hiSubset.isEmpty()) {
// the selected attribute did not change the data, avoid using it in the child notes
selected[best.getAttr()] = true;
} else {
// the data changed, so we can unselect all previousely selected NUMERICAL attributes
temp = selected;
selected = cloneCategoricalAttributes(data.getDataset(), selected);
}
// size of the subset is less than the minSpitNum
if (loSubset.size() < minSplitNum || hiSubset.size() < minSplitNum) {
// branch is not split
double label;
if (data.getDataset().isNumerical(data.getDataset().getLabelId())) {
label = sum / data.size();
} else {
label = data.majorityLabel(rng);
}
log.debug("branch is not split Leaf({})", label);
return new Leaf(label);
}
Node loChild = build(rng, loSubset);
Node hiChild = build(rng, hiSubset);
// restore the selection state of the attributes
if (temp != null) {
selected = temp;
} else {
selected[best.getAttr()] = alreadySelected;
}
childNode = new NumericalNode(best.getAttr(), best.getSplit(), loChild, hiChild);
}
比如这次debug随机选择的三个属性是[4,2,0],然后计算得到属性2的Ig最大,所以首先选择属性2,属性2是Numerical的,所以直接进入到if下面的代码块
刚开始Data loSubset = data.subset(Condition.lesser(best.getAttr(), best.getSplit()));Data hiSubset = data.subset(Condition.greaterOrEquals(best.getAttr(), best.getSplit()));这两句就是把所有数据按照属性bestAttr中的bestSplit来进行分组。若属性bestAttr中的值小于bestSplit的值,那么这条数据就被分给loSubset中,否则分给hiSubset中。debug模式查看这两个变量的值:

可以看到52+162=214,这说明这两个数组的确是由214条记录分离得到的。且分别观察loSubset、hiSubset,可以看到里面属性attr的值都是分别<bestSplit和>=bestSplit的。
下面到了Node loChild = build(rng, loSubset);然后又到了build函数,这次data是含有52条记录的数据了。然后又随机取出三个属性,计算得到最优的属性,然后再按照最优的属性把数据分为两部分,然后再build()。啥时候退出循环呢?
if (loSubset.size() < minSplitNum || hiSubset.size() < minSplitNum) {
// branch is not split
double label;
if (data.getDataset().isNumerical(data.getDataset().getLabelId())) {
label = sum / data.size();
} else {
label = data.majorityLabel(rng);
}
log.debug("branch is not split Leaf({})", label);
return new Leaf(label);
}
这里可以看到当分组后的两部分数据中的其中一部分数据小于给定的阈值minSplitNum(终于知道这个值是用来干啥的了)的时候,就退出循环。返回的new Leaf(label)中的label是哪个label呢?是data中label最多的那个,可以参见下面的代码:
public int majorityLabel(Random rng) {
// count the frequency of each label value
int[] counts = new int[dataset.nblabels()];
for (int index = 0; index < size(); index++) {
counts[(int) dataset.getLabel(get(index))]++;
}
// find the label values that appears the most
return DataUtils.maxindex(rng, counts);
}
最后返回的childNode是什么?childNode = new NumericalNode(best.getAttr(), best.getSplit(), loChild, hiChild);可以看到这个childNode包含四个属性,第一个是属性attr,第二个是该属性的分水岭bestSplit,第三个是左子树,第四个是右子树。
通过上面不断的递归循环,最后得到一棵树,调用返回到Step1MapperFollow的 Node tree=bagging.build(rng)上面来。比如某次debug的树如下:

对应的树画出来如下所示:

左边是属性值小于中间的那个数字的,右边是大于或等于的。
然后就是设置下输出的格式key.set(partition, firstTreeId + treeId);
// if (!isNoOutput()) {
MapredOutput emOut = new MapredOutput(tree);
然后直接输出了,比如Step1MapperFollow的输出如下:
key:0***value:{NUMERICAL:NUMERICAL:LEAF:;,NUMERICAL:NUMERICAL:LEAF:;,LEAF:;;,NUMERICAL:LEAF:;,NUMERICAL:LEAF:;,NUMERICAL:LEAF:;,LEAF:;;;;;;,LEAF:;; | null}
key:1***value:{NUMERICAL:NUMERICAL:LEAF:;,LEAF:;;,NUMERICAL:NUMERICAL:LEAF:;,NUMERICAL:NUMERICAL:LEAF:;,NUMERICAL:LEAF:;,LEAF:;;;,LEAF:;;;,LEAF:;;; | null}
key:2***value:{NUMERICAL:NUMERICAL:NUMERICAL:LEAF:;,LEAF:;;,LEAF:;;,NUMERICAL:LEAF:;,LEAF:;;; | null}
这样表示输出3棵树,其中最后一棵树就是上图的那棵树的打印字符串。这样Step1Mapper的仿制代码就分析完了,其实就是Step1Mapper的工作流分析完了。
分享,成长,快乐
转载请注明blog地址:http://blog.csdn.net/fansy1990
分享到:
相关推荐
樊哲是Mahout的积极学习者和实践者,他在CSDN上分享了关于Mahout算法的解析与案例实战的博客,获得了“CSDN2013博客之星”的荣誉。樊哲的经验表明,虽然Hadoop平台上算法开发一般需要耗费很长时间,但Mahout已经实现...
**Apache Mahout 源码解析** Apache Mahout 是一个基于Java的开源机器学习库,旨在简化大规模数据集上的机器学习算法...深入研究这些源码,可以帮助你理解Mahout的内部工作机制,并有可能进行二次开发或定制化需求。
二、Mahout与中文分词 1. **中文分词的重要性** 在中文信息处理中,由于中文没有明确的词边界,分词是首要任务。准确的分词能为后续的文本分析、情感分析、主题模型等提供基础。Mahout虽然并非专门的中文处理库,...
mahout-distribution-0.5-src.zip mahout 源码包
**Apache Mahout Random Forest 示例详解** Apache Mahout 是一个基于 Apache Hadoop 的机器学习库,提供了多种算法,包括分类、聚类和推荐系统等。在这些算法中,随机森林(Random Forest)是一种广泛使用的集成...
svd算法的工具类,直接调用出结果,调用及设置方式参考http://blog.csdn.net/fansy1990 <mahout源码分析之DistributedLanczosSolver(七)>
Mahout 是 Apache Software Foundation(ASF) 旗下的一个开源项目,提供一些可扩展的机器学习领域经典算法的实现,旨在帮助开发人员更加方便快捷地创建智能应用程序。Mahout包含许多实现,包括聚类、分类、推荐过滤...
《Mahout in Action》是一本深入探讨Apache Mahout机器学习框架的专业书籍,其源码提供了丰富的实践示例和深入理解Mahout算法的机会。在GitHub上,你可以找到这些源码的完整版本,链接为。下面,我们将详细探讨...
3. **Random Forest**:一种集成学习方法,用于分类和回归任务,通过构建多棵树来提高预测准确性和泛化能力。 4. **TF-IDF**:文本分析中常用的术语权重计算方法,用于识别文档中的重要词汇。 5. **Apriori关联...
《Apache Mahout 0.7源码解析与应用探索》 Apache Mahout 是一个开源机器学习库,专注于大规模数据集的算法实现。该库由Java编写,并采用Maven作为构建工具,提供了一系列用于构建智能应用的高效算法。本文将深入...
Apache Mahout是一个流行的机器学习库,广泛用于数据挖掘和大数据分析。《Mahout in Action》这本书是Mahout技术的权威指南,提供了丰富的示例代码供读者实践。然而,在实际操作过程中,使用Maven编译书中提供的源...
mahout 0.7 src, mahout 源码包, hadoop 机器学习子项目 mahout 源码包
二、下载Mahout 访问Mahout的官方网站或者GitHub仓库,选择最新稳定版本的源码进行下载。通常,你可以下载一个tar.gz或zip格式的压缩包,解压到你想要的目录。 三、构建Mahout 打开命令行,进入解压后的Mahout源码...
Mahout 主要提供了三大核心功能: - **推荐系统**:通过协同过滤等技术实现个性化推荐。 - **聚类分析**:包括 K-Means、Canopy 等多种聚类算法。 - **分类**:如朴素贝叶斯分类器等。 这些功能帮助开发者处理大...
3. **分类算法**:除了推荐系统和聚类外,Mahout还支持多种分类算法,如决策树(Decision Tree)、随机森林(Random Forest)等。这些算法主要用于预测数据的类别归属,广泛应用于文本分类、情感分析等领域。 #### 五、...
这个压缩包包含的是Mahout项目不同版本的核心库,分别是mahout-core-0.9.jar、mahout-core-0.8.jar和mahout-core-0.1.jar。这些版本的差异在于功能的完善、性能的优化以及对新特性的支持。 1. **Mahout核心功能**:...
mahout0.9的源码,支持hadoop2,需要自行使用mvn编译。mvn编译使用命令: mvn clean install -Dhadoop2 -Dhadoop.2.version=2.2.0 -DskipTests
Apache Mahout是一个开源项目,专注于开发可扩展的机器学习库,它主要由Java语言编写,并且依赖于Maven构建系统。在"apache-mahout-distribution-0.11.0-src.zip"这个压缩包中,您将找到Mahout 0.11.0版本的源代码,...
在Hadoop之上构建Mahout环境,可以实现高效的大规模数据挖掘和分析。 标题"hadop 2.4.1+mahout0.9环境搭建"涉及到的知识点主要包括以下几个方面: 1. **Hadoop 2.4.1**:这是Hadoop的一个重要版本,引入了YARN...