文档章节

Weka开发[8]-ID3源码介绍

pior
 pior
发布于 2015/10/17 22:43
字数 1206
阅读 48
收藏 1
点赞 0
评论 0

这次介绍一下Id3源码,这次用Weka的源码介绍一下。首先Id3是继承于Classifier的:

       public class Id3 extends Classifier

Id3[]成员变量是递归保存树的变量,数据中每一个元素都是当前结点的子结点。

       /** The node's successors. */

    private Id3[] m_Successors;

Attribute是属性类,m_Attribute是分裂属性

    /** Attribute used for splitting. */

    private Attribute m_Attribute;

如果当前结果是叶子结点,m_ClassValue是类别,到底double代表什么,以前讲过了,一会再讲

    /** Class value if node is leaf. */

    private double m_ClassValue;

Distribution表示的是这个结点属于某个类别的概率,如m_Distribution[0] == 0.1表示当前结点属于类别0的概率为0.1

    /** Class distribution if node is leaf. */

    private double[] m_Distribution;

数据集的类别,以前也讲过了

    /** Class attribute of dataset. */

    private Attribute m_ClassAttribute;

 

以前也讲过,继承自Classifier类的类都要实现buildClassifier函数。

public void buildClassifier(Instances data) throws Exception {

 

    // can classifier handle the data?

    getCapabilities().testWithFail(data);

 

    // remove instances with missing class

    data = new Instances(data);

    data.deleteWithMissingClass();

 

    makeTree(data);

}

getCapabilities().testWithFail(data)是判断是否ID3能处理选择的数据集,比如什么连续属性,类别索引没有设置等等。

data.deleteWithMissingClass则是删除有缺失样本的函数,具体代码如下:

for (int i = 0; i < numInstances(); i++) {

    if (!instance(i).isMissing(attIndex)) {

       newInstances.addElement(instance(i));

    }

}

    m_Instances = newInstances;

简单一点,不用为上面的东西分心,关注makeTree(data)就行了:

// Compute attribute with maximum information gain.

double[] infoGains = new double[data.numAttributes()];

Enumeration attEnum = data.enumerateAttributes();

while (attEnum.hasMoreElements()) {

    Attribute att = (Attribute) attEnum.nextElement();

    infoGains[att.index()] = computeInfoGain(data, att);

}

    m_Attribute = data.attribute(Utils.maxIndex(infoGains));

infoGains保存每个属性的信息增益(IG),枚举每个属性,用computeInfoGain函数计算信息增益值。Util.maxIndex返回信息增益最大的下标,这个属性作为分裂属性保存在m_Attribute成员变量中。

// Make leaf if information gain is zero.

if (Utils.eq(infoGains[m_Attribute.index()], 0)) {

    m_Attribute = null;

    m_Distribution = new double[data.numClasses()];

    Enumeration instEnum = data.enumerateInstances();

    while (instEnum.hasMoreElements()) {

       Instance inst = (Instance) instEnum.nextElement();

       m_Distribution[(int) inst.classValue()]++;

    }

       Utils.normalize(m_Distribution);

       m_ClassValue = Utils.maxIndex(m_Distribution);

       m_ClassAttribute = data.classAttribute();

}

当信息增益等于0时为叶子结点(这为什么再讲,就没完了)。

m_Attribute = null,已经不用再分裂了,所以为null。刚才也说过m_Distribution保存的是当前结点属于类别的概率,所以数组大小于data.numClasses()。枚举当前结点中的每一个样本,inst.classValue()就是inst样本的类别值,请注意不要以为类别都是”good”,”bad”之类的值,而是第一个类别就是0,第二个类别就是1double型。

m_Distribution[(int) inst.classValue()]++;也就是将每个样本的相应的下标加1,比如当前叶子结点有10个样本,9个属于第一个类别,1个属于第五个类别,则m_Distribution[0]=9,m_Distribution[4]=1

Utils.normalize(m_Distribution);简单地理解为归一化吧,刚在例子也就是m_Distribution[0]=9,m_Distribution[4]=0.1。(提醒一下,这个例子应该是不会发生的,包括开始的那个例子,为什么就不解释了)

       m_ClassValue = Utils.maxIndex(m_Distribution);属于哪个类别的概率最高,那当然就是哪个类别,在刚才失败的例子中也就是m_ClassValue == 0

       m_ClassAtrribute也就是类别属性。

// Otherwise create successors.

