本文参考木东居士公众号文章《特征工程系列:特征筛选的原理与实现》
数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。由此可见,特征工程在机器学习中占有相当重要的地位。在实际应用当中,可以说特征工程是机器学习成功的关键。
特征工程又包含了Feature Selection(特征选择)、Feature Extraction(特征提取)和Feature construction(特征构造)等子问题,本章内容主要讨论特征选择相关的方法及实现。
在实际项目中,我们可能会有大量的特征可使用,有的特征携带的信息丰富,有的特征携带的信息有重叠,有的特征则属于无关特征,如果所有特征不经筛选地全部作为训练特征,经常会出现维度灾难问题,甚至会降低模型的准确性。因此,我们需要进行特征筛选,排除无效/冗余的特征,把有用的特征挑选出来作为模型的训练数据。

一、相关概念介绍
1. 按重要性分类
**相关特征:**对于学习任务(例如分类问题)有帮助,可以提升学习算法的效果;
**无关特征:**对于我们的算法没有任何帮助,不会给算法的效果带来任何提升;
**冗余特征:**不会对我们的算法带来新的信息,或者这种特征的信息可以由其他的特征推断出;

2.特征选择的目的
对于一个特定的学习算法来说,哪一个特征是有效的是未知的。因此,需要从所有特征中选择出对于学习算法有益的相关特征。而且在实际应用中,经常会出现维度灾难问题。如果只选择所有特征中的部分特征构建模型,那么可以大大减少学习算法的运行时间,也可以增加模型的可解释性。

3.特征选择的原则
获取尽可能小的特征子集,不显著降低分类精度、不影响分类分布以及特征子集应具有稳定、适应性强等特点。

二、特征选择方法
1.Filter(过滤式
先进行特征选择,然后去训练学习器,所以特征选择的过程与学习器无关。相当于先对特征进行过滤操作,然后用特征子集来训练分类器。
**主要思想:**对每一维特征“打分”,即给每一维的特征赋予权重,这样的权重就代表着该特征的重要性,然后依据权重排序。
主要方法:
Chi-squared test(卡方检验)
Information gain(信息增益)
Correlation coefficient scores(相关系数)
优点:运行速度快,是一种非常流行的特征选择方法。
缺点:无法提供反馈,特征选择的标准/规范的制定是在特征搜索算法中完成,学习算法无法向特征搜索算法传递对特征的需求。另外,可能处理某个特征时由于任意原因表示该特征不重要,但是该特征与其他特征结合起来则可能变得很重要。

实现一:去掉取值变化小的特征
该方法一般用在特征选择前作为一个预处理的工作,即先去掉取值变化小的特征,然后再使用其他特征选择方法选择特征。 考察某个特征下,样本的方差值,可以认为给定一个阈值,抛弃哪些小于某个阈值的特征。
1)实现原理
离散型变量:
假设某特征的特征值只有0和1,并且在所有输入样本中,95%的实例的该特征取值都是1,那就可以认为这个特征作用不大。如果100%都是1,那这个特征就没意义了。
连续型变量:需要将连续变量离散化之后才能用。
而且实际当中,一般不太会有95%以上都取某个值的特征存在,所以这种方法虽然简单但是不太好用。可以把它作为特征选择的预处理,先去掉那些取值变化小的特征,然后再从接下来提到的的特征选择方法中选择合适的进行进一步的特征选择。

实现二:单变量特征选择
单变量特征选择方法独立的衡量每个特征与响应变量之间的关系,单变量特征选择能够对每一个特征进行测试,衡量该特征和响应变量之间的关系,根据得分扔掉不好的特征。该方法简单,易于运行,易于理解,通常对于理解数据有较好的效果(但对特征优化、提高泛化能力来说不一定有效);这种方法有许多改进的版本、变种。
(1)Pearson相关系数(Pearson Correlation)
使用条件:线性相关性、连续型特征
皮尔森相关系数是一种最简单的,能帮助理解特征和响应变量之间关系的方法,该方法衡量的是变量之间的线性相关性(即此方法使用的前提假设是变量间具有线性相关性,如果是非线性关系,见下文的熵增益法)。
1)原理介绍

