0

インスタンスの分類器をトレーニングしましたが、Weka ライブラリが利用できない Android アプリケーションにエクスポートしたいと考えています。

そのサイズ (6.5 Mb) のため、単純に Android アプリケーションに Weka ライブラリを追加するのは適切ではありません。

分類器を使用して他のラベルのないインスタンスを評価してラベルを付ける他の方法はありますか? このために特別に設計された、より小さな独立したライブラリはありますか?

もちろん、最終的には、Weka の出力モデルを解釈する独自のライブラリを作成することもできますが、そのようなソリューションが既に存在することは論理的に思えます。(なんとなく逃げられますが)

4

3 に答える 3

2

あなたが望むことをする独立したライブラリはありません。不要なWekaのすべての部分を削除して、ライブラリにパッケージ化することができます。

if...elseあなたの特定のケースでは、Wekaが学習した決定木を取得し、それを一連のステートメントのコードに直接配置するのが最も簡単な方法かもしれません。デシジョンツリーの(グラフィカルな)出力を取得し、そのコードを作成するスクリプトを作成することもできます。

于 2013-01-24T18:32:14.840 に答える
1

wekaの出力モデルにもっと注意を払った後、Javaクラス形式でツリーを生成するオプションを使用することで、wekaライブラリとは別に使用できることに気付きました。

生成されたWekaWrapperを削除して、ツリーの基本的な実装である内部クラスのみを保持できます。

クラスは次のようになります。

public class WekaWrapper
  extends Classifier {

  /**
   * Returns only the toString() method.
   *
   * @return a string describing the classifier
   */
  public String globalInfo() {
    return toString();
  }

  /**
   * Returns the capabilities of this classifier.
   *
   * @return the capabilities
   */
  public Capabilities getCapabilities() {
    weka.core.Capabilities result = new weka.core.Capabilities(this);

    result.enable(weka.core.Capabilities.Capability.NOMINAL_ATTRIBUTES);
    result.enable(weka.core.Capabilities.Capability.NOMINAL_CLASS);
    result.enable(weka.core.Capabilities.Capability.MISSING_CLASS_VALUES);

    result.setMinimumNumberInstances(0);

    return result;
  }

  /**
   * only checks the data against its capabilities.
   *
   * @param i the training data
   */
  public void buildClassifier(Instances i) throws Exception {
    // can classifier handle the data?
    getCapabilities().testWithFail(i);
  }

  /**
   * 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);
  }

  /**
   * Returns the revision string.
   * 
   * @return        the revision
   */
  public String getRevision() {
    return RevisionUtils.extract("1.0");
  }

  /**
   * Returns only the classnames and what classifier it is based on.
   *
   * @return a short description
   */
  public String toString() {
    return "Auto-generated classifier wrapper, based on weka.classifiers.trees.Id3 (generated with Weka 3.6.9).\n" + this.getClass().getName() + "/WekaClassifier";
  }

  /**
   * Runs the classfier from commandline.
   *
   * @param args the commandline arguments
   */
  public static void main(String args[]) {
    runClassifier(new WekaWrapper(), args);
  }
}

class WekaClassifier {
  private static void checkMissing(Object[] i, int index) {
    if (i[index] == null)
      throw new IllegalArgumentException("Null values are not allowed!");
  }

  public static double classify(Object[] i) {
    return node0(i);
  }

  protected static double node0(Object[] i) {
    return 0.0; // unacc
  }
}

だから、ええ、実際にはあなたはそれを本当に簡単に行うことができます。覚えておくべきこと:

  • インスタンスを分類するには、classify(Object [])メソッドを呼び出します。
  • 戻り値はfloat値になります。
  • 戻り値は、returnコマンドのすぐ隣のコメントで説明されています。
  • パラメータには検証がないため、入力する順序に注意してください(この部分はweka依存部分によって行われました)。
  • 順序は、arffファイルで定義されている順序です。
于 2013-01-25T21:47:01.967 に答える