Weka predict classifcation node

2020-03-30 04:21发布

问题:

I have created a huge j48 tree of size around 7000 with so many branches and leaves. I am getting classification result as well for test images. I would like to know which of the node is making the classification for each result. In other words, Is there a way with weka to see the id or something of the leaf node that makes the decision.

回答1:

As far as I know, you will not be able to do this from the Weka GUI. However, if you use the Weka API there is some hope. I am not an expert in Java, so the following steps may not follow the best practice, but it does work for the small example I concocted.

  1. Build the j48 tree in the Weka GUI and in the "more options" tab select "Output Source Code"

  2. Copy the source code to a new class in your Java code

  3. In the classifyInstance method augment the return variable to include a leaf number

  4. Modify the class so it no longer extends "Classifier" (this requires eliminating a few other methods in the class you just created)

Below is a class that will classify a Weka Instance with a decision stump classifier. The output will include a leaf number. This was built from the categorical weather data included in the Weka example datasets by following the above steps. For the huge decision tree you have it may be necessary to do some string replacement to efficiently augment your return variable.

import weka.core.Instance;

public class WekaWrapper {

  /**
   * Classifies the given instance.
   *
   * @param i the instance to classify
   * @return the classification result
   */
  public double[] classifyInstance(Instance i) throws Exception {
    Object[] s = new Object[i.numAttributes()];

    for (int j = 0; j < s.length; j++) {
      if (!i.isMissing(j)) {
        if (i.attribute(j).isNominal())
          s[j] = new String(i.stringValue(j));
        else if (i.attribute(j).isNumeric())
          s[j] = new Double(i.value(j));
      }
    }

    // set class value to missing
    s[i.classIndex()] = null;

    return WekaClassifier.classify(s);
  }
}
class WekaClassifier {
  public static double[] classify(Object[] i) {
    /* outlook */
      double[][] here=new double[3][2];
      here[0][0]=0; //leaf value
      here[0][1]=1; //leaf ID
      here[1][0]=0; //leaf value
      here[1][1]=2; //leaf ID
      here[2][0]=0; //leaf value
      here[2][1]=3; //leaf ID
    if (i[0] == null) { return here[0]; } else if (((String)i[0]).equals("overcast")) { return here[1]; } else { return here[2]; }
  }
}