lasso特征选择python_转:结合Scikit-learn介绍几种常用的特征选择方法-2

4.2 平均精确率减少 Mean decrease accuracy

另一种常用的特征选择方法就是直接度量每个特征对模型精确率的影响。主要思路是打乱每个特征的特征值顺序,并且度量顺序变动对模型的精确率的影响。很明显,对于不重要的变量来说,打乱顺序对模型的精确率影响不会太大,但是对于重要的变量来说,打乱顺序就会降低模型的精确率。

这个方法sklearn中没有直接提供,但是很容易实现,下面继续在波士顿房价数据集上进行实现。

fromsklearn.cross_validationimportShuffleSplit

fromsklearn.metricsimportr2_score

fromcollectionsimportdefaultdict

X = boston["data"]

Y = boston["target"]

rf = RandomForestRegressor()

scores = defaultdict(list)

#crossvalidate the scores on a number of different random splits of the data

fortrain_idx, test_idxinShuffleSplit(len(X),100, .3):

X_train, X_test = X[train_idx], X[test_idx]

Y_train, Y_test = Y[train_idx], Y[test_idx]

r = rf.fit(X_train, Y_train)

acc = r2_score(Y_test, rf.predict(X_test))

foriinrange(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 inscores.items()], reverse=True))

Features sorted by their score: [(0.7276, ‘LSTAT’), (0.5675, ‘RM’),

(0.0867, ‘DIS’), (0.0407, ‘NOX’), (0.0351, ‘CRIM’), (0.0233,

‘PTRATIO’), (0.0168, ‘TAX’), (0.0122, ‘AGE’), (0.005, ‘B’),

(0.0048, ‘INDUS’), (0.0043, ‘RAD’), (0.0004, ‘ZN’), (0.0001,

‘CHAS’)]

在这个例子当中,LSTAT和RM这两个特征对模型的性能有着很大的影响,打乱这两个特征的特征值使得模型的性能下降了73%和57%。注意,尽管这些我们是在所有特征上进行了训练得到了模型,然后才得到了每个特征的重要性测试,这并不意味着我们扔掉某个或者某些重要特征后模型的性能就一定会下降很多,因为即便某个特征删掉之后,其关联特征一样可以发挥作用,让模型性能基本上不变。

5 两种顶层特征选择算法

之所以叫做顶层,是因为他们都是建立在基于模型的特征选择方法基础之上的,例如回归和SVM,在不同的子集上建立模型,然后汇总最终确定特征得分。

5.1 稳定性选择 Stability selection

稳定性选择是一种基于二次抽样和选择算法相结合较新的方法,选择算法可以是回归、SVM或其他类似的方法。它的主要思想是在不同的数据子集和特征子集上运行特征选择算法,不断的重复,最终汇总特征选择结果,比如可以统计某个特征被认为是重要特征的频率(被选为重要特征的次数除以它所在的子集被测试的次数)。理想情况下,重要特征的得分会接近100%。稍微弱一点的特征得分会是非0的数,而最无用的特征得分将会接近于0。

sklearn在随机lasso和随机逻辑回归中有对稳定性选择的实现。

fromsklearn.linear_modelimportRandomizedLasso

fromsklearn.datasetsimportload_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(lambdax: 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是不同的。对于特征选择任务,在许多数据集和环境下,稳定性选择往往是性能最好的方法之一。

5.2 递归特征消除 Recursive feature elimination (RFE)

递归特征消除的主要思想是反复的构建模型(如SVM或者回归模型)然后选出最好的(或者最差的)的特征(可以根据系数来选),把选出来的特征放到一遍,然后在剩余的特征上重复这个过程,直到所有特征都遍历了。这个过程中特征被消除的次序就是特征的排序。因此,这是一种寻找最优特征子集的贪心算法。

RFE的稳定性很大程度上取决于在迭代的时候底层用哪种模型。例如,假如RFE采用的普通的回归,没有经过正则化的回归是不稳定的,那么RFE就是不稳定的;假如采用的是Ridge,而用Ridge正则化的回归是稳定的,那么RFE就是稳定的。

Sklearn提供了RFE包,可以用于特征消除,还提供了RFECV,可以通过交叉验证来对的特征进行排序。

fromsklearn.feature_selectionimportRFE

fromsklearn.linear_modelimportLinearRegression

boston = 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(lambdax: 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’)]

