3

私はこの 1 か月ほど (私は学生です) Weka API を独学で学んでいます。私がやっていることは、特定のデータ セットをフィルター処理し、最終的にそのデータのベイズ ネットを構築するプログラムを作成することです。1 週間前に、離散化クラスと属性選択クラスを終了しました。ほんの数日前、離散化関数を教師付きに変更する必要があることに気付き、最終的にデフォルトの Fayyad & Irani メソッドを使用することになりました。これを行った後、属性選択クラスで次のエラーが発生し始めました。

Exception in thread "main" weka.core.WekaException: 
weka.attributeSelection.CfsSubsetEval: Not enough training instances with class labels (required: 1, provided: 0)!
at weka.core.Capabilities.test(Capabilities.java:1138)
at weka.core.Capabilities.test(Capabilities.java:1023)
at weka.core.Capabilities.testWithFail(Capabilities.java:1302)
at weka.attributeSelection.CfsSubsetEval.buildEvaluator(CfsSubsetEval.java:331)
at weka.attributeSelection.AttributeSelection.SelectAttributes(AttributeSelection.java:597)
at weka.filters.supervised.attribute.AttributeSelection.batchFinished(AttributeSelection.java:456)
at weka.filters.Filter.useFilter(Filter.java:663)
at AttributeSelectionFilter.selectionFilter(AttributeSelectionFilter.java:29)
at Runner.main(Runner.java:70)

変更前の属性選択はうまく機能していたので、離散化クラスで何か間違ったことをしたのではないかと思います。この質問の他の部分はそれに関連しています。なぜなら、離散化クラスが実際にはデータを離散化していないように見えることにも気づいたからです。すべての数値データを 1 つの範囲に入れるだけで、Fayyad & Irani のように戦略的にビニングするのではありません。

ここに私の離散化クラスがあります:

import weka.core.Instances;
import weka.filters.Filter;
import weka.filters.supervised.attribute.Discretize;
import weka.filters.unsupervised.attribute.NumericToNominal;

public class DiscretizeFilter
{
    private Instances data;
    private boolean sensitiveOption;
    private Filter filter = new Discretize();

    public DiscretizeFilter(Instances data, boolean sensitiveOption)
    {
        this.data = data;
        this.sensitiveOption = sensitiveOption;
    }

    public Instances discreteFilter() throws Exception
    {
        NumericToNominal nm = new NumericToNominal();
        nm.setInputFormat(data);
        Filter.useFilter(data, nm);
        Instances nominalData = nm.getOutputFormat();

        if(sensitiveOption)//if the user wants extra sensitivity
        {
            String options[] = new String[1];
            options[0] = options[0];
            options[2] = "-E";
            ((Discretize) filter).setOptions(options);
        }
        filter.setInputFormat(nominalData);
        Filter.useFilter(nominalData,filter);
        return filter.getOutputFormat();
    }
}

これが私の属性選択クラスです:

import weka.attributeSelection.BestFirst;
import weka.attributeSelection.CfsSubsetEval;
import weka.core.Instances;
import weka.filters.supervised.attribute.AttributeSelection;

public class AttributeSelectionFilter 
{
    public Instances selectionFilter(Instances data) throws Exception
    {
        AttributeSelection filter = new AttributeSelection();

        for(int i = 0; i < data.numInstances(); i++)
        {
            filter.input(data.instance(i));
        }
        CfsSubsetEval eval = new CfsSubsetEval();
        BestFirst search = new BestFirst();
        filter.setSearch(search);
        filter.setEvaluator(eval);

        filter.setInputFormat(data);
        AttributeSelection.useFilter(data, filter);

        return filter.getOutputFormat();
    }

    public int attributeCounter(Instances data)
    {
        return data.numAttributes();
    }
}

どんな助けでも大歓迎です!!!

4

2 に答える 2

0

調べてみたら、Discretizeクラスのメソッド「outputFormat()」の記述を勘違いした私のミスでした。代わりに useFilter() からフィルタリングされたインスタンスを取得し、問題を解決しました! 属性選択フィルターに間違ったタイプのデータを与えていました。

于 2012-10-29T17:45:01.387 に答える
0

内部的に Weka は属性値を double として保存します。データセット ( ) 内のすべてのインスタンスdataが「クラスを欠いている」ため、例外がスローされたようです。つまり、何らかの理由で内部クラス属性値 NaN (「数値ではない」) が与えられたようです。data'sクラス属性が正しく作成/設定されているかどうかを再確認することをお勧めします。

于 2012-10-23T21:55:59.077 に答える