就是用x_i、x_j的协方差除以x_i的标准差和x_j的标准差,可以看成一种剔除了两个变量量纲影响、标准化后的特殊协方差。
协方差是度量各个维度偏离其均值的程度,协方差的值为正值时说明两者是正相关,否则是负相关的。
结果的取值区间为[-1,1],-1表示完全的负相关,+1表示完全的正相关,0表示没有线性相关,绝对值表示相关性的强度。
标准差也称均方差,是方差的算术平方根,能反映一个数据集的离散程度。
2)主要用于连续型特征的筛选,不适用于离散型特征的筛选。
3)优缺点
优点:
相关系数计算速度快、易于计算,经常在拿到数据(经过清洗和特征提取之后的)之后第一时间就执行。Pearson相关系数能够表征丰富的关系,符合表示关系的正负,绝对值能够表示强度。
缺点:
相关系数作为特征排序机制,它只对线性关系敏感,如果关系是非线性的,即便两个变量具有一一对应的关系,相关系数系数也可能会接近0。
(2)互信息和最大信息系数(Mutual information and maximal information coefficient)
如果变量不是独立的,那么我们可以通过考察联合概率分布与边缘概率分布乘积之间的 Kullback-Leibler 散度来判断它们是否“接近”于相互独立。
1)互信息方法
使用前提假设:特征间相互独立、离散型特征
熵H(Y)与条件熵H(Y|X)之间的差称为互信息,互信息与条件熵之间的关系:

其实,这就是ID3决策树的特征选择规则。
互信息法也是评价定性自变量对定性因变量的相关性的,但是并不方便直接用于特征选择:
它不属于度量方式,也没有办法进行归一化,在不同的数据上的结果无法做比较。
只能用于离散型特征的选择,连续型特征需要先进行离散化才能用互信息进行特征选择,而互信息的结果对离散化的方式很敏感(即分段阈值的选择对结果影响较大)。
2)最大信息系数方法
由于互信息法并不方便直接用于特征选择,因此引入了最大信息系数。最大信息数据首先寻找一种最优的离散方式,然后把互信息取值转换成一种度量方式,取值区间为[0,1]。

(3)距离相关系数(Distance correlation)
距离相关系数是为了克服Pearson相关系数只能衡量线性相关性而不能衡量非线性关系的弱点而生的。
1)原理介绍

(5)卡方检验
卡方值描述两个事件的独立性或者描述实际观察值与期望值的偏离程度。
1)原理介绍

CHI值(卡方值)用于衡量实际值与理论值的差异程度,除以T是为了避免不同观察值与不同期望之间产生的偏差因T的不同而差别太大,所以除以E以消除这种弊端。

2)实现流程
CHI值越大,说明两个变量越不可能是独立无关的,也就是说CHI值越大,两个变量的相关程度也越高。
a. 对于特征变量x1,x2,…,xn,以及分类变量y。只需要计算CHI(x1,y)、CHI(x2,y)、…、CHI(xn,y),并按照CHI的值从大到小将特征排序。
b. 选择合适的阈值,大于阈值的特征留下,小于阈值的特征删除。这样筛选出一组特征子集就是输入模型训练的特征。

3)局限性:只适用于分类问题中离散型特征筛选,不能用于分类问题中连续型特征的筛选,也不能用于回归问题的特征筛选。
4)代码实现
现实方法:
sklearn.feature_selection.SelectKBest:
返回k个最佳特征
sklearn.feature_selection.SelectPercentile:
返回表现最佳的前r%个特征

#导入sklearn库中的SelectKBest和chi2
from sklearn.feature_selection import SelectKBest ,chi2
#选择相关性最高的前5个特征
X_chi2 = SelectKBest(chi2, k=5).fit_transform(X, y)
X_chi2.shape
输出:(27, 5)

(6)Relief (Relevant Features) 是一种著名的过滤式特征选择方法,该方法设计了一个"相关统计量"来度量特征的重要性。