6 一个完整的例子

下面将本文所有提到的方法进行实验对比,数据集采用Friedman #1 回归数据(这篇论文中的数据)。数据是用这个公式产生的:

a4c26d1e5885305701be709a3d33442f.png

X1到X5是由单变量分布生成的,e是标准正态变量N(0,1)。另外,原始的数据集中含有5个噪音变量

X5,…,X10,跟响应变量是独立的。我们增加了4个额外的变量X11,…X14,分别是X1,…,X4的关联变量,通过f(x)=x+N(0,0.01)生成,这将产生大于0.999的关联系数。这样生成的数据能够体现出不同的特征排序方法应对关联特征时的表现。

接下来将会在上述数据上运行所有的特征选择方法,并且将每种方法给出的得分进行归一化,让取值都落在0-1之间。对于RFE来说,由于它给出的是顺序而不是得分,我们将最好的5个的得分定为1,其他的特征的得分均匀的分布在0-1之间。

fromsklearn.datasetsimportload_boston

fromsklearn.linear_modelimport(LinearRegression, Ridge,

Lasso, RandomizedLasso)

fromsklearn.feature_selectionimportRFE, f_regression

fromsklearn.preprocessingimportMinMaxScaler

fromsklearn.ensembleimportRandomForestRegressor

importnumpy as np

fromminepyimportMINE

np.random.seed(0)

size = 750

X = np.random.uniform(0,1, (size,14))

#"Friedamn #1” regression problem

Y = (10* np.sin(np.pi*X[:,0]*X[:,1]) +20*(X[:,2] - .5)**2+

10*X[:,3] +5*X[:,4] + np.random.normal(0,1))

#Add 3 additional correlated variables (correlated with X1-X3)

X[:,10:] = X[:,:4] + np.random.normal(0, .025, (size,4))

names = ["x%s"% iforiinrange(1,15)]

ranks = {}

defrank_to_dict(ranks, names, order=1):

minmax = MinMaxScaler()

ranks = minmax.fit_transform(order*np.array([ranks]).T).T[0]

ranks = map(lambdax: round(x,2), ranks)

returndict(zip(names, ranks ))

lr = LinearRegression(normalize=True)

lr.fit(X, Y)

ranks["Linear reg"] = rank_to_dict(np.abs(lr.coef_), names)

ridge = Ridge(alpha=7)

ridge.fit(X, Y)

ranks["Ridge"] = rank_to_dict(np.abs(ridge.coef_), names)

lasso = Lasso(alpha=.05)

lasso.fit(X, Y)

ranks["Lasso"] = rank_to_dict(np.abs(lasso.coef_), names)

rlasso = RandomizedLasso(alpha=0.04)

rlasso.fit(X, Y)

ranks["Stability"] = rank_to_dict(np.abs(rlasso.scores_), names)

#stop the search when 5 features are left (they will get equal scores)

rfe = RFE(lr, n_features_to_select=5)

rfe.fit(X,Y)

ranks["RFE"] = rank_to_dict(map(float, rfe.ranking_), names, order=-1)

rf = RandomForestRegressor()

rf.fit(X,Y)

ranks["RF"] = rank_to_dict(rf.feature_importances_, names)

f, pval = f_regression(X, Y, center=True)

ranks["Corr."] = rank_to_dict(f, names)

mine = MINE()

mic_scores = []

foriinrange(X.shape[1]):

mine.compute_score(X[:,i], Y)

m = mine.mic()

mic_scores.append(m)

ranks["MIC"] = rank_to_dict(mic_scores, names)

r = {}

fornameinnames:

r[name] = round(np.mean([ranks[method][name]

formethodinranks.keys()]),2)

methods = sorted(ranks.keys())

ranks["Mean"] = r

methods.append("Mean")

print("\t%s"%"\t".join(methods))

fornameinnames:

print("%s\t%s"% (name,"\t".join(map(str,

[ranks[method][name] formethodinmethods]))))

a4c26d1e5885305701be709a3d33442f.png

