Weka开发[14]-AdaBoost源代码介绍

这一次讲的是Ensemble的东西,一位读者希望我讲一下Adaboost的内容,这种Ensemble看起来的确比较吓人,推荐一篇论文:Ensemble Based Systems in Decision Making. 在这里所有理论的东西我就不介绍了。

与以往一样,先看buildClassifier函数(我在函数中将不重要的代码全部去掉):

super.buildClassifier(data);

if ((!m_UseResampling)&& (m_Classifier instanceof WeightedInstancesHandler)) {

       buildClassifierWithWeights(data);

} else {

       buildClassifierUsingResampling(data);

}

Adaboost类继承自RandomizableIteratedSingleClassifierEnhancer类,再看一下这个类的buildClasssifier函数内容:

m_Classifiers = Classifier.makeCopies(m_Classifier, m_NumIterations);

这句话是产生m_NumIterations个基分类器。

接下来的是判断是否用Resampling方法,这个先不讲,直接看下面的函数,先讲buildClassifierWithWeights这个函数,代码太长了,我分开讲:

// Select instances to train the classifier on

if (m_WeightThreshold < 100) {

       trainData = selectWeightQuantile(training,(double) m_WeightThreshold / 100);

} else {

        trainData = new Instances(training, 0, numInstances);

}

最上面那个循环m_Classifiers.length次的循环没有粘,这一段话也没什么意思,就是说先多少样本训练,默认的是100,不是100的时候用selectWeightQuantile函数,这个函数是根据样本权重的比例来选择的,它先根据权重对样本进行排序,再选择样本。如果是默认值,那么当然是选择全部样本。

// Build the classifier

if (m_Classifiers[m_NumIterationsPerformed] instanceof Randomizable)

        ((Randomizable) m_Classifiers[m_NumIterationsPerformed])

              .setSeed(randomInstance.nextInt());

m_Classifiers[m_NumIterationsPerformed].buildClassifier(trainData);

    有的分类器是一个Randomizable实例,那么就给它设置种子,然后训练一个分类器。

    // Evaluate the classifier

    evaluation = new Evaluation(data);        

    evaluation.evaluateModel(m_Classifiers[m_NumIterationsPerformed],training);

    epsilon = evaluation.errorRate();

 

    // Stop if error too small or error too big and ignore this model

    if (Utils.grOrEq(epsilon, 0.5) || Utils.eq(epsilon, 0)) {

       if (m_NumIterationsPerformed == 0) {

           // If we're the first we have to to use it

           m_NumIterationsPerformed = 1;

        }

       break;

    }

    这一段,看过论文的人应该比较清楚是什么意思,这里也就不解释了。

    // Determine the weight to assign to this model

    m_Betas[m_NumIterationsPerformed] = Math.log((1 - epsilon)/ epsilon);

    reweight = (1 - epsilon) / epsilon;

 

    // Update instance weights

    setWeights(training, reweight);

    第一行代码对应我刚才讲的论文的图5中的公式15,第二句对应公式13,最后一句对应公式14,下面详细讲一下:

    oldSumOfWeights = training.sumOfWeights();

    Enumeration enu = training.enumerateInstances();

    while (enu.hasMoreElements()) {

       Instance instance = (Instance) enu.nextElement();

       if (!Utils.eq(m_Classifiers[m_NumIterationsPerformed].

           classifyInstance(instance), instance.classValue()))

           instance.setWeight(instance.weight() * reweight);

    }

 

    // Renormalize weights

    newSumOfWeights = training.sumOfWeights();

    enu = training.enumerateInstances();

    while (enu.hasMoreElements()) {

       Instance instance = (Instance) enu.nextElement();

       instance.setWeight(instance.weight() * oldSumOfWeights / newSumOfWeights);

    }

这段代码也是adaboost的核心了,这个函数就是重新计算每个样本的权重,第一个if是判断是否分类错误,如果分类错误,就在原来的权重上乘上reweight(这地方我还有点不清楚,原论文上应该是分类正确了乘上reweight,公式14)。

底下的那部分代码就是重新归一化权重,没什么特别的。至于另一个函数buildClassifierUsingResampling,想想还是不讲了,与这个函数比较也没什么特别的地方。


你可能感兴趣的:(Weka开发[14]-AdaBoost源代码介绍)