2.2 预处理
Preprocess标签页可用于从文件、URL或数据库中加载数据集,并且根据应用要求或领域知识过滤掉不需要进行处理或不符合要求的数据。
2.2.1 加载数据
Preprocess标签页中顶部的前四个按钮可以让用户将数据加载到Weka系统。Open file按钮用于启动“打开”对话框,用户可以浏览本地文件系统,打开本地数据文件。Open URL按钮要求用户提供一个URL地址,Weka使用HTTP协议从网络位置下载数据文件。Open DB按钮用于从数据库中读取数据,支持所有能够用JDBC驱动程序读取的数据库,使用SQL语句或存储过程读取数据表。注意,必须根据自己的计算机环境配置,相应修改weka\experiment\DatabaseUtils.props配置文件后才能访问数据库,具体参见1.4节内容。Generate按钮用于让用户使用不同的DataGenerators(数据生成器)生成人工数据,适用于分类功能的人工数据可以由决策列表RDG1、径向基函数网络RandomRBF、贝叶斯网络BayesNet、LED24等算法产生,人工回归数据也可以根据数学表达式生成,用于聚类的人工数据可以使用现成的生成算法产生。
使用Open file按钮,可以读取多种数据格式的文件,包括Weka ARFF格式、C4.5数据格式、CSV格式、JSON实例文件格式、LibSVM数据文件格式、Matlab ASCII文件格式、svm轻量级数据文件格式、XRFF格式,以及序列化实例的格式。其中,ARFF格式的后缀为.arff,C4.5数据格式的后缀为.data或.names,CSV格式的后缀为.csv,JSON实例文件格式的后缀为.json,LibSVM数据文件格式的后缀为.libsvm,Matlab ASCII文件格式的后缀为.m,svm轻量级数据文件格式的后缀为.dat,XRFF格式的后缀为.xrff,序列化实例对象文件的后缀为.bsi。有的格式后缀还会加上.gz,这代表对应文件的压缩形式。
另外,使用Save(保存)按钮,可以将已加载的数据保存为Weka支持的文件格式。该功能特别适合在不同文件格式之间进行转换,以及学习Weka文件格式的细节。
由于存在多种数据格式,为了从不同种类的数据源中导入数据,Weka提供实用工具类进行转换,这种工具称为转换器(converters),位于weka.core.converters包中。按照功能的不同,转换器分为加载器和保存器,前者的Java类名以Loader结束,后者以Saver结束。
加载数据后,Preprocess标签页会在Current relation(当前关系)选项组中显示当前数据集的一些总结信息。Relation(关系)栏显示关系名称,该名称由加载的文件给定;Attributes(属性)栏显示数据集中的属性(或特征)个数;Instances(实例)栏显示数据集中的实例(或数据点/记录)个数;Sum of weights(权重和)栏显示全部实例的权重之和。例如,当加载iris数据集后,Current relation选项组中显示关系名称为iris,属性个数为5,实例个数为150,权重和为150,如图2.11所示。
图2.11 Current relation选项组
Weka根据文件后缀调用不同的转换器来加载数据集。如果Weka无法加载数据,就会尝试以ARFF格式解释数据,如果再次失败,就会弹出如图2.12所示的提示对话框,提示Weka无法自行决定使用哪一个文件加载器,需要用户自己来选择。
图2.12 加载数据失败
单击图2.12中的“确定”按钮后,会弹出如图2.13所示的通用对象编辑器对话框,让用户选择能打开数据文件的对应转换器。默认转换器为CSVLoader,该转换器专门用于加载后缀为.csv的文件。如果用户已经确定数据文件格式是CSV格式,那么可以输入日期格式、字段分割符等信息。如果对对话框里的各选项不了解,可以单击More按钮查看使用说明。
图2.13 通用对象编辑器对话框
如果用户已经知道数据文件格式不是CSV格式,可以单击通用对象编辑器对话框上部的Choose按钮选择其他的转换器,如图2.14所示。
图2.14 选择转换器
图2.14所示对话框中,第一个选项是ArffLoader,选择该选项并成功的可能性很小,因为默认就是使用它来加载数据集,没有成功才会弹出加载数据失败的提示对话框。第二个选项是C45Loader,C4.5格式的数据集由两个文件共同构成,一个文件(.names)提供字段名,另一个文件(.data)提供实际数据。第三个选项是默认的CSVLoader,这是一种以逗号分隔各属性的文件格式,前文已经介绍了这种数据转换器。第四个选项DatabaseLoader是从数据库,而不是文件中读取数据集。然而,使用第1章介绍的SQLViewer工具来访问数据库,是更为人性化且方便的方案。SerializedInstancesLoader选项用于重新加载以前作为Java序列化对象保存的数据集。任何Java对象都可以采用这种格式予以保存并重新加载。由于序列化对象本身就是Java格式,使用它可能比加载ARFF文件的速度更快,这是因为加载ARFF文件时必须对其进行分析和检查,从而花费更多的时间。如果需要多次加载大数据集,则很值得以这种数据格式进行保存。
值得一提的是TextDirectoryLoader加载器,它的功能是导入一个目录,目录中包含若干以文本挖掘为目的的纯文本文件。导入目录应该有特定的结构——一组子目录,每个子目录包含一个或多个扩展名为.txt的文本文件,每个文本文件都会成为数据集中的一个实例,其中,一个字符串型属性保存该文件的内容,一个标称型的类别属性保存文件所在的子目录名称。该数据集可以通过使用StringToWordVector过滤器进一步加工为词典,为后面的文本挖掘做准备。
2.2.2 属性处理
在Current relation选项组下方,可以看到Attributes(属性)选项组,该选项组上部有四个按钮,中部是一个三列多行的表格,下部有一个Remove按钮,如图2.15所示。
图2.15 Attributes选项组
表格有三列表头,包括No.(序号)列、复选框列和Name(名字)列。其中,序号列用于标识指定数据集中的属性序号;复选框列用于选择属性,以便对其进行操作;名字列显示属性名称,这些名称与数据文件的属性声明一致。
表格里每行表示一个属性,单击某一行的复选框选中该行,再单击一次则取消选中。表格上方的四个按钮也可以用于改变选中状态:All按钮使全部复选框都选中,即选中全部属性;None按钮使全部复选框都取消选中,即不选中任何属性;Invert按钮反选,即取消选中已经选中的复选框,选中没有选中的复选框;Pattern按钮使用Perl 5正则表达式指定要选中的属性,例如,“.*_id”选择满足属性名称以_id结束的全部属性。
一旦已经选中所需的属性,就可以单击属性列表下方的Remove按钮将它们去除,本功能用于去除无关属性。注意,本功能仅去除内存中的数据集,不会更改数据文件的内容。另外,属性去除之后还可以单击Undo按钮进行撤销,Undo按钮位于Preprocess标签页的上部。
如果选中某一个属性,例如,选中图2.15中名称为sepallength的属性,该行的颜色就会变为蓝色,并且右边的Selected attribute(已选择属性)选项组中将显示选中属性的一些信息。图2.16和图2.17所示分别为选中数值型属性和标称型属性的显示结果。
图2.16 选中数值型属性的显示结果
图2.17 选中标称型属性的显示结果
其中,Name栏显示属性的名称,与属性表格中选中属性的名称相同;Type栏显示属性的类型,最常见的是标称型和数值型;Missing(缺失)栏显示数据集中该属性不存在或未指定的实例的数量及百分比;Distinct(不同)栏显示该属性取不同值的数量;Unique(唯一)栏显示没有任何其他实例拥有该属性值的数量及百分比。
Selected attribute选项组的下部有一个统计表格,显示该属性值的更多信息,根据属性类型的不同,表格会有所差别,从图2.16和图2.17中可以看到这一点。如果属性是数值型,表格显示数据分布的四种统计描述,即Minimum(最小值)、Maximum(最大值)、Mean(平均值)和StdDev(Standard Deviation,标准偏差或标准差)。如果属性是标称型,表格中显示:No.(编号),表示属性的全部可能取值;Label(标签),表示属性值名称;Count(数量),表示拥有该属性值的实例数量;Weight(权重),表示拥有该属性值的实例权重。
在统计表格下方会显示一个彩色直方图,如图2.18所示。直方图上部有一个下拉列表框,用于选择类别属性。图2.18中选择的类别属性是class,三种颜色代表三种不同类别的鸢尾花,横坐标表示当前属性(sepallength)的取值。注意,只有标称型的类别属性才会有彩色编码。单击右边的Visualize All按钮,会弹出一个单独的窗口,显示所有属性的直方图,如前面的图2.9所示。
图2.18 彩色直方图
2.2.3 过滤器
Preprocess标签页允许定义并执行以各种方式转换数据的过滤器,过滤器也称为筛选器。在Filter选项组中有一个Choose(选择)按钮,单击该按钮可以选择一个过滤器,如图2.19所示。按钮的右侧是过滤器文本框,用于设置所选择的过滤器参数。
图2.19 过滤器
一旦选定了过滤器,其名称和参数都会显示在过滤器文本框内。在文本框内单击,会弹出通用对象编辑器对话框,如图2.20所示。
图2.20 通用对象编辑器对话框
该通用对象编辑器对话框用于设置过滤器选项。此外,既然名称里有“通用”二字,显然该对话框还可以用于设置其他对象,如分类器和聚类器等,详见后文。图2.20所示对话框中的About选项组简要说明所选择过滤器的功能;单击右侧的More按钮,会弹出Information对话框,显示过滤器的简介和不同选项的功能,如图2.21所示;单击Capabilities按钮,会弹出Information about Capabilities对话框,列出所选择对象能够处理的类别类型和属性类型,如图2.22所示。
图2.21 Information对话框
图2.22 Information about Capabilities对话框
在图2.20所示对话框的中部,attributeIndices文本框用于让用户输入要删除(因为此处为Remove过滤器)属性的索引(或下标);如果将debug下拉列表框设置为True,过滤器会在控制台输出额外信息;如果将doNotCheckCapabilities下拉列表框设置为True,在构建过滤器之前将不检查过滤器的能力,谨慎使用以减少运行时间;invertSelection下拉列表框中只有True和False两个选项,指示是否反选。对话框下端有四个按钮:Open按钮用于打开所保存的对象选项设置;Save按钮用于保存对象选项设置,以备将来使用;OK按钮用于正确完成设置后,返回探索者界面;Cancel按钮用于取消所做的修改,回退到原来的状态。
右击(或在按住Alt键和Shift键的同时单击)过滤器文本框,弹出的快捷菜单中有四个菜单项:Show properties(显示属性)、Copy configuration to clipboard(复制设置到剪贴板)、Enter configuration(输入设置)和Edit configuration(编辑设置)。如果选择Show properties菜单项,就会弹出通用对象编辑器对话框,允许用户修改设置,其功能与单击过滤器文本框一样;如果选择Copy configuration to clipboard菜单项,则将当前的设置字符串复制到剪贴板,以便用于Weka以外的系统中,当用户设置了很长而复杂的选项设置字符串并且想将来复用时,该功能尤其方便;如果选择Enter configuration菜单项,则弹出“输入”对话框,让用户直接输入设置字符串,格式为类名称后接类能够支持的选项,如图2.23所示;如果选择Edit configuration菜单项,则弹出如图2.24所示的“输入”对话框,让用户直接编辑设置字符串。
图2.23 “输入”对话框(1)
图2.24 “输入”对话框(2)
一旦选择并配置好一个过滤器之后,就可以将其应用到数据集。单击位于Preprocess标签页中Filter选项组右端的Apply按钮应用过滤,Preprocess标签页会显示转换后的数据信息。如果对结果不满意,可以单击Undo按钮撤销转换,还可以单击Edit按钮在数据集编辑器里手动修改数据。如果满意修改后的结果,可以单击Preprocess标签页右上角的Save按钮,将当前关系以文件格式进行保存,以供将来使用。
使用直方图上部的下拉列表框,可以设置类别属性。根据是否设置类别属性,有些过滤器的行为会有所不同。特别地,有监督过滤器要求设置类别属性;一些无监督属性过滤器会忽略类别属性,即使已经设置了类别属性。
注意: 如果不想设置类别属性,可以将类别属性设置为No class。
2.2.4 过滤器算法介绍
本节介绍在Weka中实现的过滤算法,这些过滤算法都可以用于探索者、知识流和实验者界面。
所有的过滤器都是对输入数据集进行某种程度的转换,将其转换为适合数据挖掘的形式。选择某个过滤器之后,过滤器的名字及默认参数会出现在Choose按钮旁的过滤器文本框内,通过单击该文本框,可以在通用对象编辑器对话框中设置其属性。过滤器以及参数都会以命令行的方式显现在文本框中,仔细观察和研究这些过滤器和参数设置,是学习如何直接使用Weka命令的好方法。
Weka过滤器分为无监督过滤器和有监督过滤器两种。过滤器经常应用于训练集,然后再应用于测试集。如果过滤器是有监督的,例如,使用类别值的离散化过滤器是有监督的,它会使用类别值以得到良好的离散化间隔,但如果将有监督的离散化过滤器在测试集中训练并应用,由于已经提前“看到”并“使用”了测试集中的类别信息,可能会使结果出现偏倚。因此,使用有监督的过滤器时,必须非常小心,以确保评估结果的公平性。例如,有监督的离散化过滤器必须仅从训练集中通过训练得到离散化间隔,并将这些间隔应用到测试集中。然而,由于无须经过训练,无监督过滤器就不会出现这个问题。
Weka将无监督和有监督两种过滤方法分开处理,每种类型又细分为属性过滤器和实例过滤器,前者作用于数据集中的属性,后者作用于数据集中的实例。要了解某个过滤器的更多使用信息,可在Weka探索者界面中选择该过滤器,并查看对应的对象编辑器,以了解该过滤器的功能和选项。
Weka实现的过滤器的更详细介绍请参见附录B,附录B中按照字母顺序列出各过滤器的功能及选项。本节按照过滤器的类型和功能进行介绍。
1.无监督属性过滤器
1)添加和删除属性
Add过滤器在一个给定的位置插入一个属性,对于所有实例该属性值声明为缺失。使用通用对象编辑器对话框来指定属性名称,指定的属性名称会出现在属性列表中,标称型属性还可以指定可能值,日期型属性还可以指定日期格式。Copy过滤器复制现有属性,这样就可以在实验时保护这些属性,以免属性值为过滤器所覆盖。使用表达式可以一起复制多个属性,例如,“1-3”复制前三个属性,“first-3,5,9-last”复制属性“1、2、3、5、9、10、11、12、…”。选择可以进行反转,即反选,反选选中除了选定属性以外的所有属性。很多过滤器都拥有表达式和反选功能。
AddID过滤器在用户指定索引的属性列表中插入一个数字标识符属性。标识符属性常用于跟踪某个实例,尤其是在已经通过某种方式处理过数据集之后,例如,通过其他过滤器进行过转换,或者随机化重排实例的顺序之后,此时标识符便于跟踪。
Remove过滤器删除数据集中指定范围的属性,与之类似的有RemoveType过滤器和RemoveUseless过滤器,RemoveType过滤器删除指定类型(标称型、数值型、字符串型、日期型或关系型)的所有属性,RemoveUseless过滤器删除常量属性以及几乎与所有实例的值都不相同的标称型属性。用户可以通过规定不相同值的数量占全部值总数的百分比来设定可以容忍的变化度,决定是否删除一个属性。需要注意的是,如果在Preprocess标签页中已经设置了类别属性(默认情况下,最后一个属性就是类别属性),则不同无监督属性过滤器的行为不同。例如,RemoveType和RemoveUseless过滤器都会跳过类别属性。
InterquartileRange过滤器添加新属性,以指示实例的值是否可以视为离群值或极端值。离群值和极端值定义为基于属性值的第25个和第75个百分位数之间的差。如果用户指定的极端值系数和百分位距的乘积值高于第75个百分位数,或低于第25个百分位数,该值就标记为极端值(也有超出上述范围标记为离群值但不是极端值的情况)。可以设置该过滤器,如果某个实例的任意属性值认为是离群值或极端值,或产生离群极端的指标,可以标记该实例为离群值或极端值。也可以将所有极端值标记为离群值,并输出与中位数偏离多少个百分位数的属性。该过滤器忽略类别属性。
AddCluster过滤器先将一种聚类算法应用于数据,然后再进行过滤。用户通过对象编辑器选择聚类算法,其设置方式与过滤器一样。AddCluster对象编辑器通过自己界面中的Choose按钮来选择聚类器,单击Choose按钮右边的文本框,会打开另外一个对象编辑器对话框,在新对话框中设置聚类器的参数,必须填写完整后才能返回AddCluster对象编辑器。一旦用户选定一个聚类器,AddCluster会为每个实例指定一个簇号,作为实例的新属性。对象编辑器还允许用户在聚类时忽略某些属性,如前文所述的Copy过滤器那样指定。ClusterMembership过滤器在过滤器对象编辑器中指定所使用的聚类器,生成簇隶属度值,以形成新的属性。如果设置了类别属性,在聚类过程中会忽略。
AddExpression过滤器通过将一个数学函数应用于数值型属性而生成一个新属性。表达式可包括属性引用和常量,四则运算符+、-、*、/和^,函数log、abs、cos、exp、sqrt、floor、ceil、rint、tan、sin以及左右括号。属性可通过索引加前缀a确定,例如a7指第七个属性。表达式范例如下:
a1^2*a5/log(a7*4.0)
MathExpression过滤器与AddExpression过滤器类似,它根据给定的表达式修改数值型属性,能够用于多个属性。该过滤器只是在原地修改现有属性,并不创建新属性。正因为如此,表达式中不能引用其他属性的值。所有适用于AddExpression过滤器的操作符都可用,还可以求正在处理属性的最小值、最大值、平均值、和、平方和以及标准偏差。此外,可以使用包含运算符和函数的简单if-then-else表达式。
NumericTransform过滤器通过对选中的数值型属性调用Java函数,可以执行任意的转换。该函数可以接受任意double数值作为参数,返回值也为double类型。例如,java.lang.Math类的sqrt()函数就符合这一标准。NumericTransform过滤器的一个参数(className)是实现该函数Java类的全限定名称,还有一个参数是转换方法的名称。
Normalize过滤器将数据集中的全部数值型属性规范化在[0,1]区间内。规范化值可以采用用户提供的常数进一步进行缩放和转换。Center和Standardize过滤器能将数值型属性转换为具有零均值的数值型属性,后者还能转换为具有单位方差的数值型属性。如果设置了类别属性,上述三个过滤器都会跳过,不对类别属性进行处理。RandomSubset过滤器随机选择属性的一个子集,并包括在输出中。可以用绝对数值或百分比指定抽取的范围,输出的新数据集总是把类别属性作为最后一个属性。
PartitionedMultiFilter是一种特殊的过滤器,在输入数据集中一组对应的属性范围内应用一组过滤器。只允许使用能操作属性的过滤器,用户提供和配置每个过滤器,定义过滤器工作的属性范围。removeUnused选项可以删除不在任何范围内的属性,将各个过滤器的输出组装成一个新的数据集。Reorder过滤器改变数据中属性的顺序,通过提供属性索引列表,指定新顺序。另外,通过省略或复制属性索引,可以删除属性或添加多个副本。
2)改变值
SwapValues过滤器交换同一个标称型属性的两个值的位置。值的顺序不影响学习,但如果选择了类别属性,顺序的改变会影响混淆矩阵的布局。MergeTwoValues过滤器将一个标称型属性的两个值合并为一个单独的类别,新值的名称是原有两个值的字符串连接,每一个原有值的每次出现都更换为新值,新值的索引比原有值的索引小。例如,天气数据集中原有五个sunny、四个overcast、五个rainy实例,如果合并outlook属性的前两个值(sunny和overcast),则新的outlook属性就包含sunny_overcast和rainy值,数据集中将有九个sunny_overcast实例和原有的五个rainy实例。MergeManyValues过滤器将指定标称型属性的多个值合并为一个值。MergeInfrequentNominalValues过滤器将指定标称型属性中出现次数足够低的值进行合并。
处理缺失值的一个方法是在实施学习方案前,全局替换缺失值。ReplaceMissingValues过滤器用均值取代每个数值型属性的缺失值,用出现最多的众数取代标称型属性的缺失值。如果设置了类别属性,默认不替换该属性的缺失值,但可以使用ignoreClass选项进行修改。ReplaceWithMissingValue过滤器用于在数据集中引入缺失值,指定概率用于决定是否将实例的特定属性值替换为缺失值。
NumericCleaner过滤器用默认值取代数值型属性中值太小,或太大,或过于接近某个特定值的取值。也可以为每一种情况指定不同的默认值,供选择情况包括认定为太大或太小的阈值,以及过于接近定义的容差值(tolerance value)。
AddValues过滤器对照用户提供的列表,在标称型属性中添加其中不存在的值,可以选择对标签进行升序排序。如果不提供标签列表,可以只对原有标签排序。ClassAssigner过滤器用于设置或取消数据集的类别属性。用户提供新的类别属性的索引,索引为0则取消当前类别属性。
3)转换
许多过滤器可用于将属性从一种形式转换为另一种形式。Discretize过滤器使用等宽或等频分箱将指定范围内的数值型属性离散化。对于等宽分箱方法,可以指定箱数,或使用留一法交叉验证,自动选择使似然值最大化。也可以创建多个二元属性,替换一个多元属性。对于等频离散化,可以改变每个分隔期望的实例数量。PKIDiscretize过滤器使用等频分箱离散化数值型属性,箱的数目设置为非缺失值数量的平方根。默认情况下,上述两个过滤器都跳过类别属性。
MakeIndicator过滤器将标称型属性转换为二元指示符属性,可以用于将多个类别的数据集转换成多个两个类别的数据集。它用二元属性替换所选择的标称型属性,其中,如果某个特定的原始值存在,该实例的值为1,否则为0。新属性默认声明为数值型,但如果需要,也可以声明为标称型。
对于一些学习方案,如支持向量机,多元标称型属性必须被转换成二元属性。NominalToBinary过滤器能将数据集中所有指定的多元标称型属性转换为二元属性,使用一种简单的“每值一个”(one-per-value)编码,将每个属性替换为k个二元属性的k个值。默认情况下,新属性将是数值型,已经是二元属性的将保持不变。NumericToBinary过滤器将除了类别属性外的所有数值型属性转换成标称二元属性。如果数值型属性的值恰好为0,新属性值也为0;如果属性值缺失,新属性值也缺失;否则,新属性值将为1。上述过滤器都跳过类别属性。NumericToNominal过滤器通过简单地增加每一个不同数值到标称值列表,将数值型属性转换为标称型属性。该过滤器在导入.csv文件之后非常有用,Weka的csv导入机制将所有可解析为数字的数据列都相应创建为数值型属性,但有时将整型属性的值解释为离散的标称型有可能更为恰当。
FirstOrder过滤器对一定范围内的数值型属性应用一阶差分算子。算法为:将N个数值型属性替换为N-1个数值型属性,其值是原来实例中连续属性值之差,即新属性值等于后一个属性值减去前一个属性值。例如,如果原来的属性值分别为3、2、1,则新的属性值将是-1、-1。
KernelFilter过滤器将数据转换为核矩阵,类别值保持不变。它输出一个新数据集,包含的实例数量和原来的一样,新数据集的每个值都是用核函数评估一对原始实例的结果。默认情况下,预处理使用Center过滤器,将所有的值都转换为将中心平移至0,尽管没有重新缩放为单位方差。然而,用户也可以指定用不同的过滤器。
PrincipalComponents过滤器在数据集上进行主成分转换,将多元标称型属性转换为二元属性,用均值替换缺失值,默认将数据标准化。主成分数量通常根据用户指定的覆盖比例的方差确定,但也可以明确指定主成分数量。
Transpose过滤器将数据进行转置运算:实例变为属性,属性变为实例。
4)字符串转换
字符串型属性值的数目不定。StringToNominal过滤器用一组值将字符串型属性转换为标称型属性。用户要确保所有要出现的字符串值都会在第一批数据中出现。NominalToString过滤器转换的方向相反。
StringToWordVector过滤器将字符串型属性转换为表示单词出现频率的数值型属性。单词集合就是新的属性集,由字符串型属性值的完整集合确定。新属性可以采用用户指定的前缀来命名,这样通过名称容易区分来源不同的字符串型属性。
ChangeDateFormat过滤器更改用于解析日期型属性的格式化字符串,可以指定Java的SimpleDateFormat类所支持的任意格式。
5)时间序列
Weka提供两种处理时间序列的过滤器。TimeSeriesTranslate过滤器将当前实例的属性值替换为以前(或未来)的实例的等效属性值。TimeSeriesDelta过滤器将当前实例的属性值替换为以前(或未来)的实例的等效属性值与当前属性值之间的差值。对于时移差值未知的实例,要么删除实例,要么使用缺失值。
6)随机化
一些属性过滤器有意降低数据的质量。AddNoise过滤器按照指定的一定比例更改标称型属性的值。可以保留缺失值不变,也可以让缺失值和其他值一起变化。Obfuscate过滤器对关系型属性、全部属性名称,以及所有标称型属性值进行重命名,对数据集进行模糊处理,目的主要是为了交换敏感数据集。RandomProjection过滤器通过使用列为单位长度的随机矩阵,将数据投影到一个低维子空间,以此来降低数据维数。投影不包括类别属性。
2.无监督实例过滤器
1)随机化和子抽样
Randomize过滤器用于将数据集中实例的顺序进行随机重排。产生的数据子集的方式有很多种。Resample过滤器产生一个有放回或无放回数据集的随机子样本。RemoveFolds过滤器将数据集分割为给定的交叉验证折数,并指定输出第几折。如果提供一个随机数种子,在提取子集前,先对数据集重新排序。ReservoirSample过滤器使用水库抽样算法从数据集中抽取一个随机样本(无放回)。当在知识流界面或命令行界面中使用时,可以增量读取数据集,因此可以抽样超出主内存容量的数据集。
RemovePercentage过滤器删除数据集中给定百分比的实例。RemoveRange过滤器删除数据集中给定范围的实例。RemoveWithValues过滤器删除符合条件的实例,如标称型属性具有一定值的,或者数值型属性大于或小于特定阈值的。默认情况下,会删除所有满足条件的实例。也可以反向匹配,保留所有满足条件的实例,删除其余实例。
RemoveFrequentValues过滤器删除那些满足某个标称型属性值最经常或最不经常使用的对应的实例。用户可以指定频度多大或多小的具体值。
RemoveDuplicates过滤器删除接收到的第一批数据中所有重复的实例。
SubsetByExpression过滤器选择那些满足用户提供的逻辑表达式的所有实例。表达式可以是数学运算符和函数,如那些可用于AddExpression和MathExpression过滤器的运算符和函数,以及应用于属性值的逻辑运算符(与、或、非)。例如,表达式
(CLASS is 'mammal') and (ATT14 > 2)
选择那些CLASS属性值为mammal并且第14个属性的值大于2的实例。
通过将分类方法应用到数据集,然后使用RemoveMisclassified过滤器删除错误分类的实例,可以删除离群值。通常上述过程需要重复多遍,直到充分清洗数据,也可以指定最大的迭代次数。除了评估训练数据,还可以使用交叉验证,对数值类别也可以指定错误阈值。
2)稀疏实例
NonSparseToSparse过滤器将全部输入实例转换为稀疏格式。SparseToNonSparse过滤器将输入的所有稀疏实例转换为非稀疏格式。
3.有监督属性过滤器
Discretize过滤器将数据集中一定范围内的数值型属性离散化为标称型属性,用户可指定属性的范围以及强制属性进行二元离散化。要求类别属性为标称型属性,默认的离散化方法是Fayyad & Irani的MDL(最小描述长度)判据,也可以使用Kononenko方法。
NominalToBinary过滤器也有一个有监督版本,用于将全部标称型属性转换成二元的数值型属性。在有监督版本中,类别属性是标称型还是数值型决定了如何进行转换。如果是标称型,使用每个值一个属性的方法,将k个值的属性转换成k个二元属性。如果是数值型,考虑类别平均值与每个属性值的关联,创建k-1个新的二元属性。两种情况都不改变类别本身。
MergeNominalValues过滤器使用CHAID方法,合并指定范围的标称型属性(但不含类别属性)中的所有属性值,它不使用re-split子集合并。
ClassOrder过滤器更改类别顺序。用户指定新顺序是否按随机顺序,或按类别频率进行升序或降序排列。该过滤器不能与FilteredClassifier元学习方案联合使用。AttributeSelection过滤器用于自动属性选择,并提供与探索者界面中Select attributes标签页相同的功能。
ClassConditionalProbabilities过滤器将标称型属性值或数值型属性值转换为类别条件概率。如果有k个类别,则将创建k个新属性,其值由pr(att val|class k)给出。
AddClassification过滤器使用指定分类器为数据集添加类别、类别分布和错误标志。分类器可以通过对数据本身进行训练而得到,也可以通过序列化模型得到。
PartitionMembership过滤器使用PartitionGenerator生成分隔隶属度值,过滤实例由这些值加上类别属性(如果在输入数据中设置)组成,并呈现为稀疏的实例集。
4.有监督实例过滤器
Weka提供四个有监督的实例过滤器。
ClassBalancer过滤器调整数据集中的实例,使得每个类别都有相同的总权重。所有实例的权重总和将维持不变。
Resample过滤器与同名的无监督实例过滤器类似,但它保持在子样本的类别分布。另外,它可以配置是否使用均匀的分类偏倚,抽样可以设置为有放回(默认)或无放回模式。
SpreadSubsample过滤器也产生一个随机子样本,但可以控制最稀少和最常见的类别之间的频率差异。例如,可以指定至多2:1类别频率差异。也可以通过明确指定某个类别的最大计数值,来限制实例的数量。
与无监督的实例过滤器RemoveFolds相似,StratifiedRemoveFolds过滤器为数据集输出指定交叉验证的折,不同之处在于此时的折是分层的。
2.2.5 手把手教你用
1.使用数据集编辑器
Weka可以查看和编辑整个数据集。
首先加载weather.nominal.arff文件,单击Preprocess标签页中的Edit按钮,弹出Viewer(阅读器)对话框,列出全部天气数据。该对话框以二维表的形式展现数据,用于查看和编辑整个数据集,也称为数据集编辑器,如图2.25所示。
图2.25 数据集编辑器
数据表顶部显示当前数据集的关系名称。表头列出数据集各属性的序号、名称和数据类型。数据集编辑器的第一列是序号,标识实例的编号。
数据集编辑器右下部有三个按钮:Undo按钮用于撤销所做的修改,不关闭窗口;OK按钮用于提交所做的修改,关闭窗口;Cancel按钮用于放弃所做的修改,关闭窗口。
除了用探索者界面编辑数据集之外,还可以直接使用ARFF-Viewer工具。具体方法是,在Weka GUI选择器窗口中,选择Tools|ArffViewer菜单项,或按Ctrl+A快捷键,就可以打开ARFF-Viewer窗口,再选择窗口中的File|Open菜单项,就可以打开Weka支持的各种数据文件,如图2.26所示。可以看到,ARFF-Viewer窗口可提供更多的编辑和视图功能。
图2.26 ARFF-Viewer窗口
2.删除属性
Weka使用过滤器来系统性地更改数据集,因此过滤器属于预处理工具。
假设要求去除weather.nominal.arff数据集的第二个属性,即temperature属性,具体操作步骤如下。
首先,使用探索者界面加载weather.nominal.arff文件。在Perprocess标签页中单击Choose按钮,打开过滤器分层列表,如图2.27所示。
图2.27 过滤器分层列表
适合本例要求的过滤器为Remove,全称是weka.filters.unsupervised.attribute.Remove。从名称上可以看出,过滤器组织成层次结构,根为weka,往下继续分为unsupervised(无监督)和supervised(有监督)两种类型,前者不使用类别属性,后者使用。继续往下分为attribute(属性)和instance(实例)两种类型,前者主要处理有关属性的过滤,后者处理有关实例的过滤。
在分层列表中按照weka\filters\unsupervised\attribute路径,找到Remove条目,单击选择该过滤器。这时,Choose按钮右边的滤波器文本框中显示Remove字符串。单击该文本框,打开通用对象编辑器对话框以设置参数。
在attributeIndices文本框内输入“2”,如图2.28所示。单击OK按钮,关闭通用对象编辑器对话框。这时,Choose按钮右边的文本框中应该显示“Remove -R 2”,含义是从数据集中去除第二个属性。单击该文本框右边的Apply按钮使过滤器生效,应该看到原来的5个属性现在变为4个,temperature属性已经被去除。要特别说明的是,本操作只影响内存中的数据,不会影响数据集文件中的内容。当然,变更后的数据集也可以通过单击Save按钮并输入文件名另存为ARFF格式或其他格式的新文件。如果要撤销过滤操作,可单击Undo按钮,撤销操作也只会影响内存中的数据。
图2.28 修改过滤器选项
如果仅需要去除属性,还有更简单并且效果一样的方法。只要在Attributes选项组中选择要去除的属性,然后单击属性表格下面的Remove按钮即可。
3.添加属性
启动探索者界面并加载weather.nominal.arff数据集。假设要求在数据集倒数第二个属性位置添加一个用户定义的字段,具体操作步骤如下。
在Preprocess标签页中单击Choose按钮,选择AddUserFields过滤器。然后单击Choose按钮右边的文本框,在通用对象编辑器对话框中设置AddUserFields过滤器的选项。单击New按钮,设置Attribute name(属性名称)为mode,设置Attribute type(属性类型)为nominal,不设置Date format(日期格式)和Attribute value(属性值)两个选项,如图2.29所示。
图2.29 设置AddUserFields过滤器选项
单击OK按钮结束选项设置,并在Preprocess标签页中单击Apply按钮应用过滤器。这时,应该看到Attributes选项组的属性表格中多出了一个mode属性。单击Edit按钮,打开Viewer对话框,可以看到新增的属性并没有值,因此,下一步是添加标称型属性值。
再次单击Choose按钮,选择AddValues过滤器。按照图2.30所示设置标称型属性的标签。
图2.30 设置标签
再次单击Edit按钮,打开Viewer对话框,如图2.31所示。可以看到,mode属性已经有了属性标签,可以随意设置一些值,然后单击OK按钮关闭对话框。
图2.31 编辑属性
注意: 新增属性的位置不太符合Weka的习惯,习惯上最后一个属性一般是类别属性,因此需要把第五个属性与第六个属性对换一下。读者是否知道该使用哪个过滤器呢?
提示:使用Reorder过滤器,参数为“-R 1,2,3,4,6,5”,请读者自行完成。
4.离散化
如果数据集包含数值型属性,但所用的学习方案只能处理标称型属性的分类问题,那么先将数值型属性进行离散化是必要的,这样就能使学习方案增加处理数值型属性的能力,通常能获得较好的效果。
有两种类型的离散化技术——无监督离散化和有监督离散化,前者不需要也不关注类别属性值,后者在创建间隔时考虑实例的类别属性值。离散化数值型属性的直观方法是将值域分隔为多个预先设定的间隔区间。显然,如果分隔级别过大,将会混淆学习阶段可能有用的差别;反之,如果分隔级别过小或分隔边界选取不当,则会将很多不同类别的实例混合在一起影响学习。Weka无监督离散化数值型属性的Java类是weka.filters.unsupervised.attribute.Discretize,它实现了等宽和等频两种离散化方法,其中,等宽离散化是默认方法。
等宽离散化(或称为等宽分箱)经常造成实例分布不均匀,有的间隔区域内(箱内)包含很多个实例,但有的却很少甚至没有。这样会降低属性辅助构建较好决策结果的能力。通常也允许不同大小的间隔区域存在,从而使每个区间内的训练实例数量相等,这样的效果可能会好一些,该方法称为等频离散化(或称为等频分箱),其方法是:根据数轴上实例样本的分布将属性区间分隔为预先设定数量的区间。如果观察结果区间的直方图,会发现其形状平直。等频离散化与朴素贝叶斯学习方案一起应用时效果较好。但是,等频离散化也没有注意实例的类别属性,仍有可能导致不好的区域划分。例如,如果一个区域内的全部实例都属于一个类别,而下一个区域内除了第一个实例属于前一个类别外,其余的实例都属于另一个类别,那么,显然将第一个实例包含到前一个区域更为合理。
下面以实例说明这两种方法的差异。首先,在data目录中查找到玻璃数据集glass.arff文件,并将它加载至探索者界面,在Preprocess标签页中查看RI属性直方图,如图2.32所示。实施无监督离散化过滤器,分别使用等宽和等频两种离散化方法,即首先使Discretize的全部选项保持默认值不变,然后将useEqualFrequency选项的值更改为True。得到离散化后对应的RI属性直方图分别如图2.33和图2.34所示。
图2.32 原始的RI属性直方图
图2.33 等宽离散化后的RI属性
图2.34 等频离散化后的RI属性
从图2.33和图2.34中容易看出,等宽离散化将数值型属性从最小值到最大值平均分为十份,因此每一份所包含的实例数量就各不相等;而等频离散化按数值型属性的大小顺序将全部实例平均分为十份,每份所包含的实例数量为21~22,因此,图2.34中的直方图大致等高。
读者可能会形成一个错觉,等频离散化后形成的直方图似乎都会等高。但是,如果等频离散化Ba属性,再检查结果,会发现这些直方图严重地偏向一端,也就是根本不等频,如图2.35所示。
图2.35 等频离散化后的Ba属性
这又是为什么呢?
仔细观察第一个直方图的标签,其值为’(-inf-0.03]',即区间大于负无穷且小于等于0.03。使用数据集编辑器打开离散化前的原始数据集,单击第八列表头,使数据集按照Ba属性进行排序,如图2.36所示。可以看到,有176个实例的Ba属性值都等于0.0,由于这些值都完全相同,没有办法将它们分开,因此图2.35中的直方图严重地偏向一端。
图2.36 原始数据集
读者可自行检查Fe属性,验证是否为同样的原因。
总结:一般情况下,等频离散化后直方图大致等高。但如果有很多实例的值都完全相等,等频离散化也没法做到“等频”。
下面尝试有监督的离散化技术。有监督的离散化竭力构建一种间隔,虽然各个间隔之间的分类分布各不相同,但间隔内的分布保持一致。Weka有监督离散化数值型属性的Java类的全路径名称为weka.filters.supervised.attribute.Discretize。首先,定位到data目录下的鸢尾花数据集,加载iris.arff文件,施加有监督的离散化方案,观察得到的直方图如图2.37所示。
图2.37 有监督离散化后的直方图
请读者思考一下,图2.37中哪一个经过离散化后的属性最具有预测能力?
显然,只有petallength(花瓣长)和petalwidth(花瓣宽)最具竞争力,因为它们的每种分类都已经接近于同一种颜色。再经过仔细对比可以发现,在前者中,有1个virginica实例错分到versicolor中,有6个versicolor实例错分到virginica中,因此共有7个错分的实例;而在后者中,只有5个virginica实例错分到versicolor中,有1个versicolor实例错分到virginica中,因此共有6个错分的实例。从而得出结论:离散化后的petalwidth属性最具有预测能力。
通常将离散化后的属性编码为标称型属性,每一个范围给定一个值。然而,因为范围是有序的,离散化后的属性实际上是一个有序标量。
除了创建多元属性外,有监督和无监督两种离散化过滤器都能创建二元属性,只要将选项makeBinary设置为True即可。图2.38所示即为有监督的离散化方案创建二元属性后得到的结果。
图2.38 有监督二元离散化后的直方图
将图2.38和图2.37做一个比较,便知道二元属性就是指每个属性离散化后只有两种编码。初看起来,这样做似乎没有什么用处。由于还有一些知识没有介绍,后文“深入研究离散化”部分再讨论这个问题。