我创建了一个大约7000个节点的大型J48决策树,包含许多分支和叶子。我也得到了测试图像的分类结果。我想知道是哪个节点对每个结果进行了分类。换句话说,有没有办法在Weka中查看做出决策的叶节点的ID或其他信息。
回答:
据我所知,你无法通过Weka的图形界面实现这一点。然而,如果你使用Weka的API,还是有希望的。我不是Java专家,所以以下步骤可能不是最佳实践,但对于我设计的小例子是有效的。
-
在Weka的图形界面中构建J48决策树,并在“更多选项”标签中选择“输出源代码”
-
将源代码复制到你的Java代码中的一个新类中
-
在classifyInstance方法中扩展返回变量以包含叶节点编号
-
修改类,使其不再扩展“Classifier”(这需要删除你刚创建的类中的其他几个方法)
下面是一个类,它将使用决策树桩分类器对Weka实例进行分类。输出将包括一个叶节点编号。这是通过遵循上述步骤,从Weka示例数据集中包含的分类天气数据构建的。对于你拥有的巨大决策树,可能需要进行一些字符串替换以有效地扩展你的返回变量。
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]; } }}