百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

sklearn中的特征选择单变量选择法【上】

toyiye 2024-06-21 12:31 9 浏览 0 评论

在特征选择中,最适合在探索阶段使用的就是过滤式的方法,比如方差阈值法和单变量选择法。在上一篇文章中我们介绍了如何在sklearn中使用方差阈值法,那么今天我们就进一步介绍更加实用、有效的单变量选择法。

sklearn中的单变量选择法

单变量选择法的主要思路是根据某些统计检验的方法分别对每个变量进行检验,得到一组分数、p-value数据,然后我们排序选择分数最高(或p-value最小等)的那些特征。在sklearn中,分别针对不同的统计检验方法和不同的排序选择标准提供了不同的工具,比如用于回归问题的f_regression、mutual_info_regression分数,用于分类问题的f_classif、chi2、mutual_info_classf分数;以及用于特征排序和选择的SelectKBest、SelectPercentile、SelectFpr等。把这两类工具相结合,就可以完成特征选择的任务了。

今天我们先学习一下选择方法,在下一篇文章中,我们再介绍不同的评分方法。

1. SelectKBest

顾名思义,SelectKBest方法就是从所有特征中挑选出最好的K个特征组成新的特征集。如何来定义最好呢?这要取决于我们传入的评分函数,该方法默认会使用f_classif,这种方法适用于为分类模型评估特征,与之对应的是f_regression,它适用于回归模型的特征评估。

我们来看一个简单的例子。

from sklearn.datasets import load_boston
from sklearn.feature_selection import SelectKBest, f_regression
from sklearn.metrics import r2_score, mean_squared_error
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
boston = load_boston()
X = boston.data
y = boston.target
print(X.shape)
print(y.shape)

输出为:

(506, 13)
(506,)

这里我们导入了波士顿房价的数据集,该数据集是一个回归问题,共有506个样本、13个特征,我们的任务是根据这13个特征来预测房价。我们先使用所有的特征数据来训练一个模型,作为一个基准。

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1001)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
print('R2: ', r2)
print('MSE: ', mse)

这里我们使用R2和均方误差MSE来作为回归模型效果的评估标准,输出如下:

R2: 0.6783942923302058
MSE: 29.824006898863182

R2来看效果尚可。那么接下来我们就从这13个特征中选择最好的10个特征来训练一个新的模型。

我们先生成新的特征子集:

selector = SelectKBest(f_regression, k=10)
X_new = selector.fit_transform(X, y)
print(X_new.shape)

输出为:

(506, 10)

可以看到,样本数不变,仍为506个,特征则被删减到了10个。接下来我们用这10个特征的数据来训练一个新的模型。注意,在使用train_test_split方法分割测试集和训练集时,我们要保证random_state参数的取值是固定的,这样才能确保不同的模型训练和测试过程中,训练集和测试集的样本是一致的。

X_train, X_test, y_train, y_test = train_test_split(X_new, y, random_state=1001)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
print('R2: ', r2)
print('MSE: ', mse)

输出为:

R2: 0.682644378927699
MSE: 29.429876418646238

对比刚才的R2和MSE,我们发现在我们删掉了3个特征以后,R2略有提升,均方误差MSE略有下降,也就是说我们模型的效果反而更好了。

2. SelectPercentile

SelectPercentile的选取方式与SelectKBest略有不同,后者如我们之前所示,是选取在某种标准下最好的K个特征;而前者,则是在给定一个0到1之间的百分比x%的情况下,选择最好的x%的特征。比如10个特征,前20%的特征就是最好的两个特征,以此类推。

其使用的评分标准与SelectKBest没有什么不同,按需传入所需的评分方法即可。需要注意的是,percentile接受的是一个0到100的整数。

from sklearn.feature_selection import SelectPercentile
selector = SelectPercentile(f_regression, percentile=70)
X_new = selector.fit_transform(X, y)
print(X_new.shape)
X_train, X_test, y_train, y_test = train_test_split(X_new, y, random_state=1001)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
print('R2: ', r2)
print('MSE: ', mse)

输出为:

(506, 9)
R2: 0.6831525503257939
MSE: 29.382751299529424

可以看到,我们选择了前70%的特征(9个),模型的R2?进一步提升。

