13

我使用手动创建的一些训练数据训练了一个 IBK 分类器,如下所示:

ArrayList<Attribute> atts = new ArrayList<Attribute>();
ArrayList<String> classVal = new ArrayList<String>();
classVal.add("C1");
classVal.add("C2");
atts.add(new Attribute("a"));
atts.add(new Attribute("b"));
atts.add(new Attribute("c"));
atts.add(new Attribute("d"));
atts.add(new Attribute("@@class@@", classVal));

Instances dataRaw = new Instances("TestInstances", atts, 0);
dataRaw.setClassIndex(dataRaw.numAttributes() - 1);
double[] instanceValue1 = new double[]{3,0,1,0,0};
dataRaw.add(new DenseInstance(1.0, instanceValue1));

double[] instanceValue2 = new double[]{2,1,1,0,0};
dataRaw.add(new DenseInstance(1.0, instanceValue2));

double[] instanceValue3 = new double[]{2,0,2,0,0};
dataRaw.add(new DenseInstance(1.0, instanceValue3));

double[] instanceValue4 = new double[]{1,3,0,0,1};
dataRaw.add(new DenseInstance(1.0, instanceValue4));

double[] instanceValue5 = new double[]{0,3,1,0,1};
dataRaw.add(new DenseInstance(1.0, instanceValue5));

double[] instanceValue6 = new double[]{0,2,1,1,1};
dataRaw.add(new DenseInstance(1.0, instanceValue6));

然后我建立分类器:

IBk ibk = new IBk();
try {
    ibk.buildClassifier(dataRaw);

} catch (Exception e) {
    e.printStackTrace();
}

我想用未标记的类创建一个新实例并对这个实例进行分类,我尝试了以下方法,但没有成功。

IBk ibk = new IBk();
try {
    ibk.buildClassifier(dataRaw);
    double[] values = new double[]{3,1,0,0,-1};
    DenseInstance newInst = new DenseInstance(1.0,values);
    double classif = ibk.classifyInstance(newInst);
    System.out.println(classif);
} catch (Exception e) {
    e.printStackTrace();
}

我只是收到以下错误

weka.core.UnassignedDatasetException: DenseInstance doesn't have access to a dataset!
at weka.core.AbstractInstance.classAttribute(AbstractInstance.java:98)
at weka.classifiers.AbstractClassifier.classifyInstance(AbstractClassifier.java:74)
at TextCategorizationTest.instancesWithDoubleValues(TextCategorizationTest.java:136)
at TextCategorizationTest.main(TextCategorizationTest.java:33)

看起来我在创建新实例时做错了什么。我怎样才能准确地创建一个未标记的实例?

提前致谢

4

3 回答 3

15

当您对未与数据集关联的新实例进行分类时,您将看到此错误。您必须使用 . 将您创建的每个新实例关联到一个Instances对象setDataset

//Make a place holder Instances
//If you already have access to one, you can skip this step
Instances dataset = new Instances("testdata", attr, 1);
dataset.setClassIndex(classIdx);

DenseInstance newInst = new DenseInstance(1.0,values);

//To associate your instance with Instances object, in this case dataset
newInst.setDataset(dataset); 

在此之后,您可以对新创建的实例进行分类。

double classif = ibk.classifyInstance(newInst);

http://www.cs.tufts.edu/~ablumer/weka/doc/weka.core.Instance.html

详细实现链接

于 2015-01-25T19:46:15.117 回答
13

问题在于这一行:

double classif = ibk.classifyInstance(newInst);

当您尝试进行分类newInst时,Weka 会抛出异常,因为newInst没有与之关联的 Instances 对象(即数据集) - 因此它不知道有关其类属性的任何信息。

您应该首先创建一个类似于 dataRaw 的新 Instances 对象,将未标记的实例添加到其中,设置类索引,然后才尝试对其进行分类,例如:

Instances dataUnlabeled = new Instances("TestInstances", atts, 0);
dataUnlabeled.add(newInst);
dataUnlabeled.setClassIndex(dataUnlabeled.numAttributes() - 1);        
double classif = ibk.classifyInstance(dataUnlabeled.firstInstance());
于 2012-08-29T19:11:42.673 回答
-1

请参阅 WEKA 文档的第 203 - 204 页。这对我帮助很大!(Weka 手册是一个 pdf 文件,位于您的 weka 安装文件夹中。只需打开 doucmentation.html,它将指向您的 pdf 手册。)

复制粘贴第 17 章(使用 WEKA API / 在内存中创建数据集)的代码清单的一些片段应该可以帮助您解决任务。

于 2013-03-27T23:59:09.823 回答