2.Wrapper方法(封装式)
直接把最后要使用的分类器作为特征选择的评价函数,对于特定的分类器选择最优的特征子集。
主要思想:将子集的选择看作是一个搜索寻优问题,生成不同的组合,对组合进行评价,再与其他的组合进行比较。这样就将子集的选择看作是一个优化问题,这里有很多的优化算法可以解决,尤其是一些启发式的优化算法,如GA、PSO(如:优化算法-粒子群算法)、DE、ABC(如:优化算法-人工蜂群算法)等。
主要方法:递归特征消除算法
优点:对特征进行搜索时围绕学习算法展开的,对特征选择的标准/规范是在学习算法的需求中展开的,能够考虑学习算法所属的任意学习偏差,从而确定最佳子特征,真正关注的是学习问题本身。由于每次尝试针对特定子集时必须运行学习算法,所以能够关注到学习算法的学习偏差/归纳偏差,因此封装能够发挥巨大的作用。
缺点:运行速度远慢于过滤算法,实际应用用封装方法没有过滤方法流行。

两种顶层特征选择算法
之所以叫做顶层,是因为他们都是建立在基于模型的特征选择方法基础之上的,例如回归和SVM,在不同的子集上建立模型,然后汇总最终确定特征得分。
1.稳定性选择(Stability selection)
稳定性选择常常是一种既能够有助于理解数据又能够挑出优质特征的这种选择。
1)原理介绍
稳定性选择是一种基于二次抽样和选择算法相结合较新的方法,选择算法可以是回归、SVM或其他类似的方法。
它的主要思想是在不同的数据子集和特征子集上运行特征选择算法,不断的重复,最终汇总特征选择结果。比如可以统计某个特征被认为是重要特征的频率(被选为重要特征的次数除以它所在的子集被测试的次数)。
理想情况下,重要特征的得分会接近100%。稍微弱一点的特征得分会是非0的数,而最无用的特征得分将会接近于0。
2)代码实现
sklearn在随机lasso和随机逻辑回归中有对稳定性选择的实现。

from sklearn.linear_model import RandomizedLasso
from sklearn.datasets import load_boston
boston = load_boston()#using the Boston housing data.
#Data gets scaled automatically by sklearn's implementation
X = boston["data"]
Y = boston["target"]
names = boston["feature_names"]rlasso = RandomizedLasso(alpha=0.025)
rlasso.fit(X, Y)print "Features sorted by their score:"
print sorted(zip(map(lambda x: round(x, 4), rlasso.scores_), names), reverse=True)
#输出
Features sorted by their score: [(1.0, ‘RM’), (1.0, ‘PTRATIO’), (1.0, ‘LSTAT’), (0.62, ‘CHAS’), (0.595, ‘B’), (0.39, ‘TAX’), (0.385, ‘CRIM’), (0.25, ‘DIS’), (0.22, ‘NOX’), (0.125, ‘INDUS’), (0.045, ‘ZN’), (0.02, ‘RAD’), (0.015, ‘AGE’)]

在上边这个例子当中,较高的3个特征得分是1.0,这表示他们总会被选作有用的特征(当然,得分会受到正则化参数alpha的影响,但是sklearn的随机lasso能够自动选择最优的alpha)。接下来的几个特征得分就开始下降,但是下降的不是特别急剧,这跟纯lasso的方法和随机森林的结果不一样。能够看出稳定性选择对于克服过拟合和对数据理解来说都是有帮助的:总的来说,**好的特征不会因为有相似的特征、关联特征而得分为0,这跟Lasso是不同的。**对于特征选择任务,在许多数据集和环境下,稳定性选择往往是性能较好的方法之一。

2.递归特征消除(Recursive feature elimination,RFE)
1)原理介绍
递归特征消除的主要思想是**反复构建模型(如SVM或者回归模型)然后选出最好的(或者最差的)的特征(可以根据系数来选),把选出来的特征放到一遍,然后在剩余的特征上重复这个过程,直到所有特征都遍历了。这个过程中特征被消除的次序就是特征的排序。**因此,这是一种寻找最优特征子集的贪心算法。
RFE的稳定性很大程度上取决于在迭代的时候底层用哪种模型。
假如RFE采用的普通的回归,没有经过正则化的回归是不稳定的,那么RFE就是不稳定的。假如RFE采用的是Ridge,而用Ridge正则化的回归是稳定的,那么RFE就是稳定的。
Sklearn提供了RFE包,可以用于特征消除,还提供了RFECV,可以通过交叉验证来对的特征进行排序。

