1

非常に多くの枝と葉を持つ、サイズが約 7000 の巨大な j48 ツリーを作成しました。テスト画像の分類結果も取得しています。どのノードが各結果の分類を行っているかを知りたいです。つまり、weka を使用して、決定を行うリーフ ノードの ID などを確認する方法はありますか。

4

1 に答える 1

0

私の知る限り、Weka GUI からこれを行うことはできません。ただし、Weka API を使用する場合は、いくつかの希望があります。私は Java の専門家ではないため、次の手順はベスト プラクティスに従っていない可能性がありますが、作成した小さな例では機能します。

  1. Weka GUI で j48 ツリーをビルドし、[その他のオプション] タブで [ソース コードの出力] を選択します。

  2. ソース コードを Java コードの新しいクラスにコピーする

  3. classifyInstanceメソッドで、戻り変数を増やしてリーフ番号を含めます

  4. 「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]; }
  }
}
于 2013-10-10T04:09:09.350 に答える