注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

anqiang专栏

不要问细节是怎么搞的,源码说明一切

 
 
 

日志

 
 

J48实现中的一些问题 三  

2009-05-26 22:27:03|  分类: Weka 学习系列 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

如何处理分类时测试样本属性缺失问题

在数据挖掘的实验中,我们时常会遇到缺失值的问题即weka中的"?",在这个时候我们该怎么处理?在这篇文章中,我主要分析一下wekaJ48在分类时处理缺失值的问题,至于在其它情况下缺失值问题,我想在以后有机会弄懂的时候再弄出来跟大家分享.

其实这次写的东西主要还是 屈伟(kolala++)告诉我的. 在一次做实验时,我突然想到在分类一个缺失属性值的样本时,J48是如何处理的,我以为是当样本被分到某个节点时,如果该属性值为空,我就按照当前节点的样本分布来给它赋一个类别值. 问了一下屈伟,才知道不是这样的,于是今天窃取他的知识在这里跟大家讲讲了.

J48,如果在当前节点上该样本的属性为空,它会按照一个当前节点上该属性的分布情况得到一个分布表,即如果该节点的训练样本的属性值分布为 [2,3,5] (样本量为10),则此时该样本按照[0.2,0.3,0.5]的权重进入当前节点的子树中,不知道这样讲是否清楚.

还是我的老办法,把代码展示出来最能说明问题.

 

//WangYi 2007-10-7

  /*

   * 分类样本

   */

  public double classifyInstance(Instance instance)

    throws Exception {

 

    double maxProb = -1;

    double currentProb;

    int maxIndex = 0;

    int j;

 

    /*

     * 找到可能性最大的类别作为当前测试样本的类别

     */

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

      //对于类别j的可能性

      //wangyi 2008.4.1

    currentProb = getProbs(j, instance, 1);

      if (Utils.gr(currentProb,maxProb)) {

    maxIndex = j;

    maxProb = currentProb;

      }

    }

 

    return (double)maxIndex;

  }

 

该函数在 weka.classifiers.trees.ClassifierTree类文件中.该函数实现了分类一个测试样本的功能.

 

/*

   * 在这里有DecisionTree处理未知值的解决办法

   */

  private double getProbs(int classIndex, Instance instance, double weight)

    throws Exception {

   

    double prob = 0;

   

    /*

     * 当前节点如果是叶子节点,返回instance在该classIndex下的可能性

     */

    if (m_isLeaf) {

      return weight * localModel().classProb(classIndex, instance, -1);

    } else {

           /*

            * 如果不是叶子节点则我们找该样本应该进入下一级哪一个子节点

            */

      int treeIndex = localModel().whichSubset(instance);

     

      /*

       * 当该样本的属性为?,它将返回-1

       */

      if (treeIndex == -1) {

             /*

              * 计算当前节点上的属性值分布情况,得到权重数组

              */

       double[] weights = localModel().weights(instance);

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

              /*

               * 按照权重数组进入下一级子节点

               */

         if (!son(i).m_isEmpty) {

           prob += son(i).getProbs(classIndex, instance,

                                weights[i] * weight);

         }

       }

       return prob;

      } else {

             /*

              * 如果该样本的属性为空,进入特定子节点

              */

       if (son(treeIndex).m_isEmpty) {

         return weight * localModel().classProb(classIndex, instance,

                                           treeIndex);

       } else {

         return son(treeIndex).getProbs(classIndex, instance, weight);

       }

      }

    }

  }

 

该函数也在weka.classifiers.trees.ClassifierTree.

 

/*

   * C4.5Split中计算样本在当前节点 属性上的权重数值

   */

  public final double [] weights(Instance instance) {

   

    double [] weights;

    int i;

   

    if (instance.isMissing(m_attIndex)) {

      weights = new double [m_numSubsets];

      /*

       * 计算权重信息还是借助了 Split中保存的统计信息

       * (distribution),这个对象相信大家不会陌生

       */

      for (i=0;i<m_numSubsets;i++)

       weights [i] = m_distribution.perBag(i)/m_distribution.total();

      return weights;

    }else{

      return null;

    }

  }

 

这个函数在weka.classifiers.trees.j48. C45Split类中,它展示了求取当前节点属性值分布数组的一个实例.

 

好了,由于不是我的东西,就搞到这里,大家自己看吧.过几天再写了,这几天要忙着做我的实验了.回头我在blog上开辟一个MOA专栏(这个也是在屈伟那边搞过来的),介绍一些数据流的东西. 当然还是从代码的角度了,别的俺搞不了.

 
  评论这张
 
阅读(1555)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017