from sklearn.feature_selection import RFE
from sklearn.linear_model import LinearRegression
from sklearn.datasets import load_bostonboston = load_boston()
X = boston["data"]
Y = boston["target"]
names = boston["feature_names"]#use linear regression as the model
lr = LinearRegression()
#rank all features, i.e continue the elimination until the last one
rfe = RFE(lr, n_features_to_select=1)
rfe.fit(X,Y)print "Features sorted by their rank:"
print sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), names))#输出
Features sorted by their rank: [(1.0, ‘NOX’), (2.0, ‘RM’), (3.0, ‘CHAS’), (4.0, ‘PTRATIO’), (5.0, ‘DIS’), (6.0, ‘LSTAT’), (7.0, ‘RAD’), (8.0, ‘CRIM’), (9.0, ‘INDUS’), (10.0, ‘ZN’), (11.0, ‘TAX’), (12.0, ‘B’), (13.0, ‘AGE’)]

3.Embedded方法(嵌入式)
将特征选择嵌入到模型训练当中,其训练可能是相同的模型,但是特征选择完成后,还能给予特征选择完成的特征和模型训练出的超参数,再次训练优化。
主要思想:在模型既定的情况下学习出对提高模型准确性最好的特征。也就是在确定模型的过程中,挑选出那些对模型的训练有重要意义的特征。
主要方法:用带有L1正则化的项完成特征选择(也可以结合L2惩罚项来优化)、随机森林平均不纯度减少法/平均精确度减少法。
优点:对特征进行搜索时围绕学习算法展开的,能够考虑学习算法所属的任意学习偏差。训练模型的次数小于Wrapper方法,比较节省时间。
缺点:运行速度慢。

线性模型与正则化
1.主要思想
当所有特征在相同尺度上时,最重要的特征应该在模型中具有最高系数,而与输出变量不相关的特征应该具有接近零的系数值。即使使用简单的线性回归模型,当数据不是很嘈杂(或者有大量数据与特征数量相比)并且特征(相对)独立时,这种方法也能很好地工作。
2.正则化模型
正则化就是把额外的约束或者惩罚项加到已有模型(损失函数)上,以防止过拟合并提高泛化能力。损失函数由原来的E(X,Y)变为E(X,Y)+alpha||w||,w是模型系数组成的向量(有些地方也叫参数parameter,coefficients),||·||一般是L1或者L2范数,alpha是一个可调的参数,控制着正则化的强度。当用在线性模型上时,L1正则化和L2正则化也称为Lasso和Ridge。

1)L1正则化/Lasso regression
L1正则化将系数w的L1范数作为惩罚项加到损失函数上,由于正则项非零,这就迫使那些弱的特征所对应的系数变成0。因此L1正则化往往会使学到的模型很稀疏(系数w经常为0),这个特性使得L1正则化成为一种很好的特征选择方法。
Lasso能够挑出一些优质特征,同时让其他特征的系数趋于0。当如需要减少特征数的时候它很有用,但是对于数据理解来说不是很好用。

2)L2正则化/Ridge regression
L2正则化将系数向量的L2范数添加到了损失函数中。
由于L2惩罚项中系数是二次方的,这使得L2和L1有着诸多差异,最明显的一点就是,L2正则化会让系数的取值变得平均。
对于关联特征,这意味着他们能够获得更相近的对应系数。
Ridge将回归系数均匀的分摊到各个关联变量上。
L2正则化对于特征选择来说一种稳定的模型,不像L1正则化那样,系数会因为细微的数据变化而波动。所以L2正则化和L1正则化提供的价值是不同的,L2正则化对于特征理解来说更加有用:表示能力强的特征对应的系数是非零。

3.代码实现
1)普通线性模型