从以上结果中可以找到一些有趣的发现:

特征之间存在线性关联关系,每个特征都是独立评价的,因此X1,…X4的得分和X11,…X14的得分非常接近,而噪音特征X5,…,X10正如预期的那样和响应变量之间几乎没有关系。由于变量X3是二次的,因此X3和响应变量之间看不出有关系(除了MIC之外,其他方法都找不到关系)。这种方法能够衡量出特征和响应变量之间的线性关系,但若想选出优质特征来提升模型的泛化能力,这种方法就不是特别给力了,因为所有的优质特征都不可避免的会被挑出来两次。

Lasso能够挑出一些优质特征,同时让其他特征的系数趋于0。当如需要减少特征数的时候它很有用,但是对于数据理解来说不是很好用。(例如在结果表中,X11,X12,X13的得分都是0,好像他们跟输出变量之间没有很强的联系,但实际上不是这样的)

MIC对特征一视同仁,这一点上和关联系数有点像,另外,它能够找出X3和响应变量之间的非线性关系。

随机森林基于不纯度的排序结果非常鲜明,在得分最高的几个特征之后的特征,得分急剧的下降。从表中可以看到,得分第三的特征比第一的小4倍。而其他的特征选择算法就没有下降的这么剧烈。

Ridge将回归系数均匀的分摊到各个关联变量上,从表中可以看出,X11,…,X14和X1,…,X4的得分非常接近。

稳定性选择常常是一种既能够有助于理解数据又能够挑出优质特征的这种选择,在结果表中就能很好的看出。像Lasso一样,它能找到那些性能比较好的特征(X1,X2,X4,X5),同时,与这些特征关联度很强的变量也得到了较高的得分。

总结

对于理解数据、数据的结构、特点来说,单变量特征选择是个非常好的选择。尽管可以用它对特征进行排序来优化模型,但由于它不能发现冗余(例如假如一个特征子集,其中的特征之间具有很强的关联,那么从中选择最优的特征时就很难考虑到冗余的问题)。

正则化的线性模型对于特征理解和特征选择来说是非常强大的工具。L1正则化能够生成稀疏的模型,对于选择特征子集来说非常有用;相比起L1正则化,L2正则化的表现更加稳定,由于有用的特征往往对应系数非零,因此L2正则化对于数据的理解来说很合适。由于响应变量和特征之间往往是非线性关系,可以采用basis

expansion的方式将特征转换到一个更加合适的空间当中,在此基础上再考虑运用简单的线性模型。

随机森林是一种非常流行的特征选择方法,它易于使用,一般不需要feature

engineering、调参等繁琐的步骤,并且很多工具包都提供了平均不纯度下降方法。它的两个主要问题,1是重要的特征有可能得分很低(关联特征问题),2是这种方法对特征变量类别多的特征越有利(偏向问题)。尽管如此,这种方法仍然非常值得在你的应用中试一试。

特征选择在很多机器学习和数据挖掘场景中都是非常有用的。在使用的时候要弄清楚自己的目标是什么,然后找到哪种方法适用于自己的任务。当选择最优特征以提升模型性能的时候,可以采用交叉验证的方法来验证某种方法是否比其他方法要好。当用特征选择的方法来理解数据的时候要留心,特征选择模型的稳定性非常重要,稳定性差的模型很容易就会导致错误的结论。对数据进行二次采样然后在子集上运行特征选择算法能够有所帮助,如果在各个子集上的结果是一致的,那就可以说在这个数据集上得出来的结论是可信的,可以用这种特征选择模型的结果来理解数据。

Tips

什么是卡方检验?用方差来衡量某个观测频率和理论频率之间差异性的方法

什么是皮尔森卡方检验?这是一种最常用的卡方检验方法,它有两个用途:1是计算某个变量对某种分布的拟合程度,2是根据两个观测变量的Contingency

table来计算这两个变量是否是独立的。主要有三个步骤:第一步用方差和的方式来计算观测频率和理论频率之间卡方值;第二步算出卡方检验的自由度(行数-1乘以列数-1);第三步比较卡方值和对应自由度的卡方分布,判断显著性。

