您的位置:首页 > 其它

数据挖掘 ID3算法

2015-12-09 12:55 239 查看
ID3算法是一种贪心算法,用来构造决策树。ID3算法起源于概念学习系统(CLS),以信息熵的下降速度为选取测试属性的标准,即在每个节点选取还尚未被用来划分的具有最高信息增益的属性作为划分标准,然后继续这个过程,直到生成的决策树能完美分类训练样例。

归纳决策树ID3(Java实现)

先上问题吧,我们统计了14天的气象数据(指标包括outlook,temperature,humidity,windy),并已知这些天气是否打球(play)。如果给出新一天的气象指标数据:sunny,cool,high,TRUE,判断一下会不会去打球。
table 1
outlooktemperaturehumiditywindyplay
sunnyhothighFALSEno
sunnyhothighTRUEno
overcasthothighFALSEyes
rainymildhighFALSEyes
rainycoolnormalFALSEyes
rainycoolnormalTRUEno
overcastcoolnormalTRUEyes
sunnymildhighFALSEno
sunnycoolnormalFALSEyes
rainymildnormalFALSEyes
sunnymildnormalTRUEyes
overcastmildhighTRUEyes
overcasthotnormalFALSEyes
rainymildhighTRUEno
这个问题当然可以用朴素贝叶斯法求解,分别计算在给定天气条件下打球和不打球的概率,选概率大者作为推测结果。
现在我们使用ID3归纳决策树的方法来求解该问题。

预备知识:信息熵

熵是无序性(或不确定性)的度量指标。假如事件A的全概率划分是(A1,A2,...,An),每部分发生的概率是(p1,p2,...,pn),那信息熵定义为:



通常以2为底数,所以信息熵的单位是bit。
补充两个对数去处公式:



ID3算法

构造树的基本想法是随着树深
ceaa
度的增加,节点的熵迅速地降低。熵降低的速度越快越好,这样我们有望得到一棵高度最矮的决策树。
在没有给定任何天气信息时,根据历史数据,我们只知道新的一天打球的概率是9/14,不打的概率是5/14。此时的熵为:



weka中的源代码如下:
 private double computeEntropy(Instances data) throws Exception {

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

    Enumeration instEnum = data.enumerateInstances();

    while (instEnum.hasMoreElements()) {

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

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

    }

    double entropy = 0;

    for (int j = 0; j < data.numClasses(); j++) {

      if (classCounts[j] > 0) {

        entropy -= classCounts[j] * Utils.log2(classCounts[j]);

      }

    }

    entropy /= (double) data.numInstances();

    return entropy + Utils.log2(data.numInstances());

  }

属性有4个:outlook,temperature,humidity,windy。我们首先要决定哪个属性作树的根节点。
对每项指标分别统计:在不同的取值下打球和不打球的次数。
table 2
outlooktemperaturehumiditywindyplay
 yesno yesno yesno yesnoyesno
sunny23hot22high34FALSE6295
overcast40mild42normal61TRUR33  
rainy32cool31        
下面我们计算当已知变量outlook的值时,信息熵为多少。
outlook=sunny时,2/5的概率打球,3/5的概率不打球。entropy=0.971
outlook=overcast时,entropy=0
outlook=rainy时,entropy=0.971
而根据历史统计数据,outlook取值为sunny、overcast、rainy的概率分别是5/14、4/14、5/14,所以当已知变量outlook的值时,信息熵为:5/14 × 0.971 + 4/14 × 0 + 5/14 × 0.971 = 0.693
这样的话系统熵就从0.940下降到了0.693,信息增溢gain(outlook)为0.940-0.693=0.247
同样可以计算出gain(temperature)=0.029,gain(humidity)=0.152,gain(windy)=0.048。
源码
private double computeInfoGain(Instances data, Attribute att) 

    throws Exception {

    double infoGain = computeEntropy(data);

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

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

      if (splitData[j].numInstances() > 0) {

        infoGain -= ((double) splitData[j].numInstances() /

                     (double) data.numInstances()) *

          computeEntropy(splitData[j]);

      }

    }

    return infoGain;

  }

gain(outlook)最大(即outlook在第一步使系统的信息熵下降得最快),所以决策树的根节点就取outlook。



接下来要确定N1取temperature、humidity还是windy?在已知outlook=sunny的情况,根据历史数据,我们作出类似table 2的一张表,分别计算gain(temperature)、gain(humidity)和gain(windy),选最大者为N1。
依此类推,构造决策树。当系统的信息熵降为0时,就没有必要再往下构造决策树了,此时叶子节点都是纯的--这是理想情况。最坏的情况下,决策树的高度为属性(决策变量)的个数,叶子节点不纯(这意味着我们要以一定的概率来作出决策)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: