16

我对 Weka 相当陌生,在命令行上对 Weka 更是陌生。我发现文档很差,我正在努力找出一些要做的事情。例如,想要获取两个 .arff 文件,一个用于训练,一个用于测试,并获取测试数据中缺失标签的预测输出。

我怎样才能做到这一点?

我有这个代码作为起点

java -classpath weka.jar weka.classifiers.meta.FilteredClassifier
-t "training_file_with_missing_values.arff"
-T "test_file_with_missing_values.arff"
-F weka.filters.unsupervised.attribute.ReplaceMissingValues -- -c last
-W weka.classifiers.functions.MultilayerPerceptron -- -L 0.3 -M 0.2 -H a

运行该代码给了我“非法选项 -c last”,我不知道为什么。我也不打算使用 MLP,因为当我从文本数据中获得几千个特征时,NN 往往会太慢。我知道如何将其更改为另一个分类器(例如 NB 或 libSVM,这很好)。

但我不确定如何在一次调用中添加多个过滤器,因为我还需要添加 StringToWordVector 过滤器(可能还有 Reorder 过滤器以使该类成为最后一个属性,而不是第一个属性)。

然后我如何让它实际输出每个类的预测标签?然后将这些与初始数据一起存储在 arff 中。

4

2 回答 2

41

Weka 并不是真正的文档示例,但您仍然可以在他们的网站上找到有关它的有价值的信息。你应该从Primer开始。我知道您想对文本文件进行分类,因此您还应该看看Text categorization with WEKA。还有一个新的Weka 文档站点

[编辑:Wikispaces 已经关闭,Weka 还没有在其他地方打开这些站点,所以我修改了指向 Google 缓存的链接。如果有人阅读了这篇文章并且新的 Weka Wiki 已经上线,请随时编辑链接并删除此注释。]

您在问题中发布的命令行包含错误。我知道,您从我对另一个问题的回答中复制了它,但我也刚刚注意到它。您必须省略-- -c last,因为ReplaceMissingValue过滤器不喜欢它。

在 Primer 中它说:

weka.filters.监督

类层次结构中低于 weka.filters.supervised 的类用于监督过滤,即利用类信息。必须通过 -c 分配一个类,以便 WEKA 默认行为使用-c last

butReplaceMissingValue是一个无监督过滤器,和 一样StringToWordVector

多个过滤器

添加多个过滤器也没有问题,这就是MultiFilter它的用途。不过,命令行可能会有点混乱:(我选择了RandomForest这里,因为它比 NN 快得多)。

java -classpath weka.jar weka.classifiers.meta.FilteredClassifier \
  -t ~/weka-3-7-9/data/ReutersCorn-train.arff \
  -T ~/weka-3-7-9/data/ReutersCorn-test.arff \
 -F "weka.filters.MultiFilter \
     -F weka.filters.unsupervised.attribute.StringToWordVector \
     -F weka.filters.unsupervised.attribute.Standardize" \
 -W weka.classifiers.trees.RandomForest -- -I 100 \

做出预测

以下是 Primer 关于获得预测的内容:

但是,如果需要有关分类器预测的更详细信息,-p # 仅输出每个测试实例的预测,以及一系列从 1 开始的属性 id(0 表示无)。

将这些常规选项-p 0直接放在您调用的类之后是一个很好的约定,因此命令行将是

java -classpath weka.jar weka.classifiers.meta.FilteredClassifier \
  -t ~/weka-3-7-9/data/ReutersCorn-train.arff \
  -T ~/weka-3-7-9/data/ReutersCorn-test.arff \
  -p 0 \
 -F "weka.filters.MultiFilter \
     -F weka.filters.unsupervised.attribute.StringToWordVector \
     -F weka.filters.unsupervised.attribute.Standardize" \
 -W weka.classifiers.trees.RandomForest -- -I 100 \

WEKA 分类器/过滤器的结构

但是正如你所看到的,从命令行调用 WEKA 会变得非常复杂。这是由于 WEKA 分类器和过滤器的树形结构。虽然每个命令行只能运行一个分类器/过滤器,但它的结构可以任意复杂。对于上述命令,结构如下所示:

FilteredClassifier 将在训练数据集上初始化一个过滤器,过滤训练和测试数据,然后在训练数据上训练一个模型并对给定的测试数据进行分类。

FilteredClassifier
 |
 + Filter
 |
 + Classifier

如果我们想要多个过滤器,我们使用 MultiFilter,它只是一个过滤器,但它会按照给定的顺序调用多个其他过滤器。

FilteredClassifier
 |
 + MultiFilter
 |  |
 |  + StringToWordVector
 |  |
 |  + Standardize
 |
 + RandomForest

从命令行运行这样的事情的困难部分是将所需的选项分配给正确的类,因为通常选项名称是相同的。例如,该-F选项也用于 theFilteredClassifier和 the MultiFilter,因此我必须使用引号来明确哪个 -F 属于哪个过滤器。

在最后一行中,您会看到-I 100属于的选项RandomForest不能直接附加,因为那样它将被分配给FilteredClassifier并且您将得到Illegal options: -I 100。因此,您必须--在它之前添加。

将预测添加到数据文件

添加预测的类标签也是可能的,但更复杂。AFAIK 这不能一步完成,但您必须先训练和保存模型,然后使用这个模型来预测和分配新的类标签。

训练和保存模型:

java -classpath weka.jar weka.classifiers.meta.FilteredClassifier \
  -t ~/weka-3-7-9/data/ReutersCorn-train.arff \
  -d rf.model \
  -F "weka.filters.MultiFilter \
      -F weka.filters.unsupervised.attribute.StringToWordVector \
      -F weka.filters.unsupervised.attribute.Standardize" \
  -W weka.classifiers.trees.RandomForest -- -I 100 \

这会将训练的模型序列化FilteredClassifier到文件rf.model中。这里重要的是初始化的过滤器也会被序列化,否则过滤后测试集将不兼容。

加载模型,进行预测并保存:

java -classpath weka.jar weka.filters.supervised.attribute.AddClassification \
  -serialized rf.model \
  -classification \
  -remove-old-class \
  -i ~/weka-3-7-9/data/ReutersCorn-test.arff \
  -o pred.arff \
  -c last
于 2013-03-16T10:43:06.163 回答
-1

使用 GUI Explorer 完成所有操作的更好方法。以下是如何做所有你想做的事:

1)取两个单独的文件进行训练和测试。

使用“预处理”选项卡下的“打开文件”选择您的训练文件。使用“分类”选项卡下的“提供的测试集”单选来选择您的测试文件。

2)输出缺失标签的预测。

使用“更多选项”并选择“分类”选项卡下的“输出预测”以查看预测。

3) 使用多个过滤器

使用“预处理”选项卡下的“过滤器”在分类之前应用任意数量的过滤器。

4) 使类成为最后一个属性

这实际上是不必要的。您可以选择任何属性作为您的类。类是您希望分类器预测的任何属性。使用 Classify 选项卡上的 Nom(Class) 下拉菜单选择哪个属性是您的类。

于 2013-03-15T20:33:53.153 回答