3. SelectFpr

前两种方法都很好理解,而SelectFpr方法则要求对假设检验有一定的认识。这种方法基于FPR测试,即False Positive Rate,其含义为假阳性率,是指被我们预测为正但实际为负的样本的比例,也就是假设检验中的一类错误发生的比例。

不想深究的同学可以直接简单粗暴地记住,这里就是按照p-value来筛选特征的,p-value越小越好,所有p-value低于我们设定的阈值α的特征都会被选择。由于这个例子中每个特征的p-value都很小,为了演示效果,我们把α设定到十万分之一:

from sklearn.feature_selection import SelectFpr
selector = SelectFpr(f_regression, alpha=0.00001)
X_new = selector.fit_transform(X, y)
print(X_new.shape)
X_train, X_test, y_train, y_test = train_test_split(X_new, y, random_state=1001)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
print('R2: ', r2)
print('MSE: ', mse)

输出为:

(506, 12)
R2: 0.6935405006596658
MSE: 28.419427903725335

可以看到,f_regression检验中,p值在十万分之一以下的特征(第四个)被剔除了。

4. SelectFdr

SelectFdr则是根据错误发现率(FDR,False Discovery Rate)来为特征排序。错误发现率与假阳性率非常相似,但是却有着本质的不同。假阳性率是在所有样本中一类错误发生的概率,而错误发现率则仅仅关注在我们拒绝原假设(预测为正)的样本中,有多大比例是犯了一类错误的(即在"发现"的样本里,有多少是错误的"发现")。

sklearn中的SelectFdr方法使用Benjamini-Hochberg过程对p值进行修正,并筛选出修正后的p值在α水平以下的特征。这一过程的公式很简单,但是其原理较复杂,感兴趣的可以阅读这篇维基百科。

下边这张图是sklearn中的源码,也可以帮助你理解这一过程。

在这个例子中,SelectFdr和SelectFpr的结果是一样的。

from sklearn.feature_selection import SelectFdr
selector = SelectFdr(f_regression, alpha=0.00001)
X_new = selector.fit_transform(X, y)
print(X_new.shape)
X_train, X_test, y_train, y_test = train_test_split(X_new, y, random_state=1001)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
print('R2: ', r2)
print('MSE: ', mse)

输出为:

(506, 12)
R2: 0.6935405006596658
MSE: 28.419427903725335

5. SelectFwe

在多重假设检验中,总体错误率(族系误差率,FWER,family-wise error rate)是另一个常用的错误控制指标,它与FDR的区别在于,FWER是指至少出现一次一类错误的概率,而FDR则是关注预测为正的样本中一类错误发生的比例。

举个例子来帮助大家理解FPR、FDR和FWER之间的区别,共有20个样本,我们做了100次多重检验,其中有30次出现了一类错误,这30次中,平均每次检验中我们会拒绝H010次,其中2次是错误拒绝。这时:

当然,在sklearn中是直接使用特定的过程对p值进行修正,并不是真正地去进行多次模拟并计算各项指标。我们可以再看下sklearn中的源码,来加深对FWER过程的理解:

我们来看下sklearn中的SelectFwe的使用:

from sklearn.feature_selection import SelectFwe
selector = SelectFwe(f_regression, alpha=0.0000001)
X_new = selector.fit_transform(X, y)
print(X_new.shape)
X_train, X_test, y_train, y_test = train_test_split(X_new, y, random_state=1001)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
print('R2: ', r2)
print('MSE: ', mse)

输出为:

(506, 11)
R2: 0.690619122897421
MSE: 28.69034097665137

在不同的α下,SelectFpr、SelectFdr和SelectFwe所选取的特征会出现不同,大家可以自行测试一下。

6. GenericUnivariateSelect

这种方法将上述五种方法集成到了一起,然后我们将评分方法、选择方法以参数的形式传递进来即可。

from sklearn.feature_selection import GenericUnivariateSelect
selector = GenericUnivariateSelect(f_regression, mode='fpr', param=0.0000001)
X_new = selector.fit_transform(X, y)
print(X_new.shape)
X_train, X_test, y_train, y_test = train_test_split(X_new, y, random_state=1001)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
print('R2: ', r2)
print('MSE: ', mse)

