Weka manual 3.6翻译: 16.5 过滤

16.5 过滤

在WEKA中,过滤器用来进行数据预处理。他们可以在weka.filters包中找到。各过滤器可归为以下两类别之一:

      有监督 -过滤器需要设置一个类属性。

      无监督 - 类的属性可以不存在。

并且可归为两个子类之一:

      基于属性 -处理列,例如,添加或删除列。

      基于实例 -处理行,例如,添加或删除行。

这些类别表明了Weka中两个 离散化 过滤器之间的区别。有监督的 过滤器需要考虑数据集中类的属性及其分布,以确定最佳的容器的数量和规模,而 无监督的 过滤器依赖于用户指定容器的数量。

除了这种分类,过滤器也可分为基于数据流或基于批处理。 过滤器可以马上处理数据,使其立即可以再次收集。另一方面,批量 过滤器,需要一个批次的数据,来设置它们的内部数据结构。Add 过滤器(过滤器可以发现在 weka.filters.unsupervised.attribute 包)是流过滤器的一个例子。添加一个只包含缺失值的新属性,不需要任何复杂的设置。然而,ReplaceMissingValues 过滤器(与 Add 过滤器 类似的包 )需要一个批次的数据,以确定每个属性的平均值和模式。否则,过滤器将无法用有意义的值来代替缺失值。但只要批量过滤器已用第一批数据初始化,它也可以一行一行地处理数据,就像一个流过滤器。

基于实例的 过滤器在处理数据上有点特别。正如前面提到的,首批数据处理完后, 所有 过滤器都可以一行一行地处理数据。当然,如果过滤器是从一批数据中添加或删除行,当它工作于单行处理模式下这将不再有效。这是有道理的,如果你想到一个涉及 FilteredClassifier 元分类器的场景:训练阶段(第一批数据)完后,分类器将从测试集得到评估,一次一个实例。现在,如果过滤器移除唯一的实例,或添加一些实例,它将不再被正确评估,因为评估过程期望只得到一个唯一的返回结果。这就是为什么 基于实例的 过滤器只传递任何后续批次的数据,不作任何处理的原因。例如,Resample 过滤器就是这样的。

可以在WEKA Example 集合的 wekaexamples.filters 包中找到过滤器的示例类

下面的示例使用 Remove 过滤器(过滤器位于 weka.filters.unsupervised.attribute包中)删除数据集中的第一个属性。设置选项, 传递setOptions(字符串[]) 方法。

import weka.core.Instances;

import weka.filters.Filter;

import weka.filters.unsupervised.attribute.Remove;

String[] options = new String[2];

options[0] = "-R"; // "range"

options[1] = "1"; // first attribute

Remove remove = new Remove(); // new instance of filter

remove.setOptions(options); // set options

remove.setInputFormat(data); // inform filter about dataset

// **AFTER** setting options

Instances newData = Filter.useFilter(data, remove); // apply filter

一个常见的陷阱是, setInputFormat(Instances) 被调用后才设置选项。由于这个方法(通常情况下)用于确定输出的数据格式,所有选项必需调用前设置。否则,所有之后设置的选项将被忽略。

16.5.1 批量过滤

如果如果两个或两个以上的数据集需要根据相同的过滤器初始化进行处理,批量过滤是必要的,如果不使用批量过滤,例如,当使 StringToWordVector 过滤器( weka.filters.unsupervised.attribute包)一个训练集和一个测试集,那么这两个过滤器的运行是完全独立的,并会带来两个很可能不兼容的数据集。在两个不同的数据集上运行 StringToWordVector ,这将产生两个不同的词典,因此产生不同的属性。

下面的代码示例显示了如何使用Standardize 过滤器(weka.filters.unsupervised.attribute包)规范化(即把所有数值属性转化成具有零均值和单位方差)训练集和测试集:

Instances train = ... // from somewhere Instances test = ...              // from somewhere

Standardize filter = new Standardize(); // initializing the filter once with training set

filter.setInputFormat(train);

// configures the Filter based on train instances and returns

/ /过滤实例

Instances newTrain = Filter.useFilter(train, filter);

/ /创建一个新的测试集

Instances newTest = Filter.useFilter(test, filter);

16.5.2 运行中(on-the-fly)过滤

即使使用API为我们提供了一个完整控制数据的方式,使得在同一时间处理几个数据集变得方便,运行中(on-the-fly)过滤数据将使我们的工作更方便。这个方便的功能是可以通过WEKA的元方案(meta schemes)实现,如FilteredClassifier(package weka.classifiers.meta),FilteredClusterer (package weka.clusterers),FilteredAssociator(package weka.associations) and FilteredAttributeEval/FilteredSubsetEval(in weka.attributeSelection). 相比于事先 过滤数据 我们只要设置一个元方案,让它去过滤。

下面的例子使用 FilteredClassifier Remove 过滤器,一起删除数据集的第一个属性(这恰好是一个ID属性), 其中使用J48(J48是WEKA的C4.5的实现,包 weka.classifiers.trees)作为基分类器。首先,用一个训练集创建分类器,然后用独立的测试集测试分类器。实际和预测的类值打印到控制台上。关于分类的更多信息,请参阅第16.6章。

import weka.classifiers.meta.FilteredClassifier;

import weka.classifiers.trees.J48;

import weka.core.Instances;

import weka.filters.unsupervised.attribute.Remove;

...

Instances train = ... // from somewhere

Instances test = ... // from somewhere

// filter

Remove rm = new Remove();

rm.setAttributeIndices("1"); // remove 1st attribute

// classifier

J48 j48 = new J48();

j48.setUnpruned(true); // using an unpruned J48

// meta-classifier

FilteredClassifier fc = new FilteredClassifier();

fc.setFilter(rm);

fc.setClassifier(j48);

// train and output model

fc.buildClassifier(train);

System.out.println(fc);

for (int i = 0; i < test.numInstances(); i++)

{ double pred = fc.classifyInstance(test.instance(i));

 double actual = test.instance(i).classValue();

System.out.print("ID: "

+ test.instance(i).value(0));

System.out.print(", actual: "

+ test.classAttribute().value((int) actual));

System.out.println(", predicted: "

+ test.classAttribute().value((int)pred)); }

你可能感兴趣的:(weka)