什么是p-value?简单地说,p-value就是为了验证假设和实际之间一致性的统计学意义的值,即假设检验。有些地方叫右尾概率,根据卡方值和自由度可以算出一个固定的p-value,

什么是响应变量(response

value)?简单地说,模型的输入叫做explanatroy variables,模型的输出叫做response

variables,其实就是要验证该特征对结果造成了什么样的影响

什么是零假设(null

hypothesis)?在相关性检验中,一般会取“两者之间无关联”作为零假设,而在独立性检验中,一般会取“两者之间是独立”作为零假设。与零假设相对的是备择假设(对立假设),即希望证明是正确的另一种可能。

That’s it

References

http://blog.datadive.net/selecting-good-features-part-i-univariate-selection/

http://blog.datadive.net/selecting-good-features-part-ii-linear-models-and-regularization/

http://scikit-learn.org/stable/modules/feature_selection.html#univariate-feature-selection

http://www.quora.com/What-are-some-feature-selection-methods

http://www.quora.com/What-are-some-feature-selection-algorithms

http://www.quora.com/What-are-some-feature-selection-methods-for-SVMs

http://www.quora.com/What-is-the-difference-between-principal-component-analysis-PCA-and-feature-selection-in-machine-learning-Is-PCA-a-means-of-feature-selection

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/291315.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mac Generating Pods project Abort trap: 6

为什么80%的码农都做不了架构师?>>> 为项目添加cocoapods如果产生此种错误时,主要有以下几点原因: 1,cocoapods版本过低: 打开终端在终端输入:pod --version,目前最新版本是1.2.0(2017年3月),如果发现版本过低,则可以在终端输入以下命令:gem install co…

svn 服务器搭建

2019独角兽企业重金招聘Python工程师标准>>> Svn搭建 1. Linux 搭建 YUM 服务器 [rootlocalhost conf]# yum install -y subversion 2.验证安装版本: [rootlocalhost conf]# svnserve –version 3.创建SVN 版本库 [rootlocalhost conf]# mkdir /v…

C# 使用 ValueTasks

C# 7 带有更灵活的 await 关键字;它现在可以等待任何提供 GetAwaiter 方法的对象。一种可用于等待的新类型是 ValueTask。与 Task 类相反,ValueTask 是一个结构。这具有性能优势,因为 ValueTask 在堆上没有对象。与异步方法调用相比&#xff…

Electron - 创建跨平台的桌面客户的应用程序

Electron 框架的前身是 Atom Shell,可以让你写使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序。它是基于io.js 和 Chromium 开源项目,并用于在 Atom 编辑器中。Electron 是开源的,由 GitHub 维护,有一个活跃的…

Cognos TM1_10.1.1服务端配置

场景:本文继Cognos TM1_10.1.1服务端安装 之后,简单的说一下本人对简单配置的拙见,确保服务端在安装过程一切正常,成功安装。 1:进入TM的Cognos Configuration 2:如下图,选中环境,这里可以看出…

java黄油刀_一篇文章玩转ButterKnife,让代码更简洁

前言话说,Android开发的兄弟们都知道,每次初始化控件,设置相应的事件,写的那点过程多而且恶心。我们先一块回顾下不堪的曾经~那些年,我们是这样初始化控件:// 每次的习惯上来写一个initView()方法tvContent…

nodejs的内存管理,垃圾回收机制

2019独角兽企业重金招聘Python工程师标准>>> 要点记录: 1、网页js、命令行工具,快进快出的,即时内存泄露,无内存管理必要! 2、服务器端nodejs和其他正规语言一样存在内存泄露。 3、nodejs基于谷歌v8js引擎&#xff…

Redis【第二篇】集群搭建

第一步:准备 1.安装包 ruby-2.4.0.tar.gz rubygems-2.6.10.tgz zlib-1.2.11.tar.gz redis-3.3.2.gem 2. 架构: 名称IP端口节点属性redisA192.168.6.1286379主节点redisB192.168.6.1289379从节点redisC192.168.6.1296379主节点redisD192.168.6.1299379从节…

(转)java中对集合对象list的几种循环访问总结

Java集合的Stack、Queue、Map的遍历在集合操作中,常常离不开对集合的遍历,对集合遍历一般来说一个foreach就搞定了,但是,对于Stack、Queue、Map类型的遍历,还是有一些讲究的。最近看了一些代码,在便利Map时…

