J48算法中的信息增益值是怎么计算的?能帮我分析一下吗?

来自统计分析、机器学习、模式识别等领域的数据挖掘算法

J48算法中的信息增益值是怎么计算的?能帮我分析一下吗?

帖子朔风不寒 » 2009年 11月 8日 16:16

代码: 全选
/*
*    This program is free software; you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation; either version 2 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program; if not, write to the Free Software
*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
*    EntropyBasedSplitCrit.java
*    Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
*
*/

package weka.classifiers.trees.j48;

/**
* "Abstract" class for computing splitting criteria
* based on the entropy of a class distribution.
*
* @author Eibe Frank (eibe@cs.waikato.ac.nz)
* @version $Revision: 1.8 $
*/
public abstract class EntropyBasedSplitCrit
  extends SplitCriterion {

  /** for serialization */
  private static final long serialVersionUID = -2618691439791653056L;

  /** The log of 2. */
  protected static double log2 = Math.log(2);

  /**
   * Help method for computing entropy.
   */
  public final double logFunc(double num) {

    // Constant hard coded for efficiency reasons
    if (num < 1e-6)
      return 0;
    else
      return num*Math.log(num)/log2;
//此处的num是什么参数啊
  }

  /**
   * Computes entropy of distribution before splitting.
   */
  public final double oldEnt(Distribution bags) {

    double returnValue = 0;
    int j;

    for (j=0;j<bags.numClasses();j++)
      returnValue = returnValue+logFunc(bags.perClass(j));
    return logFunc(bags.total())-returnValue;
//这里它返回的参数logFunc(bags.total())-returnValue;又是什么啊
  }

  /**
   * Computes entropy of distribution after splitting.
   */
  public final double newEnt(Distribution bags) {
   
    double returnValue = 0;
    int i,j;

    for (i=0;i<bags.numBags();i++){
      for (j=0;j<bags.numClasses();j++)
   returnValue = returnValue+logFunc(bags.perClassPerBag(i,j));
      returnValue = returnValue-logFunc(bags.perBag(i));
    }
    return -returnValue;
//还有这里  }

  /**
   * Computes entropy after splitting without considering the
   * class values.
   */
  public final double splitEnt(Distribution bags) {

    double returnValue = 0;
    int i;

    for (i=0;i<bags.numBags();i++)
      returnValue = returnValue+logFunc(bags.perBag(i));
    return logFunc(bags.total())-returnValue;
  }
}



怎么与原始公式中的参数对应不上呢?
朔风不寒
 
帖子: 20
注册: 2009年 11月 8日 15:57

Re: J48算法中的信息增益值是怎么计算的?能帮我分析一下吗?

帖子koalaundead » 2009年 11月 13日 09:11

我感觉和公式是一样的呀

num就是公式中的p(xi)

它计算的就是log_2^(p(xi)),只是用了换底公式。

下面就是entropy的公式。oldEnt是分裂前的,newEnt是分裂后的,分裂后要把全部分出来的子结点加起来,numBags是属性取值的个数
koalaundead
 
帖子: 84
注册: 2009年 2月 25日 20:08

Re: J48算法中的信息增益值是怎么计算的?能帮我分析一下吗?

帖子朔风不寒 » 2009年 11月 13日 13:41

我原来也是这么想的,但是我在num的上面放了一个输出System.out.println(num);后输出的是被统计值的个数,而不是概率。。。。。。。不信你试试
朔风不寒
 
帖子: 20
注册: 2009年 11月 8日 15:57

Re: J48算法中的信息增益值是怎么计算的?能帮我分析一下吗?

帖子koalaundead » 2009年 11月 13日 15:01

看一下ID3里的这个函数

代码: 全选
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());
  }
koalaundead
 
帖子: 84
注册: 2009年 2月 25日 20:08

Re: J48算法中的信息增益值是怎么计算的?能帮我分析一下吗?

帖子朔风不寒 » 2009年 11月 13日 18:05

代码: 全选
    entropy /= (double) data.numInstances();
    return entropy + Utils.log2(data.numInstances());

上面的代码中熵值:图片 这个与公式中图片的也对不上啊。。。
最后由 朔风不寒 编辑于 2009年 11月 14日 13:26,总共编辑了 1 次
朔风不寒
 
帖子: 20
注册: 2009年 11月 8日 15:57

Re: J48算法中的信息增益值是怎么计算的?能帮我分析一下吗?

帖子koalaundead » 2009年 11月 14日 10:08

我怎么怎么看都感觉是一样的,呵呵?

你这样看:P(ci)是等于这个类别的概率密度函数,Ci是这个结点ci类别的样本数,这个结点的样本总数是N
也就是p(ci)为Ci/N

代码: 全选
double entropy = 0;
    for (int j = 0; j < data.numClasses(); j++) {
      if (classCounts[j] > 0) {
        entropy -= classCounts[j] * Utils.log2(classCounts[j]);
      }
    }


这段代码可看成是 sum_(n=0)^M (Cn * log_2^Cn)
代码: 全选
entropy /= (double) data.numInstances();


也就是(sum_(n=0)^M (Cn * log_2^Cn) )/ N
代进去(sum_(n=0)^M (Cn / N * log_2^Cn) )
而前面说过Cn/N=P(cn)那么再推一步
(sum_(n=0)^M (p(ci) * log_2^Cn) )

再看最后一步的log_2^N
这个你可以看成是(N/N)log_2^N
把它展成M个式子(C1/N)log_2^N+...+(Cm/N)log_2^N
log运算中log(ab) = log(a)+log(b)
前面的计算用的是减法,这里加也就相当于用除法。
你代进去就相当于是给前面那个导出来的式子每次除一个分母。
(sum_(n=0)^M (p(ci) * log_2^Cn/N) )

最后推出来
(sum_(n=0)^M (p(ci) * log_2^p(ci)) )
公式写起来太痛苦了,如果还是不懂,过两天我发一篇blog解释
koalaundead
 
帖子: 84
注册: 2009年 2月 25日 20:08

Re: J48算法中的信息增益值是怎么计算的?能帮我分析一下吗?

帖子朔风不寒 » 2009年 11月 14日 13:09

十分感谢koalaundead的详细讲解,能遇到您这样的老师我感到很荣幸。再次感谢koalaundead的详细讲解。
最后由 朔风不寒 编辑于 2009年 11月 15日 09:31,总共编辑了 1 次
朔风不寒
 
帖子: 20
注册: 2009年 11月 8日 15:57

Re: J48算法中的信息增益值是怎么计算的?能帮我分析一下吗?

帖子C6H5NO2 » 2009年 11月 15日 03:22

不要贴来自QQ空间的图片。。。别人看不见。需要的话可以直接上传图片的
头像
C6H5NO2
 
帖子: 291
注册: 2006年 11月 17日 15:30

Re: J48算法中的信息增益值是怎么计算的?能帮我分析一下吗?

帖子zy2009zsm » 2010年 1月 6日 16:59

请问代码在哪里可以看到??
zy2009zsm
 
帖子: 7
注册: 2010年 1月 6日 16:26



回到 算法讨论

在线用户

正在浏览此版面的用户:Yahoo [Bot] 和 1 位游客