from sklearn.linear_model import LinearRegression
from sklearn.datasets import load_boston
#获取boston数据
boston=datasets.load_boston()
x=boston.data
y=boston.target
#过滤掉异常值
x=x[y<50]
y=y[y<50]
reg=LinearRegression()
reg.fit(x,y)
#求排序后的coef
coefSort=reg.coef_.argsort()
#featureNameSort: 按对标记值的影响,从小到大的各特征值名称
#featureCoefSore:按对标记值的影响,从小到大的coef_
featureNameSort=boston.feature_names[coefSort]
featureCoefScore=reg.coef_[coefSort]
print("featureNameSort:", featureNameSort)
print("featureCoefSore:", featureCoefScore)
# 输出:featureNameSort: ['NOX' 'DIS' 'PTRATIO' 'LSTAT' 'CRIM' 'INDUS' 'AGE' 'TAX' 'B' 'ZN' 'RAD' 'CHAS' 'RM']
featureCoefSore: [-1.24268073e+01 -1.21088069e+00 -8.38888137e-01 -3.50952134e-01-1.05574295e-01 -4.35179251e-02 -2.36116881e-02 -1.37702943e-02 7.93577159e-03
3.52748549e-02  2.50740082e-01  4.55405227e-01 3.75411229e+00]

结果分析:
正相关影响系数最大的特征值是”RM”:房间的平均数量,系数值为3.75。
负相关影响系数最大的特征值是”NOX”:一氧化氮浓度,系数值为-1.24。

2)L1正则化线性模型

#A helper method for pretty-printing linear models
def pretty_print_linear(coefs, names = None, sort = False):if names == None:names = ["X%s" % x for x in range(len(coefs))]lst = zip(coefs, names)if sort:lst = sorted(lst,  key = lambda x:-np.abs(x[0]))return " + ".join("%s * %s" % (round(coef, 3), name)for coef, name in lst)from sklearn.linear_model import Lasso
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_bostonboston = load_boston()
scaler = StandardScaler()
X = scaler.fit_transform(boston["data"])
Y = boston["target"]
names = boston["feature_names"]lasso = Lasso(alpha=.3)
lasso.fit(X, Y)print("Lasso model: {}".format(pretty_print_linear(lasso.coef_, names, sort = True)))
# 输出:Lasso model: -3.707 * LSTAT + 2.992 * RM + -1.757 * PTRATIO
+ -1.081 * DIS + -0.7 * NOX + 0.631 * B + 0.54 * CHAS + -0.236 * CRIM
+ 0.081 * ZN + -0.0 * INDUS + -0.0 * AGE + 0.0 * RAD + -0.0 * TAX

许多特征具有系数0。L1正则化回归的稳定性与非正则化线性模型类似,这意味着当数据中存在相关特征时,系数(以及特征等级)即使在小数据变化时也会发生显着变化。

3)L2正则化线性模型

import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.metrics import r2_score
size = 100#We run the method 10 times with different random seeds
for i in range(10):print("Random seed {}".format(i))np.random.seed(seed=i)X_seed = np.random.normal(0, 1, size)X1 = X_seed + np.random.normal(0, .1, size)X2 = X_seed + np.random.normal(0, .1, size)X3 = X_seed + np.random.normal(0, .1, size)Y = X1 + X2 + X3 + np.random.normal(0, 1, size)X = np.array([X1, X2, X3]).Tlr = LinearRegression()lr.fit(X,Y)print("Linear model: {}".format(pretty_print_linear(lr.coef_)))ridge = Ridge(alpha=10)ridge.fit(X,Y)print("Ridge model: {}".format(pretty_print_linear(ridge.coef_)))# 输出
Random seed 0
Linear model: 0.728 * X0 + 2.309 * X1 + -0.082 * X2
Ridge model: 0.938 * X0 + 1.059 * X1 + 0.877 * X2Random seed 1
Linear model: 1.152 * X0 + 2.366 * X1 + -0.599 * X2
Ridge model: 0.984 * X0 + 1.068 * X1 + 0.759 * X2Random seed 2
Linear model: 0.697 * X0 + 0.322 * X1 + 2.086 * X2
Ridge model: 0.972 * X0 + 0.943 * X1 + 1.085 * X2Random seed 3
Linear model: 0.287 * X0 + 1.254 * X1 + 1.491 * X2
Ridge model: 0.919 * X0 + 1.005 * X1 + 1.033 * X2Random seed 4
Linear model: 0.187 * X0 + 0.772 * X1 + 2.189 * X2
Ridge model: 0.964 * X0 + 0.982 * X1 + 1.098 * X2Random seed 5
Linear model: -1.291 * X0 + 1.591 * X1 + 2.747 * X2
Ridge model: 0.758 * X0 + 1.011 * X1 + 1.139 * X2Random seed 6
Linear model: 1.199 * X0 + -0.031 * X1 + 1.915 * X2
Ridge model: 1.016 * X0 + 0.89 * X1 + 1.091 * X2Random seed 7
Linear model: 1.474 * X0 + 1.762 * X1 + -0.151 * X2
Ridge model: 1.018 * X0 + 1.039 * X1 + 0.901 * X2Random seed 8
Linear model: 0.084 * X0 + 1.88 * X1 + 1.107 * X2
Ridge model: 0.907 * X0 + 1.071 * X1 + 1.008 * X2Random seed 9
Linear model: 0.714 * X0 + 0.776 * X1 + 1.364 * X2
Ridge model: 0.896 * X0 + 0.903 * X1 + 0.98 * X2

