前言
本文总结了特征选择的常用方法,并附上Python实现代码,其中输入数据集均为Dataframe格式,以便于更接近真实项目场景,在定义的N列数据中,最后一列为标签列,其他列为特征列。
一、为什么要进行特征选择?
在机器学习项目中,我们往往不能直接对原始数据进行建模,我们需要对原始数据进行一系列的预处理,得到最合适的数据集来进行建模,特征选择即是一系列预处理中非常重要的一步。
那什么是最合适的数据集呢?最合适的数据集,应当在不显著降低预测精度、不影响数据分布、具有稳定、适应性强等特点的基础上,尽量的小,以助力模型达到准确性、鲁棒性、可解释性和复杂度之间的最优平衡。数据集尽量小,又包括特征纬度和实例纬度,特征选择部分只讨论特征纬度,如何筛选最有用的特征。
二、选择什么样的特征?
对于机器学习模型来说,特征分为以下三类:
- 有效特征:即对模型的效果提升有效果的特征
- 无效特征:即删除或保留对模型效果没有影响的特征
- 有效重复:即虽然特征有效,但是可以由其他有效特征替代或推断的特征
很明显,我们需要选择第一种,即有效特征,删除无效特征,对有效重复特征进行识别和选择性保留,但在实际特征选择工作中,有效特征和无效特征不会有明显的界限,往往需要通过设置基于筛选标准的阈值或保留特征数来确定保留特征。
三、特征选择方法分类
特征选择方法分为三大类,分别为过滤法(Filter)、包裹法(Wrapper)、嵌入法(Embedding)。
(一)、过滤法(Filter)
Filter方法用某个标准对每个特征分别打分,然后根据打分直接用阈值过滤特征。其中方差过滤法仅考虑每个特征本身的方差,而其他方法均衡量每个特征与响应变量之间的关系,再根据得分扔掉不好的特征。
1.方差过滤法:去掉取值变化小的特征,具体方法是考察每个特征单独的方差值,然后给定一个阈值,过滤掉方差小于阈值的特征。
from sklearn.feature_selection import VarianceThreshold
import pandas as pd
# ##构造数据集df_before
df_before = pd.DataFrame([[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]],columns=["columns1","columns2","columns3"])
print "df_before_select:",df_before
##定义阈值,当列方差小于该阈值,删除该列
thres_ = 0.8
##定义筛选模型
select_model = VarianceThreshold(threshold=(thres_ * (1 - thres_)))
##输出筛选数值结果
df_after = select_model.fit_transform(df_before)
##获取筛选后保留的列名
select_name = [df_before.columns.values.tolist()[i] for i in select_model.get_support(indices=True)]
##将列名和数据组合为dataframe,输出筛选后数据集
df_after = pd.DataFrame(df_after,columns=select_name)
print "df_after_select:",df_after
2.卡方检验过滤法:卡方检验是概率论和数理统计中常用的假设检验的思想,通过观察实际值和理论值的偏差来确定原假设是否成立。首先假设某特征与响应变量是独立的(此为原假设);然后观察实际值和理论值之间的偏差程度,若偏差足够小,则认为偏差是自然的样本误差,接受假设;若偏差大到一定程度,则否认原假设,接受备择假设。
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
import pandas as pd
##构造数据集df_before
df_before = pd.DataFrame([[0, 0, 1,"x"], [0, 1, 0,"y"], [1, 0, 0,"y"], [0, 1, 1,"y"], [0, 1, 0,"x"], [0, 1, 1,"x"]],columns=["columns1","columns2","columns3","label"])
print "df_before_select:",df_before
##定义筛选模型
select_model = SelectKBest(chi2, k=1)#选择k个最佳特征
##输出筛选后的数值及列名
df_after = select_model.fit_transform(df_before[["columns1","columns2","columns3"]],df_before["label"])#iris.data是特征数据,iris.target是标签数据,该函数可以选择出k个特征
select_name = [df_before.columns.values.tolist()[i] for i in select_model.get_support(indices=True)]
##将列名和数据组合为dataframe,输出筛选后的数据集
df_after = pd.DataFrame(df_after,columns=select_name)
print "df_after_select:",df_after
3.相关系数过滤法:在特征选择任务中,可以衡量每个特征变量和响应变量之间的相关性来判断特征变量的重要性,同时也可以衡量特征变量与