else {

    Instances[] splitData = splitData(data, m_Attribute);

    m_Successors = new Id3[m_Attribute.numValues()];

    for (int j = 0; j < m_Attribute.numValues(); j++) {

       m_Successors[j] = new Id3();

       m_Successors[j].makeTree(splitData[j]);

    }

}

如果信息增益不是0那么分裂当前结点,在splitData(data, m_Attribute)函数中,data被分裂成m_Attribute离散值个子结点,比如m_Attribute有三种取值”green””red””blue”,则splitDatadata分成3部分到splitData中。

在例子中当前结点有3个子结点,则m_Attribute.numValues()==3,递归地makeTree。(再讲清楚点,也就是每一个子树都是一个决策树,所以new Id3()

这里有一个问题,如果在例中,当前结点的green子结点没有样本,那么:

// Check if no instances have reached this node.

if (data.numInstances() == 0) {

    m_Attribute = null;

    m_ClassValue = Instance.missingValue();

    m_Distribution = new double[data.numClasses()];

    return;

}

这就没什么好解释的了。

对于分类一个样本:

if (m_Attribute == null) {

    return m_ClassValue;

} else {

    return m_Successors[(int) instance.value(m_Attribute)]

       .classifyInstance(instance);

}

当然也是递归了,如果已经到达叶子结点了,那直接返回类别值。不是叶子结点,那么根据样本属性值到相应的子结点,再调用classifyInstance(instance)

 

还有distributionForInstance也差不多,不作解释了:

if (m_Attribute == null) {

    return m_Distribution;

} else {

    return m_Successors[(int) instance.value(m_Attribute)]

           .distributionForInstance(instance);

}

computeInfoGaincomputeEntropy两个函数也不解释了,不过还是应该看一下,有时候还能用的着(最重要的其实是,这都不懂,也过份了点吧)。

分裂结点的函数:

private Instances[] splitData(Instances data, Attribute att) {

    Instances[] splitData = new Instances[att.numValues()];

    for (int j = 0; j < att.numValues(); j++) {

       splitData[j] = new Instances(data, data.numInstances());

    }

    Enumeration instEnum = data.enumerateInstances();

    while (instEnum.hasMoreElements()) {

       Instance inst = (Instance) instEnum.nextElement();

       splitData[(int) inst.value(att)].add(inst);

    }

    for (int i = 0; i < splitData.length; i++) {

       splitData[i].compactify();

    }

    return splitData;

}

data分裂成att.numValues()个子结点,inst.value(att)就是根据inst样本att属性值将inst样本分成相应的子结点中。(确切点,也不是子结点,一个Instances数组元素)


本文转载自:

共有 人打赏支持
pior
粉丝 25
博文 151
码字总数 22496
作品 0
济南
高级程序员
Weka开发[6]-参数设置

这一次介绍的非常简单,会用传命令行参数的人就不用浪费时间看这一篇了,这一篇介绍weka中一些类参数传递的问题。 首先要传递参数当然要知道参数有哪些,有什么作用,要知道这些,建议用Wek...

pior
2015/10/17
79
0
libsvm和id3分类器

weka中的libsvm和id3分类器为什么无法使用呢,我用的是3.6.11版本的,可是无论导入什么数据,这两个分类器都是灰色的,无法使用,希望大家帮忙看看,谢谢!

思绪forever
2014/04/29
223
1
Weka开发[9]—KMeans源码介绍

以前介绍的都是分类的内容,这一次介绍聚类,以最简单的SimpleKMeans源码为例。 分类中训练一个分类器是用buildClassifier(),在聚类中学习一个Clusterer是用buildCluster()。分类中分类一个...

pior
2015/10/17
211
0
数据挖掘简述和weka介绍--数据挖掘学习和weka使用(一)

写在开篇 weka用了一些时日了,觉得真心不错。功能很完善,而且是开源的。最重要的扩展方便,非常适合搞研究和做全国大学生数学建模之类的比赛。 我学习weka主要是看的一本数据挖掘和weka使用...

长平狐
2013/11/25
809
0
Weka开发[5]-半监督算法

这次介绍一个我现在正在做的半监督算法,因为我只是提出一个框架,半监督算法只是一个工具,可是为了找这个工具也让我花了不少功夫。现在介绍的暂时不是Weka的一部分,但开发者是waikato大学...

pior
2015/10/17
46
0
Weka 开发[1]-Instances类

言归正传,开始介绍Weka,先google一下,把Weka软件下载下来,在Weka的目录中有一个weka.jar的包。 把包添加到工程中后,就可以调用weka中的函数了。 再介绍一点weka的基本知识,在weka的目录...

pior
2015/10/17
217
0
Weka manual 3.6翻译: 1.1 简介

第一章 Weka命令行入门 1.1简介 在最初的实验,Weka所包含的图形用户界面是相当足够,若深入使用则建议使用命令行界面,因为它提供了一些功能(这些功能在图形用户界面下不可用) - 并使用少...

Honghe
2012/11/24
0
0
数据预处理和weka.filters的使用--数据挖掘学习和weka使用(三)

上一篇介绍了arff格式,这是weka专有格式,一般情况需要我们从其他数据源抽取或者获得。weka支持从cvs转化,也可以从数据库中抽取,界面如下图 weka安装目录有一个data目录,里面有一些测试数...

长平狐
2013/11/25
1K
0
ubuntu下eclipse打开java文件,注释内容为乱码,解决方法

由于要转到linux下开发,之前的项目我是用GBK编码得,因为windows默认编码是GBK,但在Linux下默认编码却是UTF-8,所以项目跑步起来,一开始想法是把Linux系统得源码换掉改为GBK,试了网上改系...

长平狐
2012/11/01
297
0
Weka开发[7]-LibSVM

首先要提的是LibSVM是一个库,Lib很明显是library的缩写,有些人不知道怎么会认为它是一种算法。它是由中国台湾的Chih-Chung Chang和Chih-Jen Lin等人开发的,他们用多种语言实现写了LibSVM。...

pior
2015/10/17
187
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

看看 LinkedList Java 9

终于迎来了 LinkedList 类,实现的接口就有点多了 Serializable, Cloneable, Iterable<E>, Collection<E>, Deque<E>, List<E>, Queue<E>。LinkedList是一个实现了List接口和Deque接口的双端链......

woshixin
6分钟前
0
0
算法 - 冒泡排序 C++

大家好,我是ChungZH。今天我给大家讲一下最基础的排序算法:冒泡排序(BubbleSort)。 冒泡排序算法的原理如下: 比较相邻的元素。如果第一个比第二个大(可以相反),就交换他们两个。 对每...

ChungZH
8分钟前
0
0
jquery ajax request payload和fromData请求方式

请求头的不同 fromData var data = { name : 'yiifaa'};// 提交数据$.ajax('app/', { method:'POST', // 将数据编码为表单模式 contentType:'application/x-ww...

lsy999
10分钟前
0
0
阿里P7架构师,带你点亮程序员蜕变之路

前言: Java是现阶段中国互联网公司中,覆盖度最广的研发语言。 掌握了Java技术体系,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能有立足之地。 有不少朋友问,成为Java架...

Java大蜗牛
12分钟前
0
0
Ecstore 在没有后台管理界面(维护)的情况如何更新表的字段

window 系统: 切换到:app\base 目录下: C:\Users\qimh>d: D:\>cd D:\WWW\huaqh\app\base 执行:D:\WWW\huaqh\app\base>cmd update linux 系统: 1># cd /alidata/www.novoeshop.com/app/......

qimh
16分钟前
0
0
设计模式-策略模式

策略模式 解释 对工厂模式的再次封装,使用参数控制上下文信息(将工厂返回的实例赋值给context field) 不会返回bean实例,只是设置对应的条件 调用context的方法(调用field的方法) 用户只...

郭里奥
19分钟前
0
0
python使用有序字典

python自带的collections包中有很多有用的数据结构可供使用,其中有个叫OrderedDict类,它可以在使用的时候记录元素插入顺序,在遍历使用的时候就可以按照原顺序遍历。 a = {"a":1,"b"...

芝麻糖人
49分钟前
0
0
RestTemplate HttpMessageConverter

RestTemplate 微信接口 text/plain HttpMessageConverter

微小宝
49分钟前
0
0
mysql视图/存储过程/函数/事件/触发器

--语法参考:https://dev.mysql.com/doc/ (当前用的是5.6) https://dev.mysql.com/doc/refman/5.6/en/sql-syntax-data-manipulation.html --视图 CREATE VIEW test.v AS SELECT * FROM t;......

坦途abc
51分钟前
0
0
MySQL参数优化案例

环境介绍 硬件配置 cpu核心数 内存大小 磁盘空间 16核 256G 3T 软件环境 操作系统版本 mysql版本 表数目 单表行数 centos-7.4 mysql-5.7.22 128张表 2kw行 优化层级与指导思想 优化层级 MySQ...

小致dad
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部