从示例中可以看出,线性回归的系数变化很大,具体取决于生成的数据。然而,对于L2正则化模型,系数非常稳定并且密切反映数据的生成方式(所有系数接近1)。

随机森林具有准确率高、鲁棒性好、易于使用等优点,这使得它成为了目前最流行的机器学习算法之一。随机森林提供了两种特征选择的方法:mean decrease impurity和mean decrease accuracy。

1.平均不纯度减少(mean decrease impurity)
1)原理介绍
随机森林由多棵CART决策树构成,决策树中的每一个节点都是关于某个特征的条件,为的是将数据集按照不同的响应变量一分为二(二叉树)。
CART利用不纯度(基尼系数,CART的节点选择指标)可以确定节点(最优条件),对于分类问题,通常采用基尼不纯度,对于回归问题,通常采用的是方差或者最小二乘拟合。
当训练决策树的时候,可以计算出每个特征减少了多少树的不纯度。对于一个决策树森林来说,可以算出每个特征平均减少了多少不纯度,并把它平均减少的不纯度作为特征选择的标准。
随机森林基于不纯度的排序结果非常鲜明,在得分最高的几个特征之后的特征,得分急剧的下降。

2)代码实现

from sklearn.datasets import load_boston
from sklearn.ensemble import RandomForestRegressor
import numpy as np#Load boston housing dataset as an example
boston = load_boston()
X = boston["data"]
Y = boston["target"]
names = boston["feature_names"]
# 训练随机森林模型,并通过feature_importances_属性获取每个特征的重要性分数。
rf = RandomForestRegressor()
rf.fit(X, Y)
print("Features sorted by their score:")
print(sorted(zip(map(lambda x: round(x, 4), rf.feature_importances_), names),reverse=True))#输出Features sorted by their score:
[(0.4738, 'RM'), (0.3284, 'LSTAT'), (0.0548, 'DIS'), (0.0373, 'NOX'), (0.0373, 'CRIM'), (0.0247, 'PTRATIO'), (0.0129, 'TAX'), (0.0117, 'AGE'), (0.0094, 'B'), (0.0035, 'RAD'), (0.0026, 'CHAS'), (0.0025, 'INDUS'), (0.001, 'ZN')]

2.平均精确度减少(mean decrease accuracy)
1)原理介绍
通过直接度量每个特征对模型精确率的影响来进行特征选择。
主要思路是打乱每个特征的特征值顺序,并且度量顺序变动对模型的精确率的影响。
对于不重要的变量来说,打乱顺序对模型的精确率影响不会太大。
对于重要的变量来说,打乱顺序就会降低模型的精确率。
2)代码实现

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
from sklearn.ensemble import RandomForestRegressor
from collections import defaultdict
from sklearn.datasets import load_bostonboston=load_boston()
X = boston["data"]
Y = boston["target"]
rf = RandomForestRegressor()
scores = defaultdict(list)
#crossvalidate the scores on a number of different random splits of the dataX_train,X_test,Y_train,Y_test=train_test_split(X,Y,test_size=0.3)# 使用修改前的原始特征训练模型,其acc作为后续混洗特征值后的对比标准。
r = rf.fit(X_train, Y_train)
acc = r2_score(Y_test, rf.predict(X_test))
# 遍历每一列特征
for i in range(X.shape[1]):X_t = X_test.copy()# 对这一列特征进行混洗,交互了一列特征内部的值的顺序np.random.shuffle(X_t[:, i])shuff_acc = r2_score(Y_test, rf.predict(X_t))# 混洗某个特征值后,计算平均精确度减少程度。scores[names[i]].append((acc-shuff_acc)/acc)
print("Features sorted by their score:")
print(sorted([(round(np.mean(score), 4), feat) for feat, score in scores.items()], reverse=True))

