Weka開發[14]-AdaBoost源代碼介紹

這一次講的是Ensemble的東西,一位讀者但願我講一下Adaboost的內容,這種Ensemble看起來的確比較嚇人,推薦一篇論文:Ensemble Based Systems in Decision Making. 在這裏全部理論的東西我就不介紹了。dom

與以往同樣,先看buildClassifier函數(我在函數中將不重要的代碼所有去掉):函數

super.buildClassifier(data);ui

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

       buildClassifierWithWeights(data);lua

} else {spa

       buildClassifierUsingResampling(data);orm

}排序

Adaboost類繼承自RandomizableIteratedSingleClassifierEnhancer類,再看一下這個類的buildClasssifier函數內容:繼承

m_Classifiers = Classifier.makeCopies(m_Classifier, m_NumIterations);ci

這句話是產生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,想一想仍是不講了,與這個函數比較也沒什麼特別的地方。

相關文章
相關標籤/搜索