前文相关回顾:在决策树算法训练后,可以获取决策树的特征重要性指标。
对当前学习任务有用的属性称为"相关特征" (relevant feature) ;没什么用的属性称为"无关特征" (irrelevant feature)。
从给定的特征集合中选择出相关特征子集的过程,称为"特征选择" (feature selection)。作用:一是解决维数灾难问题,二是去除不相关特征降低学习任务的难度。
处理高维数据的两大主流技术:特征选择、降维。
1、术语
特征选择方法
常见的特征选择方法大致可分为三类:过滤式(filter) 、包裹式(wrapper)和嵌入式(embedding)。
- 过滤式方法先对数据集进行特征选择,然后再训练学习器。代表算法:Relief (Relevant Features)是为二分类问题设计的。
- 包裹式特征选择直接把最终将要使用的学习器的性能作为特征子集的评价准则。代表:LVW (Las Vegas Wrapper)
- 嵌入式特征选择是将特征选择过程与学习器训练过程融为一体,在同一个优化过程中完成,即在学习器训练过程中自动地进行了特征选择。
稀疏表示
假设数据集D是一个矩阵,每行对应一个样本,每列对应一个特征。那么,特征选择问题可转换为特征是否具有稀疏性。
为普通稠密表达的样本找到合适的字典,将样本转化为合适的稀疏表示(sparse representation) 形式,从而使学习任务得以简化,模型复杂度得以降低,通常称为"字典学习" (dictionary learning) ,亦称"稀疏编码" (sparse coding)。
压缩感知
压缩感知(compressed sensing) 根据部分信息来恢复全部信息。
压缩感知分为"感知测量"和"重构恢复"两个阶段,"感知测量"关注如何对原始信号进行处理以获得稀疏样本表示,涉及傅里叶变换、小波变换以及字典学习、稀疏编码等;"重构恢复"关注的是如何基于稀疏性从少量观测中恢复原信号,算法的精髓部分,通常代指压缩感知。
压缩感知直接催生了人脸识别的鲁棒主成分分析和基于矩阵补全的协同过滤。
2、Sklearn代码实现
2.1、移除低方差特征
VarianceThreshold 类将移除方差不满足阈值的特征。默认,将移除所有的零方差特征。
2.2、单变量特征选择
通过基于单变量的统计测试来选择最好的特征,可以当做是评估器的预处理步骤。可选择的类对象,如下:
- SelectKBest 移除评分最高的 K 个特征之外的所有特征
- SelectPercentile 移除设置的最高得分百分比之外的所有特征
- 对每个特征应用常见的单变量统计测试: 假阳性率(false positive rate) SelectFpr, 伪发现率(false discovery rate) SelectFdr , 或者族系误差(family wise error) SelectFwe 。
- GenericUnivariateSelect 允许使用可配置方法来进行单变量特征选择。
以上类的参数-得分函数(score_func)可选择如下:
- 对于回归: f_regression , mutual_info_regression
- 对于分类: chi2 , f_classif , mutual_info_classif
2.3、递归式特征消除
给定一个外部的估计器,可以对特征赋予一定的权重,recursive feature elimination ( RFE ) 通过考虑越来越小的特征集合来递归的选择特征。
2.4、使用 SelectFromModel 选取特征
SelectFromModel 是一个 meta-transformer(元转换器) ,它可以用来处理任何带有 coef_ 或者 feature_importances_ 属性的训练之后的评估器。
示例:鸢尾花数据集分类任务的特征选择
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import datasets
from sklearn.feature_selection import SelectKBest, chi2, SelectFromModel
from sklearn.svm import LinearSVC
if __name__ == '__main__':
# 加载数据
iris = datasets.load_iris()
# 使用样本的所有特征(150, 4)
x = iris.data
y = iris.target
label_dict = iris.target_names
feature_dict = iris.feature_names
# 数据预处理 - 单变量特征选择, k=2选择最好的两个特征
x_best = SelectKBest(chi2, k=2).fit_transform(x, y)
print('特征选择后的维数', x_best.shape) # (150, 2)
# 基于 L1 的特征选取;在 SVM 和逻辑回归中,参数 C 是用来控制稀疏性的:小的 C 会导致少的特征被选择
lsvc = LinearSVC(C=0.01, penalty="l1", dual=False, max_iter=2000).fit(x, y)
model = SelectFromModel(lsvc, prefit=True)
x_model = model.transform(x)
print('特征选择后的维数', x_model.shape) # (150, 3)
# 单变量特征选择的数据散点图
for label, marker, color in zip(range(0, 3), ('*', 's', 'o'), ('blue', 'red', 'green')):
plt.scatter(x=x_best[y == label][:, 0],
y=x_best[y == label][:, 1],
marker=marker,
color=color,
alpha=0.5,
label='label_{}'.format(label))
plt.title('Iris feature selection')
plt.xlabel('xr', fontsize=14)
plt.ylabel('yr', fontsize=14)
plt.legend(loc='upper right', fancybox=True)
plt.tick_params(labelsize=10)
# plt.show()
# SelectFromModel 选取特征特征绘图
fig = plt.figure()
ax3d = Axes3D(fig, rect=[0, 0, 1, 1], elev=20, azim=20)
ax3d.scatter(x_model[:, 0], x_model[:, 1], x_model[:, 2], c=y, cmap='brg')
plt.show()
运行结果,如下图:
从上图的坐标轴数据可以看出:单变量特征选择和使用 SelectFromModel 选取特征的标准是不一样的,除了一个坐标轴刻度相同外,其他坐标轴数据不同。即:SelectFromModel 选择的特征不是“最好”的(SelectKBest)