网站首页 > 技术文章 正文
在特征选择中,最适合在探索阶段使用的就是过滤式的方法,比如方差阈值法和单变量选择法。在上一篇文章中我们介绍了如何在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
注意这里的参数名称有所变化。
好,今天就介绍到这里,下次我们会进一步探索不同的评分方法的原理和实践。
猜你喜欢
- 2024-10-02 数学选择4解法,省时又提分,备考生必备
- 2024-10-02 Scratch之变量 scratch变量怎么讲
- 2024-10-02 能够同时利用分类变量和连续变量对个案进行聚类的方法—两步聚类法
- 2024-10-02 西门子PLC | 博途FB入门篇,看这个就够了
- 2024-10-02 一文搞定神秘热图的读与做,超详细!
- 2024-10-02 一文读懂业务数据的分析思路 业务数据分析报告怎么做
- 2024-10-02 【VBA基础】变量的类型和申明变量类型的重要性
- 2024-10-02 从零开始学Java-003-选择控制语句
- 2024-10-02 Python Selenium 变量与选择器选择元素
- 2024-10-02 回归分析 之 一元线性回归 一元线性回归的主要步骤,和每个步骤的关键算法
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)