总结

(1)去掉取值变化小的特征方法一般用在特征选择前作为一个预处理的工作,即先去掉取值变化小的特征,然后再使用其他特征选择方法选择特征。如果机器资源充足,并且希望尽量保留所有信息,可以把阈值设置得比较高,或者只过滤离散型特征只有一个取值的特征。
(2)单变量特征选择可以用于理解数据、数据的结构、特点,也可以用于排除不相关特征,但是它不能发现冗余特征
(3)正则化的线性模型可用于特征理解和特征选择。相比起L1正则化,L2正则化的表现更加稳定,L2正则化对于数据的理解来说很合适。由于响应变量和特征之间往往是非线性关系,可以采用basis expansion的方式将特征转换到一个更加合适的空间当中,在此基础上再考虑运用简单的线性模型。
(4)随机森林是一种非常流行的特征选择方法,它易于使用。但它有两个主要问题:
重要的特征有可能得分很低(关联特征问题);这种方法对特征变量类别多的特征越有利(偏向问题)

关于训练模型的特征筛选,个人建议的实施流程 :
(1)数据预处理后,先排除取值变化很小的特征。如果机器资源充足,并且希望尽量保留所有信息,可以把阈值设置得比较高,或者只过滤离散型特征只有一个取值的特征。
(2)如果数据量过大,计算资源不足(内存不足以使用所有数据进行训练、计算速度过慢),可以使用单特征选择法排除部分特征。这些被排除的特征并不一定完全被排除不再使用,在后续的特征构造时也可以作为原始特征使用。
(3)如果此时特征量依然非常大,或者是如果特征比较稀疏时,可以使用PCA(主成分分析)和LDA(线性判别)等方法进行特征降维。
(4)经过样本采样和特征预筛选后,训练样本可以用于训练模型。但是可能由于特征数量比较大而导致训练速度慢,或者想进一步筛选有效特征或排除无效特征(或噪音),我们可以使用正则化线性模型选择法、随机森林选择法或者顶层特征选择法进一步进行特征筛选。
(5)最后,特征筛选是为了理解数据或更好地训练模型,我们应该根据自己的目标来选择适合的方法。为了更好/更容易地训练模型而进行的特征筛选,如果计算资源充足,应尽量避免过度筛选特征,因为特征筛选很容易丢失有用的信息。如果只是为了减少无效特征的影响,为了避免过拟合,可以选择随机森林和XGBoost等集成模型来避免对特征过拟合。

