weka が提供する情報取得ライブラリを使用して属性の選択を評価しようとしていますが、インスタンスの分類方法を決定する属性が常に値を提供するとは限りません。説明が難しいので、以下に例を示します。
これが私の関係です。3 つの数値属性とクラス属性で構成されます。属性 3 の値が 5000 の場合、分類は不合格に設定されます。
@relation TEST
@attribute attr1 numeric
@attribute attr2 numeric
@attribute attr3 numeric
@attribute class {failing,correct}
@data
8, 0.519674, 5000, failing
?, 6.78149, ?, correct
?, 7.384081, 5000, failing
21, ?, ?, correct
5, 1.016151, 5000, failing
Information Gain Attribute Evaluator を実行した後の出力は次のとおりです。
=== Attribute Selection on all input data ===
Search Method:
Attribute ranking.
Attribute Evaluator (supervised, Class (nominal): 4 class):
Information Gain Ranking Filter
Ranked attributes:
0.249 1 attr1
0 3 attr3
0 2 attr2
Selected attributes: 1,3,2 : 3
ここで、属性 3 が最高ランクになるはずです。その値によって、インスタンスが失敗として分類されるか正しいとして分類されるかが決まるからです。しかし、どういうわけかそうではありません。
では、私の質問:情報ゲインの計算に欠損値を使用するように WEKA に指示するにはどうすればよいですか?
1 つの可能性は、欠損値を次のような定数で置き換えることです。
@relation TEST
@attribute attr1 numeric
@attribute attr2 numeric
@attribute attr3 numeric
@attribute class {failing,correct}
37, 9.295889, 5000, failing
48, ?, 0, correct
35, 14.722155, 5000, failing
?, 11.417347, 0, correct
?, 4.539502, 5000, failing
次に、ランキングが機能します。
=== Attribute Selection on all input data ===
Search Method:
Attribute ranking.
Attribute Evaluator (supervised, Class (nominal): 4 class):
Information Gain Ranking Filter
Ranked attributes:
0.971 3 attr3
0.249 1 attr1
0 2 attr2
Selected attributes: 3,1,2 : 3
しかし、アトリビュート 3 が持つ値を予測できないため、それは私が本当に望んでいるものではありません。
これが私のコードです:
public static void test() {
FastVector attributes = new FastVector();
Random rand = new Random();
Attribute attr1 = new Attribute("attr1");
Attribute attr2 = new Attribute("attr2");
Attribute attr3 = new Attribute("attr3");
attributes.addElement(attr1);
attributes.addElement(attr2);
attributes.addElement(attr3);
FastVector classValues = new FastVector(2);
classValues.addElement("failing");
classValues.addElement("correct");
Attribute classAttribute = new Attribute("class", classValues);
attributes.addElement(classAttribute);
Instances instances = new Instances("TEST", attributes, 5);
for (int i = 0; i < 5; i++) {
Instance instance = new Instance(4);
instance.setDataset(instances);
if (i % (rand.nextInt(4) + 1) == 0)
instance.setValue(attr1, rand.nextInt(50));
if (i % (rand.nextInt(4) + 1) == 0)
instance.setValue(attr2, rand.nextFloat() * 15);
if (i % 2 == 0) {
instance.setValue(attr3, 5000);
instance.setValue(classAttribute, "failing");
} else {
//instance.setValue(attr3, 0);
instance.setValue(classAttribute, "correct");
}
instances.add(instance);
}
instances.setClass(classAttribute);
instances.compactify();
System.out.println(instances);
try {
System.out.println(AttributeSelection.SelectAttributes(new InfoGainAttributeEval(), new String[]{"-s", "weka.attributeSelection.Ranker"}, instances));
} catch (Exception e) {
e.printStackTrace();
}
}
ありがとう!