Search code examples
javaweka

How to implement AdaBoostM1 in Weka?


I'm using Weka 3.6.13 (latest at the time of posting) and I can't seem to get AdaBoostM1 to select a classifier. I would like to include options for both AdaBoostM1 as well as for the base classifier. But the function setClassifier() just don't seem to exist in the JAR but is present in the Docs.

import java.io.*;
import weka.classifiers.Classifier;
import weka.classifiers.Evaluation;
import weka.classifiers.evaluation.NominalPrediction;
import weka.classifiers.meta.AdaBoostM1;
import weka.classifiers.trees.RandomForest;
import weka.core.FastVector;
import weka.core.Instances;

public class ULCWekaTest
{

   public static Evaluation classify(Classifier model,
                                     Instances trainingSet, Instances testingSet)
      throws Exception
   {
      Evaluation evaluation = new Evaluation(trainingSet);

      model.buildClassifier(trainingSet);
      evaluation.evaluateModel(model, testingSet);

      return evaluation;
   }

   public static double calculateAccuracy(FastVector predictions)
   {
      double correct = 0;

      for(int i = 0; i < predictions.size(); i++)
      {
         NominalPrediction np = (NominalPrediction) predictions.elementAt(i);
         if(np.predicted() == np.actual())
            correct++;
      }

      return 100 * correct / predictions.size();
   }

   public static void main(String[] args) throws Exception
   {
      String basepath =
         "/Users/Ebe/Pantheon/Ares/PhD/Course Work/MLT/MLT-Lab/Mini Project/Implementation/";

      Instances trainData;
      try(BufferedReader reader =
         new BufferedReader(
            new FileReader(basepath + "train80.arff")))
      {
         trainData = new Instances(reader);
         reader.close();
      }
      trainData.setClassIndex(0);

      Instances testData;
      try(BufferedReader reader =
         new BufferedReader(
            new FileReader(basepath + "test80.arff")))
      {
         testData = new Instances(reader);
         reader.close();
      }
      testData.setClassIndex(0);

      Classifier forest, adaboost;
      String[] options = new String[2];

      for(int i = 100; i < 500; i+=2)
      {
         for(int s = 6; s <= 6; s++)
         {
            adaboost = new AdaBoostM1();
            forest = new RandomForest();
            //for(String str : forest.getOptions())
               // System.out.println(str);   
            options[0] = "-I";
            options[1] = ""+i;
            forest.setOptions(options);

            options[0] = "-S";
            options[1] = "" + s;
            forest.setOptions(options);

            adaboost.setClassifier(forest); // <-- COMPILER ERROR AT THIS POINT
            // Collect every group of predictions for current model in a FastVector
            FastVector predictions = new FastVector();
            // For each training-testing split pair, train and test the classifier
            Evaluation validation =
               classify(adaboost, trainData, testData);
            predictions.appendElements(validation.predictions());

            // Calculate overall accuracy of current classifier on all splits
            double accuracy = calculateAccuracy(predictions);
         // Print current classifier's name and accuracy in a complicated,
            // but nice-looking way.
            System.out.println("-I " + i + " -S " + s + ": " + String.format(
               "%.2f%%", accuracy));
         }
      }
   }
}

Am I doing something wrong? How to fix this? Could anyone please explain or at least provide a link to a sample AdaBoostM1-Weka code in Java?


Solution

  • The Classifier class was being used. This is a base class of the AdaBoostM1 and RandomForest classifier. Hence you would not have access to the selectClassifier() method as it is from a class derived from Classifier.

    Changing this line

    Classifier forest, adaboost;
    

    to

    Classifier forest;
    AdaBoostM1 adaboost;
    

    solved the problem.