输出为:

(506, 12)
R2: 0.6935405006596658
MSE: 28.419427903725335

注意这里的参数名称有所变化。

好,今天就介绍到这里,下次我们会进一步探索不同的评分方法的原理和实践。

相关推荐

如何用 coco 数据集训练 Detectron2 模型?

随着最新的Pythorc1.3版本的发布,下一代完全重写了它以前的目标检测框架,新的目标检测框架被称为Detectron2。本教程将通过使用自定义coco数据集训练实例分割模型,帮助你开始使...

CICD联动阿里云容器服务Kubernetes实践之Bamboo篇

本文档以构建一个Java软件项目并部署到阿里云容器服务的Kubernetes集群为例说明如何使用Bamboo在阿里云Kubernetes服务上运行RemoteAgents并在agents上...

Open3D-ML点云语义分割实验【RandLA-Net】

作为点云Open3D-ML实验的一部分,我撰写了文章解释如何使用Tensorflow和PyTorch支持安装此库。为了测试安装,我解释了如何运行一个简单的Python脚本来可视化名为...

清理系统不用第三方工具(系统自带清理软件效果好不?)

清理优化系统一定要借助于优化工具吗?其实,手动优化系统也没有那么神秘,掌握了方法和技巧,系统清理也是一件简单和随心的事。一方面要为每一个可能产生累赘的文件找到清理的方法,另一方面要寻找能够提高工作效率...

【信创】联想开先终端开机不显示grub界面的修改方法

原文链接:【信创】联想开先终端开机不显示grub界面的修改方法...

如意玲珑成熟度再提升,三大发行版支持教程来啦!

前期,我们已分别发布如意玲珑在deepinV23与UOSV20、openEuler24.03发行版的操作指南,本文,我们将为大家详细介绍Ubuntu24.04、Debian12、op...

118种常见的多媒体文件格式(英文简写)

MP4[?mpi?f??]-MPEG-4Part14(MPEG-4第14部分)AVI[e?vi??a?]-AudioVideoInterleave(音视频交错)MOV[m...

密码丢了急上火?码住7种console密码紧急恢复方式!

身为攻城狮的你,...

CSGO丨CS2的cfg指令代码分享(csgo自己的cfg在哪里?config文件位置在哪?)

?...

使用open SSL生成局域网IP地址证书

某些特殊情况下,用户内网访问多可文档管理系统时需要启用SSL传输加密功能,但只有IP,没有域名和证书。这种情况下多可提供了一种免费可行的方式,通过openSSL生成免费证书。此方法生成证书浏览器会提示...

Python中加载配置文件(python怎么加载程序包)

我们在做开发的时候经常要使用配置文件,那么配置文件的加载就需要我们提前考虑,再不使用任何框架的情况下,我们通常会有两种解决办法:完整加载将所有配置信息一次性写入单一配置文件.部分加载将常用配置信息写...

python开发项目,不得不了解的.cfg配置文件

安装软件时,经常会见到后缀为.cfg、.ini的文件,一般我们不用管,只要不删就行。因为这些是程序安装、运行时需要用到的配置文件。但对开发者来说,这种文件是怎么回事就必须搞清了。本文从.cfg文件的创...

瑞芯微RK3568鸿蒙开发板OpenHarmony系统修改cfg文件权限方法

本文适用OpenHarmony开源鸿蒙系统,本次使用的是开源鸿蒙主板,搭载瑞芯微RK3568芯片。深圳触觉智能专注研发生产OpenHarmony开源鸿蒙硬件,包括核心板、开发板、嵌入式主板,工控整机等...

Python9:图像风格迁移-使用阿里的接口

先不多说,直接上结果图。#!/usr/bin/envpython#coding=utf-8importosfromaliyunsdkcore.clientimportAcsClient...

Python带你打造个性化的图片文字识别

我们的目标:从CSV文件读取用户的文件信息,并将文件名称修改为姓名格式的中文名称,进行规范资料整理,从而实现快速对多个文件进行重命名。最终效果:将原来无规律的文件名重命名为以姓名为名称的文件。技术点:...

取消回复欢迎 发表评论:

请填写验证码