2.6 选择属性
选择属性就是通过搜索数据中所有可能的属性组合,以找到预测效果最好的属性子集。手工选择属性既烦琐又容易出错,为了帮助用户实现选择属性自动化,Weka专门提供如图2.89所示的Select attributes标签页。要自动选择属性,必须设立两个对象:属性评估器和搜索方法。前者在窗口顶部的Attribute Evaluator选项组中设置,后者在Search Method选项组中设置。属性评估器确定使用什么方法为每个属性子集分配一个评估值,搜索方法决定执行什么风格的搜索。
图2.89 Select attributes标签页
Weka允许用户分别选择评估器和搜索方法,如果用户选择的组合不恰当,就会产生一个错误消息,用户可通过日志查看错误消息。
2.6.1 Select attributes标签页的操作
在Attribute Selection Mode(属性选择模式)选项组中,有以下两个选项。
(1)Use full training set(使用完整的训练集):使用完整的训练数据集,以确定属性子集的评估值。
(2)Cross-validation(交叉验证):由交叉验证来确定属性子集的评估值。Folds(折数)和Seed(种子)选项分别设置交叉验证的折数和打乱数据时使用的随机种子。
与Classify标签页一样,Select attributes标签页中有一个下拉列表框,用于设定把哪个属性作为类别属性。
单击Start按钮启动选择属性过程,当选择过程结束后,会将结果输出到Attribute selection output(属性选择输出)区域,并且会在Result list(结果列表)区域添加一个条目。右击结果列表区域中的条目,弹出的快捷菜单中提供几个菜单项。前三个菜单项,即View in main window(在主窗口中查看)、View in separate window(在单独的窗口中查看)和Save result buffer(保存结果缓冲区)与Classify标签页中对应的功能一致,不再重复说明。有可能会有Visualize reduced data(减少后数据的可视化)菜单项,如果使用了PrincipalComponents(主成分)等属性转换器,也可能会有Visualize transformed data(转换后的数据可视化)菜单项。通过选择Save reduced data(保存减少后的数据)或Save transformed data(保存转换后的数据)菜单项,可以将减少或转换后的数据保存到文件中。
选择属性操作除了可以在Select attributes标签页中完成以外,还可以在Classify标签页中使用AttributeSelectedClassifier元分类器完成,该元分类器可以在训练和测试数据传递给分类器前,先通过选择属性来减少维度。AttributeSelectedClassifier元分类器的详细用法请参见后文。下一个替代方式是过滤器,一般要求同时对训练数据和测试数据进行减少或转换处理,最好在命令行或简单命令行(Simple CLI)界面中使用AttributeSelection过滤器的批处理模式(-b),这是一种有监督的属性过滤器。批处理模式允许使用-r和-s选项指定额外的输入和输出文件对,而构建过滤器则使用-i和-o选项指定训练数据的输入和输出文件对。
例如:
java weka.filters.supervised.attribute.AttributeSelection -E "weka.attributeSelection.CfsSubsetEval " -S "weka.attributeSelection.BestFirst -D 1 -N 5" -b -i <input1.arff> -o <output1.arff> -r <input2.arff> -s <output2.arff>
注意: 以上命令在Windows命令行下需要在一行内写完。
2.6.2 选择属性算法介绍
在Select attributes标签页中可以指定属性评估器和搜索方法。选择属性通常搜索属性子集空间,评估每一个空间,这可以通过组合属性子集评估器和搜索方法得以实现。另一种快捷但准确度不高的方法是评估单个属性并排序,丢弃低于指定截止点的属性,这可以通过组合单个属性评估器和属性排名的方法得以实现。Weka界面支持这两种方法,允许用户选取属性评估器和搜索方法的组合,如果用户选择了一个不恰当的组合,就会产生一个错误消息。
1.属性子集评估器
属性子集评估器选取属性的一个子集,并返回一个指导搜索的度量数值,这些评估器可以像其他Weka对象一样配置。
CfsSubsetEval评估器评估每个属性的预测能力及其相互之间的冗余度,倾向于选择与类别属性相关度高,但相互之间相关度低的属性。选项迭代添加与类别属性相关度最高的属性,只要子集中不包含与当前属性相关度更高的属性。评估器将缺失值视为单独值,也可以将缺失值记为与出现频率成正比的其他值。
WrapperSubsetEval评估器是包装器方法,它使用一个分类器来评估属性集,它对每一个子集采用交叉验证来估计学习方案的准确性。
2.单个属性评估器
单个属性评估器和Ranker搜索方法一同使用,Ranker产生一个丢弃若干属性后得到的给定数目的属性排名列表。
ReliefFAttributeEval是基于实例的评估器,它随机抽取实例样本,并检查具有相同和不同类别的邻近实例。它可运行在离散型类别和连续型类别的数据之上,参数包括指定抽样实例的数量、要检查的邻近实例的数量、是否对最近邻的距离加权,以及控制权重如何根据距离衰减的指数函数。
InfoGainAttributeEval评估器通过测量类别对应的属性信息增益来评估属性,它首先使用基于MDL(最小描述长度)的离散化方法(也可以设置为二元化处理)对数值型属性进行离散化。GainRatioAttributeEval评估器通过测量相应类别的增益率来评估属性。SymmetricalUncertAttributeEval评估器通过测量相应类别对称的不确定性来评估属性。以上几个方法都可将缺失值作为单独值处理,或者将缺失值记为与出现频率成正比的其他值。
OneRAttributeEval评估器使用简单的OneR分类器采用的准确性度量,它可以像OneR分类器那样,使用训练数据进行评估,也可以应用折数作为参数的内部交叉验证。它采用OneR分类器的简单离散化方法:将最小桶大小(minimumBucketSize)作为参数。
不同于其他的单个属性评估器,PrincipalComponents评估器转换属性集,新属性都按照其特征值进行排名。或者,通过选择足够的占方差一定比例(默认为95%)的特征向量来选择子集。最后,减少后的数据可以转换回原来的空间。
3.搜索方法
搜索方法遍历属性空间以搜索好的子集,通过所选的属性子集评估器来衡量其质量。每个搜索方法都可以使用Weka对象编辑器进行配置。
BestFirst搜索方法执行带回溯的贪婪爬山法,用户可以指定在系统回溯之前,必须连续遇到多少个无法改善的节点。它可以从空属性集开始向前搜索,也可以从全集开始向后搜索,还可以从中间点(通过属性索引列表指定)开始双向搜索并考虑所有可能的单个属性的增删操作。为提高效率,可以缓存已评估的子集,最大缓存的大小为可设置的参数。
GreedyStepwise搜索方法贪婪搜索属性的子集空间。像BestFirst搜索方法一样,它可以从空集开始向前搜索,也可以从全集开始向后搜索。但不像BestFirst,它不进行回溯,只要添加或删除剩余的最佳属性导致评估指标降低,就立即终止。在另一种模式下,它通过从空到满(或从满到空)遍历空间,并记录选择属性的顺序来对属性排名。用户可以指定要保留的属性数量,或者设置一个阈值,丢弃所有低于该值的属性。
最后,Ranker实际上不是搜索属性子集的方法,而是对单个属性进行排名的方法。通过单个属性评估对属性排序,只能用于单个属性评估器,不能用于属性子集评估器。Ranker不仅能对属性排名,还能通过删除较低排名的属性来完成属性选择。用户可以设置一个截止阈值,丢弃低于该值的所有属性,或者指定保留多少属性。用户可以指定某些不论其排名情况如何都必须保留的属性。
2.6.3 手把手教你用
1.手工选择属性
本次实践的任务是手工选择玻璃数据集的属性集,使用IBk算法和交叉验证,探究哪个属性子集能产生最佳的分类准确率。Weka中带有自动属性选择功能,后文将进行介绍,但是,手工执行本操作能让读者直观了解选择属性的工作原理,更有启发意义。
首先,在Weka的Preprocess标签页中加载glass.arff文件,可以观察到,如果不计最后一个类别属性,玻璃数据集中一共有九个属性。在Attributes选项组中,通过选中属性表格里属性名称前面的复选框,选择欲移除的属性,然后单击Remove按钮移除选中的属性,使用剩下的属性子集进行测试。当然,也可以使用Remove过滤器完成同样的工作。
这里采用逐步消去属性的方法。其步骤是,首先分别从完整的数据集中移除一个单个属性,形成一个属性子集,对每一个数据子集版本运行交叉验证,这样就可以确定最佳的八个属性的数据集;按照这种方式重复,只不过每次移除两个单个属性,在减少的数据集上实施交叉验证,可以找到最佳的七个属性的数据集;以此类推。
测试的步骤是,在Preprocess标签页中选择好数据子集后,切换至Classify标签页,选择IBk分类器和十折交叉验证方案,单击Start按钮启动分类,记录正确分类的百分比,然后返回Preprocess标签页选择下一轮的数据子集,如此反复,如图2.90所示。
图2.90 测试结果
将每次的测试结果填入表2.11中。该表的第一行数据已经填好,请读者填写其余的数据。
表2.11 使用IBk对不同属性子集得到的准确率
为了方便读者对照,表2.12中列出答案。从表中难以看出这是一项艰巨的工作,一共需要完成512次实验,即
表2.12 使用IBk对不同属性子集得到的准确率答案
如果每分钟完成一个实验,也需要将近九个小时才能完成。
从表2.12中可以看到,使用IBk分类器能达到的最高分类准确率为79.4393%,只需要在九个属性中选取五个属性就足够了,更多的属性反而会降低准确率,即最佳的属性子集得到的分类准确率高于完整数据集得到的分类准确率。请读者想一想,这是为什么?
2.自动属性选择
在大多数有监督学习的实际应用中,并不是所有的属性在预测目标方面都具有同等的重要性。对于一些学习方案,冗余或不相关的属性可能导致不准确的模型。正如在上一个实验中发现的那样,在数据集中手工选择有用的属性是非常烦琐而乏味的,自动的属性选择方法通常更快更好。
属性选择方法可以分为过滤器和包装方法。前者应用低计算开销的启发式方法来衡量属性子集的质量;后者通过构建和评估实际的分类模型来衡量属性子集的质量,其计算开销较大,但往往性能更好。
探索者界面中的Select attributes标签页将属性选择方法应用到数据集,默认使用CfsSubsetEval评估器来评估属性子集。另一种方法是使用InfoGainAttributeEval等评估器,评估单个属性,然后通过使用一种特殊的“搜索”方法(即Ranker),对这些属性进行排名。
下面首先使用InfoGainAttributeEval评估器和Ranker搜索方法对属性进行排名,具体步骤如下。
首先加载劳工数据集,即labor.arff文件,然后切换至Select attributes标签页。在Attribute Evaluator选项组中,单击Choose按钮,选择InfoGainAttributeEval,这时会弹出如图2.91所示的警告对话框,询问是否需要选择Ranker搜索方法,单击“是”按钮确认。
图2.91 警告对话框
单击Start按钮启动自动属性选择评估及搜索算法,图2.92中显示了运行结果。
图2.92 InfoGainAttributeEval运行结果
从运行结果中可以看到,属性选择输出中已经按照各个属性在预测目标方面的重要程度进行了排序,用户可按照排名后的重要程度选取一定的属性子集。
与上述使用InfoGainAttributeEval评估器的信息增益方法不同,CfsSubsetEval评估器的目标是确定一个属性子集,它与目标属性相关性强,同时相互之间又没有强相关性。默认情况下,它使用BestFirst搜索方法,但也可以选择其他方法,搜索可能的属性子集空间中“最好”的那一个。实际应用时可选择GreedyStepwise,并设置searchBackwards(向后搜索)参数为True。
还是使用劳工数据集,在Select attributes标签页的Attribute Evaluator选项组中选择CfsSubsetEval,这时会弹出如图2.93所示的警告对话框,询问是否需要选择GreedyStepwise搜索方法,单击“是”按钮确认。
图2.93 警告对话框
在Search Method选项组中单击Choose按钮旁边的文本框,在弹出的通用对象编辑器中将searchBackwards参数设置为True,再关闭通用对象编辑器,然后单击Start按钮启动自动属性选择评估及搜索算法,图2.94中显示了运行结果。
图2.94 CfsSubsetEval运行结果
从运行结果中可以看到,最佳的属性子集已经选择出来了,共有七个属性,还显示出所选择的属性索引和属性名称。读者可以将搜索方法由GreedyStepwise改为BestFirst,对于本例来说,运行结果是一样的,都选取第2、3、5、11、12、13、14共七个属性。
如果要使用包装方法,而不使用如同CfsSubsetEval那样的过滤器方法,那么,首先要选择WrapperSubsetEval评估器,然后选择学习算法,设置评估属性子集所使用的交叉验证的折数等选项。
使用包装方法处理劳工数据集的步骤是,选择WrapperSubsetEval评估器,设置基学习器classifier选项为J48,设置使用BestFirst搜索方法,单击Start按钮启动自动属性选择评估及搜索算法,图2.95中显示了运行结果。
图2.95 WrapperSubsetEval运行结果
现在检查图2.94和图2.95的最佳属性子集结果,前者输出第2、3、5、11、12、13、14共七个属性,后者输出1、2、4、6、11、12共六个属性,两种方法都选择出来的属性为2、11、12。对照图2.95的输出结果,两者都选择出来的属性分别位于信息增益输出的第二位、第三位、第六位,排名靠前。这说明尽管三种方法得出的结论不同,但有的属性由于与类别属性的相关性强,因此会被很多算法都选中。
最后,研究一下到底后两种方法哪种更符合实际。使用J48分类器、十折交叉验证,比较CfsSubsetEval和WrapperSubsetEval两种算法选出来的属性子集对分类准确度的影响,如表2.13所示。
表2.13 不同自动属性选择的实际性能比较
表2.13的第一行为参照数据,没有进行属性选择。由结果可以大致可靠地得出如下结论。
第一,经过属性选择后,分类准确度得到提高。
第二,对于本例,相对于CfsSubsetEval算法选出来的七个属性,WrapperSubsetEval算法只选出来六个属性,属性子集更小,但效果更好。
3.深入研究自动属性选择
Select attributes标签页能让用户通过属性选择方法,深入了解数据集。然而,如果将属性选择与有监督的离散化过滤方法一道使用,且将减少后的数据集的一部分用于模型测试(如交叉验证),就会带来一些问题。其原因是,在选择属性时就已经看到了在测试数据中要使用的类别标签,使用测试数据信息影响了模型的构建,导致有偏倚的准确性估计。
要避免上述问题,可以将数据分为训练集和测试集,属性选择只针对训练集。然而,通常更方便的方法是使用AttributeSelectedClassifer分类器,这是Weka的一种元学习器,它允许指定属性选择方法和学习算法作为分类方案的一部分。该分类器确保仅基于训练数据来选择属性子集。
现在将该分类器与NaiveBayes方法一起使用,测试InfoGainAttributeEval、CfsSubsetEval和WrapperSubsetEval三种属性选择方法。NaiveBayes假定属性相互独立,因此属性选择非常有帮助。这里使用weka.filters.unsupervised.attribute.Copy过滤器,添加多个复制后的属性,由于每个副本都明显与原来的数据完全相关,读者可以看到所形成的冗余属性的效果。具体操作步骤如下。
首先在Preprocess标签页中加载鸢尾花数据集,然后添加无监督的属性过滤器Copy,将attributeIndices选项设置为“1-4”,即复制第1~4个属性,如图2.96所示。然后,应用该过滤器,可以看到数据集中已经多出了四个属性,连上类别属性一共有九个属性。
图2.96 设置Copy过滤器选项
下一步,切换至Classify标签页。这时,应该注意一个问题,由于复制后的属性都是在尾部添加,因此原来的类别属性就变成不是默认的最末一个属性,一定要记得在Start按钮上方的下拉列表框中选择正确的类别属性,这里是(Nom)class。然后,选择AttributeSelectedClassifer分类器,编辑该分类器的选项,将基分类器classifier选项设置为NaiveBayes,将基分类器的useSupervisedDiscretization选项设置为True,该选项的功能是使用有监督的离散化将数值型属性转换为标称型属性;将evaluator选项设置为InfoGainAttributeEval;将search选项设置为Ranker,将Ranker算法的numToSelect选项设置为3,以指定排名属性的数目。完成以后的通用对象编辑器对话框如图2.97所示。
图2.97 设置分类器选项
关闭对话框,使用十折交叉验证测试策略,单击Start按钮运行元分类器,将运行结果填入表2.14中。
表2.14 AttributeSelectedClassifer元分类器不同评估器的效果
按照同样的方法,分别使用CfsSubsetEval和WrapperSubsetEval评估器,并在WrapperSubsetEval评估器内部指定NaiveBayes -D作为基分类器,因为它正是选择属性子集的分类器。将运行结果填入表2.14中。
可见,第一种和第二种自动属性选择算法并没有将冗余的属性分开,属性子集中都多出了一个复制(Copy of)属性。而第三种自动属性选择算法所选择的属性子集只含有一个属性,丢弃了大部分数据,但分类效果仍然是最好之一。
4.自动参数调节
许多学习算法的参数可以影响学习的结果。例如,决策树学习器C4.5有两个参数影响修剪的量,一个是叶节点中所需实例的最小数量(minNumObj),另一个是用于修剪的置信系数(confidenceFactor)。k-最近邻分类器IBk有一个参数(KNN)用于设置邻居的大小。手动调整参数设置很烦琐,就像手动选择属性一样,并且也有同样的问题:在选择参数时,一定不要使用测试数据,否则,性能估计会有所偏倚。
Weka提供元学习器CVParameterSelection,通过优化训练数据交叉验证的准确性,搜索以获得最佳的参数设置。默认情况下,每个设置使用十折交叉验证进行评估。使用CVParameters参数,在通用对象编辑器中指定要优化的参数。对于每个参数,必须提供三类信息:①一个字符串,使用字母代码进行命名(在Javadoc中可以找到分类器的相应参数);②进行评估数值的范围;③在该范围内尝试的步数,为一个数字。例如,从1~10增量为1,搜寻参数-P可写为“P 1 10 10”。
下面使用具体示例予以说明。使用CVParameterSelection元分类器,自动选择IBk的邻居大小的最优值,范围从1~10分10步。
首先加载diabetes.arff文件,在Classify标签页中选择CVParameterSelection元分类器,单击Choose按钮后面的文本框,弹出通用对象编辑器对话框。在该对话框中单击Choose按钮,选择IBk作为基分类器。然后,单击CVParameters文本框,会弹出一个通用数组编辑器对话框。在该对话框顶部的文本编辑框中输入“K 1 10 10”,分别代表KNN字母代码、1~10范围、10步,单击Add按钮添加,如图2.98所示。如果还需要评估其他参数,可以重复输入,输入完毕后关闭该对话框。
图2.98 通用数组编辑器对话框
注意: 在单击Add按钮后,Weka会自动在数值参数后添加“.0”。
完成设置后,单击Start按钮启动评估,运行结果如图2.99所示。
图2.99 运行结果
从运行结果中可以看到,当K值为7时,IBk的分类准确度最高,为73.9583%。读者可自行使用IBk的默认参数进行交叉验证,其分类准确度仅为70.1823%。
现在整定J48的参数。仍然使用上述数据与配置,只是将基分类器由IBk换成J48。如果CVParameters字段有一个以上的参数,CVParameterSelection会同时对多个参数执行网格搜索。修剪置信参数的字母代码是C,评估取值为从0.1~0.5的5个步骤。叶节点中所需实例的最小数量参数的字母代码是M,评估取值为从1到10的10个步骤。因此需要在CVParameters参数中分别加入“C 0.1 0.5 5”和“M 1 10 10”两个需要评估的参数,然后单击Start按钮启动评估,运行结果如图2.100所示。
图2.100 J48运行结果
从运行结果中可以看到,整定后的参数为“-M 10 -C 0.2”,分类准确度为74.349%,决策树的叶节点数为15,树大小为29。可以和使用默认参数的J48做一个对比,默认参数为“-C 0.25 -M 2”,其分类准确度为73.8281%,决策树的叶节点数为20,树大小为39。
综上所述,可以得出结论:优化参数后,对分类器的性能提升很大。