数据挖掘实战(二)—特征选择相关推荐

  1. 数据挖掘实战分享:财政收入影响因素分析及预测(二)

    泰迪智能科技(TipDM数据挖掘平台)最新推出的数据挖掘实战专栏 专栏将数据挖掘理论与项目案例实践相结合,可以让大家获得真实的数据挖掘学习与实践环境,更快.更好的学习数据挖掘知识与积累职业经验 专栏中 ...

  2. SAS数据挖掘实战篇【六】

    SAS数据挖掘实战篇[六] 6.3  决策树 决策树主要用来描述将数据划分为不同组的规则.第一条规则首先将整个数据集划分为不同大小的 子集,然后将另外的规则应用在子数据集中,数据集不同相应的规则也不同 ...

  3. 【机器学习】数据挖掘实战:金融贷款分类模型和时间序列分析

    今天给大家带来一个企业级数据挖掘实战项目,金融贷款分类模型和时间序列分析,文章较长,建议收藏! 如果本文对你有所帮助,记得文末点赞和在看,也可分享给你需要的朋友- 项目背景 银行和其他金融贷款机构经常 ...

  4. SAS数据挖掘实战篇【五】

    SAS数据挖掘实战篇[五] SAS--预测模型 6.1 测模型介绍 预测型(Prediction)是指由历史的和当前的数据产生的并能推测未来数据趋势的知识.这类知识可以被认为是以时 间为关键属性的关联 ...

  5. R语言数据挖掘实战系列(4)

    R语言数据挖掘实战系列(4)--数据预处理 数据预处理一方面是要提高数据的质量,另一方面是要让数据更好地适应特定的挖掘技术或工具.数据预处理的主要内容包括数据清洗.数据集成.数据变换和数据规约. 一. ...

  6. 【数据挖掘实战】——航空公司客户价值分析(K-Means聚类案例)

    目录 一.背景和挖掘目标 1.RFM模型缺点分析 2.原始数据情况 3.挖掘目标 二.分析方法与过程 1.初步分析:提出适用航空公司的LRFMC模型 2.总体流程 第一步:数据抽取 第二步:探索性分析 ...

  7. 数据挖掘实战—商品零售购物篮分析

    文章目录 引言 一.数据探索性分析 1.数据质量分析 1.1 缺失值分析 1.2 异常值分析 1.3 重复数据分析 2.数据特征分析 2.1 描述性统计分析 2.2 分布分析 2.2.1 商品热销情况 ...

  8. 数据分析与数据挖掘实战案例本地房价预测(716):

    数据分析与数据挖掘实战案例(7/16): 2022 年首届钉钉杯大学生大数据挑战赛练习题目 练习题 A:二手房房价分析与预测 要点: 1.机器学习 2.数据挖掘 3.数据清洗.分析.pyeahcrs可 ...

  9. 数据挖掘实战—餐饮行业的数据挖掘之挖掘建模

    文章目录 引言 一.分类与预测 1.常用的分类与预测算法 2. 回归分析 3.决策树 4.人工神经网络 二.聚类分析 1.常用的聚类分析算法 2.K-Means聚类算法 2.1 算法过程 2.2 数据 ...

  10. 数据挖掘实战:个人信贷违约预测

    大家好,我是东哥.本次分享一个数据挖掘实战项目:个人信贷违约预测,此项目对于想要学习信贷风控模型的同学非常有帮助,本文首发于公众号:Python数据科学,作者云朵君. 一.个人征信预测模型 1.项目背 ...

最新文章

  1. matlab肌电信号平滑滤波_BCIduino 滤波和频谱计算操作
  2. 问题:AttributeError: module 'tensorflow' has no attribute 'gfile'
  3. C#中的平台调用(P/Invoke)
  4. 一个程序员的奋斗经历1
  5. RUNOOB python练习题29
  6. hadoop启动后,9000端口无法连接,netstat -tpnl中找不到该端口
  7. JAVA类与对象(一)----基础概念理解
  8. php表单选择题代码,php 表单代码
  9. H3C网络暑期培训大作业-某银行支行内部网络整改方案
  10. Matlab中画柱状图详细教程bar函数使用方法(二维附matlab代码)柱状图创建/位置/颜色/图例
  11. PLSQL代码美化配置
  12. [数值计算-1]:数学建模、科学计算、数值计算的关系
  13. Zookeeper选举机制
  14. UG NX二次开发(C#)-UIStyler-ListBox操作
  15. 关于Binder (AIDL)的 oneway 机制
  16. 80篇数据库大数据精华内容
  17. laragon mysql版本_laragon 使用(php版本升级切换)
  18. java 逗号分隔数字_java程序 输入n个数字,以逗号隔开,然后升序排列,再重新输出...
  19. Kotlin之身份证阅读器(华视)二次开发
  20. 天载优配提示商场存在两方面的问题

热门文章

  1. 计算字体和图片的大小
  2. 怎样为Linux内核打补丁(中文版)
  3. JMeter压力测试:单接口压测和多场景混合并发
  4. 机械师F117毒药 评测怎么样
  5. 高级sed编程1--多行命令
  6. 7-12 秀恩爱分得快 (25 分)
  7. 写给自学者的入门指南
  8. MathType破解版式保存后字体变化怎么解决?
  9. 汽车电器设备与维修【2】
  10. 【转】天然嫩肤法 几乎没人知道