NET框架下如何使用PaddleOCRSharp

打开VSIDE,新建Windows窗体应用(.NETFramework)类型的项目,选择一个.NET框架,如.NETFramework 4.0,右键点击项目,选择属性》生成,目标平台设置成X64.菜单》工具》选项,Nuget包管理器》程序包管理&#xff0…

Redis主从复制(Master-Slave Replication)

案例测试&#xff1a;1. Master新增网卡&#xff0c;修改server端配置IP : 192.168.40.128/24注释&#xff1a; bind&#xff0c;支持网络连接2. 新建虚机slave&#xff0c;配置网络&#xff0c;修改redis配置#slaveof <masterip> <masterport>slaveof 192.168.40.…

如何对一组 IP 地址 进行排序?

咨询区 Cracker我有一组如下IP地址。192.168.1.5 69.52.220.44 10.152.16.23 192.168.3.10 192.168.1.4 192.168.2.1我在寻找一个方法将他们排序成如下顺序。10.152.16.23 69.52.220.44 192.168.1.4 192.168.1.5 192.168.2.1回答区 Alex Aza对 ip 地址进行排序&#xff0c;大概…

如何为APK签名?

1.用来生成应用签名的文件①默认: debug.keystore > debug签名的应用程序不能在Android Market上架销售&#xff0c;它会强制你使用自己的签名。> 不同电脑使用此文件生成的签名不一样。那就意味着如果你换了机器进行apk版本升级&#xff0c;那么将会出现上面那种程序不能…

基于 Azure 的认知服务将文本合成语音

基于 Azure 的认知服务将文本合成语音Intro前几天发了一个 .NET 20 周年祝福视频&#xff0c;语音是通过 Azure 的认知服务合成的&#xff0c;下面就来介绍一下如何将使用 Azure 的认识服务实现将文本合成为语音Prepare你可以在 Azure Portal 上创建一个免费的语音服务&#xf…

sql查询结果集根据指定条件排序的方法

oracle认为 null 最大。 升序排列&#xff0c;默认情况下&#xff0c;null值排后面。 降序排序&#xff0c;默认情况下&#xff0c;null值排前面。 有几种办法改变这种情况&#xff1a; &#xff08;1&#xff09;用 nvl 函数或decode 函数 将null转换为一特定值 &#xff08;2…

mysql怎么改字体编码_mysql怎么改字符编码?

mysql命令行修改字符编码1、修改数据库字符编码mysql> alter database mydb character set utf8 ;2、创建数据库时&#xff0c;指定数据库的字符编码mysql> create database mydb character set utf8 ;3、查看mysql数据库的字符编码mysql> show variables like charac…

如何编译 dotnet/runtime 源代码

前言最近&#xff0c;准备为 dotnet/runtime 修改 issue&#xff0c;但是在 clone 代码后&#xff0c;发现要编译成功&#xff0c;远没有想象中那么容易。因此&#xff0c;将整个过程进行记录&#xff0c;以供大家参考。以下操作都是在 Windows 10 下完成。0.环境准备详见官方文…

jenkins maven testng selenium自动化持续集成

准备环境 首先我们新建一个maven的工程&#xff0c;并且在pom.xml中配置好我们依赖的一些jar包 <dependencies><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>2.46.0<…

java程序 开发工具_15款Java程序员必备的开发工具

如果你是一名Web开发人员&#xff0c;那么用膝盖想也知道你的职业生涯大部分将使用Java而度过。这是一款商业级的编程语言&#xff0c;我们没有办法不接触它。对于Java&#xff0c;有两种截然不同的观点&#xff1a;一种认为Java是最简单功能***大的编程语言之一&#xff0c;另…

SQLite编译问题

从http://www.sqlite.org/主页上获得了SQLite的源文件&#xff0c;还没有时间研究就在编译上发生了不小的问题。 首先是碰到是&#xff0c;编译之后&#xff0c;只产生了sqlite3.dll文件&#xff0c;不产生对应的lib库文件。 查看了下sqlite3.h代码&#xff0c;发现了SQLITE_AP…