通过随机森林获取特征重要性
我们已经知道通过 L1 正则化和 SBS 算法可以用来做特征选择。
我们还可以通过随机森林从数据集中选择相关的特征。随机森林里面包含了多棵决策树,我们可以通过计算特征在每棵决策树决策过程中所产生的的信息增益平均值来衡量该特征的重要性。
你可能需要参考:《机器学习系列06:决策树》
这种方法无需对特征做归一化或者标准化预处理,也不假设数据集是否线性可分。
以红酒数据集为例。我们可以直接通过 feature_importances_ 属性获取每个特征的重要性,所有特征重要性之和为 1.0。
我们可以更直观地可视化观察一下。
可以看到上面随机森林选出的前 3 个特征最重要的特征中有 2 也出现在了之前在
《机器学习系列12:减少过拟合——降维(特征选择)》中使用 SFS 算法选择的 3 个最重要的特征中。
我们可以通过 scikit-learn 提供的 SelectFromModel 来通过 threshold 参数设定一个阈值 ,选择满足这个贡献度阈值的特征出来。
可以看到选择了 5 个特征,现在我们就用这 5 个特征拟合一下 kNN 算法。
可以对比一下在用 SFS 算法选择的 3 个特征拟合的 kNN 算法。
选择 5 个特征时,模型在训练集和测试集上的表现和选择全部特征的表现相当!
降维(特征选择)
对于不支持正则化的模型来说,我们可以通过降低数据的特征维度来减小模型复杂度,从而避免过拟合。
有两种降维方法:
-
特征选择(feature selection):从原始特征集中选择一部分特征子集。
-
特征抽取(feature extraction):从现有的特征集中抽取信息形成新的特征空间。
顺序特征选择是一种贪心算法,它通过自动选择与问题最相关的特征子集来提升计算效率,剔除不相关的特征或噪声数据来降低模型泛化误差(这对那些不支持正则化的算法来说非常有用)。最终将原始特征从 d 维降低到 k 维。
经典的特征选择算法是顺序反向选择(Sequential Backward Selection,SBS),它旨在通过牺牲一点点模型性能来降低原始数据集的特征维度。在某种程度上,SBS 可以提升过拟合模型的预测性能。
SBS 算法很简单:不断从原始的特征空间中移除特征,直到剩余的特征数达到既定的阈值。
我们需要定义一个判别函数来确定每次移除哪个特征。比如我们可以以移除某个特征之前和之后模型的性能差异作为判别指标。
在 scikit-learn 中实现了两种顺序特征选择算法:顺序反向选择(Sequential Backward Selection,SBS)和顺序前向选择(Sequential Forward Selection,SFS)。
SFS是一种从底向上的方法,第一个特征选择单独最优的特征,第二个特征从其余所有特征中选择与第一个特征组合在一起后表现最优的特征,后面的每一个特征都选择与已经入选的特征组合最优的特征。
scikit-learn 默认使用的是 SFS,所以我们需要指定方向参数为 direction='forward'。
我从 1 开始依次选择红酒数据集的全部 13 个特征,从下图可以看到当特征数量增加到 3 个之后,再增加特征数量模型在训练集上就不会再有明细的性能提升了。
我们可以看是哪 3 个特征能产生这么好的贡献。
通过以下结果可以看到,模型在测试集上仅仅损失了一点点性能。
在实际工作中我们可以牺牲一点点泛化能力来节约大量的计算资源。
L1、L2正则化
如果我们注意到模型在训练集上的表现明显优于模型在测试集上的表现,那么这就是模型过拟合了,也称为 high variance。
产生的过拟合的原因是对于给定的训练集数据来说,模型太复杂了。有几种可以减少过拟合的方法:
-
收集更多的训练数据(通常可行性不大)
-
通过正则化引入对模型复杂度的惩罚
-
选择一个含有较少参数的简单模型
-
减少数据的维度
假设模型的参数是向量 w,那么 L1 和 L2 正则化的定义如下。
L1 正则化通常会产生更稀疏的特征空间,大部分的特征对应的权重都是 0。
如果我们在处理高维且大多数特征都互不相关的数据集时,稀疏性就会十分有用,尤其是在训练数据集样本数比样本特征数还少时。此时 L1 正则化也可以被视为是一种特征选择工具,我们将在下一课学习特征选择。
我们在训练机器学习模型时的目标是使模型在训练集和测试集上的损失不断降低,损失是通过损失函数计算出来的。L1 正则化和 L2 正则化就是在损失函数后面再加上惩罚模型复杂度的因子,并且还附带一个取值在 [0.0, 1.0] 之前的参数 λ 控制惩罚力度。
在 scikit-learn 库中,我们只需要指定 penalty='l1' 或 penalty='l2' 就可以选择使用 L1 还是 L2 正则化了。注意!solver 参数指定了优化算法,lbfgs 优化算法不支持 L1 正则化。