2.6 特征选择
我们的CPU模型只有6个特征。通常,我们遇到实际环境的数据集会具有来自多种不同观测数据的非常大量的特征。另外,我们会在不太确定哪些特征在影响输出变量方面比较重要的情况下,不得不采用大量的特征。除此之外,我们还有会遇到可能要分很多水平的分类变量,对它们我们只能创建大量的新指示变量,正如在第1章里所看到的那样。当面对的场景涉及大量特征时,我们经常会发现输出只依赖于它们的一个子集。给定k个输入特征,可以形成2k个不同的子集,因此即使对于中等数量的特征,子集的空间也会大到无法通过逐个子集的拟合来进行完整的探索。
要理解为什么可能的特征子集会有2k个,一种简单的方式是这样的:我们可以给每个子集分配一个独立的识别码,这个识别码是k位的二进制数字构成的字符串,如果我们选择在该子集中包含第i个特征(特征可以任意排序),那么第i个位上的数字就是1。例如,如果我们有三个特征,字符串101就对应了只包括第一个和第三个特征的子集。在这种方式下,我们构建了所有可能的二进制字符串,它从由k个0构成的字符串一直排到由k个1构成的字符串,因此我们就得到了从0到2k-1的所有整数,也就是总计2k个子集。
特征选择(feature selection)指在模型中选择一个特征子集以构成一个带有更少特征的新模型的过程。它会去除我们认为和输出变量无关的特征,因而产生一个更易于训练和解释的更简单模型。有很多方法被设计用来进行这项任务,它们一般不会用穷举的方式去搜遍可能的子集空间,而是在该空间进行引导式搜索(guided search)。
这类方法之一是前向选择(forward selection),它是通过一系列步骤进行特征选择的逐步回归(stepwise regression)的一个范例。对于前向选择,它的思路是从一个没有选择特征的空模型起步,接着进行k次(针对每个特征进行一次)简单线性回归并从中选取最好的一个。这里比较的是有相同特征数量的模型,因此可以使用R2统计量来指导我们的选择,虽然我们也可以使用AIC之类的衡量指标。一旦选择了要加入的第一个特征,我们就可以从余下的k-1个特征中选取要加入的另一个特征。因此,现在我们可以针对每个可能的特征配对进行k-1次多元回归,配对中的其中一个特征是在第一步选择的那个特征。我们可以继续按这种方式增加特征,直到我们评价了包含所有特征的模型并结束这个过程。注意,在每一个步骤里,我们都为所有后续的步骤作出了把哪个特征包含进来的艰难选择。例如,在多于一个特征的模型当中,没有包含我们在第一步选择的那个特征的那些模型就永远不需要考虑了。因此,我们并不是穷举式地搜索我们的空间。实际上,如果考虑到我们还评估了空模型,我们就可以计算进行了线性回归的模型总数为:
这个计算结果的数量级是在k2的量级上,即使对于比较小的k值而言,也已经明显比2k小多了。在前向选择过程的最后阶段,我们必须从对应每个步骤结束时得到的子集所构成的k+1个模型中进行选择。由于过程的这个最终部分要比较带有不同数量特征的模型,我们通常会使用诸如AIC的准则或调整后的R2来作出模型的最终选择。对于CPU数据集,可以通过运行下列命令来演示这个过程:
step()函数实现了前向选择的过程。我们首先给它提供了通过在训练数据上拟合无特征的线性模型而得到的空模型。对于scope参数,我们指定的是要求算法从空模型开始一直逐步处理到包含所有6个特征的完整模型。在R语言里发出这条命令会产生一个输出,它会显示迭代每一步指定了哪个特征子集。为了节省空间,我们在下表呈现这个结果以及每个模型的AIC值。注意,AIC值越小,模型就越好。
步骤 子集里含有的特征 AIC值
0 { } 1839.13
1 {MMAX} 1583.38
2 {MMAX, CACH} 1547.21
3 {MMAX, CACH, MMIN} 1522.06
4 {MMAX, CACH, MMIN, CHMAX} 1484.14
5 {MMAX, CACH, MMIN, CHMAX, MYCT} 1478.36
step()函数对前向选择采用了一种替代性的规格,它会在任何一个剩余的特征加入当前特征子集都无法改善总体评分的情况下终止。对于数据集而言,只有一个特征会从最终模型中排除,因为把它加入进来并没有提高总体评分。既有趣又令人放心的是,这个被排除的特征就是CHMIN,它也是唯一具有相对较高p值的变量,说明在有其他特征存在的情况下我们无法确信输出变量和这个特征是相关的。
有人可能会想知道是否可以从相反方向进行变量选择,也就是从一个完整的模型开始,根据去除哪个特征会给模型评分带来最大的改善来逐个去除特征。这样实际上是可以的,这样的过程被称为后向选择(backward selection)或后向淘汰(backward elimination)。在R语言里的做法是利用step()函数,指定direction参数为backward并从完整模型开始。可以用二手车数据集来演示这个过程,并把结果保存到一个新的二手车模型里:
在二手车数据集上得到的最终线性回归模型的公式如下:
正如我们所见,最终的模型丢弃了Cruise、Sound和Chevy特征。观察我们之前的模型摘要,我们可以看到,这三个特征都具有较高的p值。前面的两种方法是一种贪心算法(greedy algorithm)的示例。这也就是说,一旦作出了是否包含某个变量的选择,它就是最终决定,之后也不能撤销了。为了对它进行弥补,就有了第三种变量选择的方法,它称为混合选择(mixed selection)或双向淘汰(bidirectional elimination),它一开始会表现为前向选择方法,采用的是增加变量的前向步骤,但是在能够改善AIC的情况下也可以包含后向的步骤。不出所料,step()函数在direction参数被指定为both时就是这样做的。
既然有了两个新模型,我们就可以观察它们在测试集上的表现:
对于CPU模型,我们在测试数据集上的表现比初始模型略有改善。合适的下一步的工作可以是探索这个缩减后的特征集是否和去除离群值配合起来效果更好,这个问题留给读者作为练习。相比之下,对于二手车模型,作为去除所有这些特征的结果,我们看到测试MSE略有增加。