特征选择
代码下载
本文主要介绍sklearn中进行特征选择的方法。
sklearn.feature_selection模块中的类可用于样本集的特征选择/降维,以提高估计量的准确性得分或提高其在超高维数据集上的性能。

SelectFromModel 是一个基础分类器,其根据重要性权重选择特征。可与拟合后具有coef_或feature_importances_属性的任何估计器一起使用。如果相应的coef_或feature_importances_值低于提供的threshold参数,则这些特征可以认为不重要或者删除。除了指定数值阈值参数,还可以使用字符串参数查找阈值,参数包括:“mean”, “median” 以及这两个参数的浮点数乘积,例如“0.1*mean”。与threshold标准结合使用时,可以通过max_features参数限制选择的特征数量。

# 多行输出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
import warnings
warnings.filterwarnings("ignore")

1 SelectFromModel基础使用

主要参数说明如下:

  • threshold:用于特征选择的阈值。保留重要性更高或相等的特征,而其特征则被丢弃。threshold为特征重要性的mean或者median,如果为None,并且估计器的参数惩罚显式或隐式设置为l1(例如Lasso),则使用的阈值为1e-5。否则,默认情况下使用mean。
  • prefit:预设模型是否期望直接传递给构造函数。
  • norm_order:在估算器threshold的coef_属性为维度2 的情况下,用于过滤以下系数矢量的范数的顺序
  • max_features:要选择的最大特征数

基础使用方法如下:

from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression
X = [[ 0.87, -1.34, 0.31 ],
[-2.79, -0.02, -0.85 ],
[-1.34, -0.48, -2.55 ],
[ 1.92, 1.48, 0.65 ]]
y = [0, 1, 0, 1]
# 建立评估器
selector = SelectFromModel(estimator=LogisticRegression()).fit(X, y)
# estimator的模型参数
print("estimator的模型参数",selector.estimator_.coef_) # 根据estimator中特征重要性均值获得阈值
print("用于特征选择的阈值;",selector.threshold_) # 哪些特征入选最后特征,true表示入选
print("特征是否保留",selector.get_support())
# 获得最后结果
print("特征提取结果",selector.transform(X));
estimator的模型参数 [[-0.32857694  0.83411609  0.46668853]]
用于特征选择的阈值; 0.5431271870420733
特征是否保留 [False True False]
特征提取结果 [[-1.34]
[-0.02]
[-0.48]
[ 1.48]]

下面演示从糖尿病数据集中选择两个最重要的特征,而无需事先知道阈值。

使用SelectFromModel和Lasso回归模型可以从糖尿病数据集中选择最佳的特征。由于L1规范促进了特征的稀疏性,我们可能只对从数据集中选择最有趣特征的子集感兴趣。本示例说明如何从糖尿病数据集中选择两个最有趣的特征。

糖尿病数据集由从442名糖尿病患者中收集的10个变量(特征)组成。此示例显示了如何使用SelectFromModel和LassoCv查找预测从基线开始一年后疾病进展的最佳两个特征。

import matplotlib.pyplot as plt
import numpy as np from sklearn.datasets import load_diabetes
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LassoCV

首先,让我们加载sklearn中可用的糖尿病数据集。然后,我们将看看为糖尿病患者收集了哪些特征:

diabetes = load_diabetes()

X = diabetes.data
y = diabetes.target feature_names = diabetes.feature_names
print(feature_names)
['age', 'sex', 'bmi', 'bp', 's1', 's2', 's3', 's4', 's5', 's6']

为了确定功能的重要性,我们将使用LassoCV估计器。具有最高绝对值的特征coef_被认为是最重要的。sklearn中coef_说明见:https://www.jianshu.com/p/6a818b53a37e

clf = LassoCV().fit(X, y)
# 模型参数的绝对值
importance = np.abs(clf.coef_)
print("十个特征的重要性:",importance);
十个特征的重要性: [  0.         226.2375274  526.85738059 314.44026013 196.92164002
1.48742026 151.78054083 106.52846989 530.58541123 64.50588257]

接下来我们可以从具有最高分数的模型特征中过滤特征。现在我们要选择两个最重要特征electFromModel()允许设置阈值。仅保留coef_高于阈值的特征。在这里,我们希望将阈值设置为略高于coef_。LassoCV()根据数据计算出高于第三高特征的高阈值。

# 对重要性进行排名
idx_third = importance.argsort()[-3]
threshold = importance[idx_third] + 0.01
print('阈值为',threshold)
idx_features = (-importance).argsort()[:2]
name_features = np.array(feature_names)[idx_features]
print('重要性第三大的特征: {}'.format(name_features)) sfm = SelectFromModel(clf, threshold=threshold);
sfm.fit(X, y) # X_transform为特征提取结果
X_transform = sfm.transform(X)
# 提取的特征数
n_features = sfm.transform(X).shape[1]
阈值为 314.4502601292063
重要性第三大的特征: ['s5' 'bmi'] SelectFromModel(estimator=LassoCV(alphas=None, copy_X=True, cv='warn', eps=0.001, fit_intercept=True,
max_iter=1000, n_alphas=100, n_jobs=None, normalize=False,
positive=False, precompute='auto', random_state=None,
selection='cyclic', tol=0.0001, verbose=False),
max_features=None, norm_order=1, prefit=False,
threshold=314.4502601292063)

最后,我们将绘制从数据中选择的两个特征。

plt.title(
"Features from diabets using SelectFromModel with "
"threshold %0.3f." % sfm.threshold)
feature1 = X_transform[:, 0]
feature2 = X_transform[:, 1]
plt.plot(feature1, feature2, 'r.')
plt.xlabel("First feature: {}".format(name_features[0]))
plt.ylabel("Second feature: {}".format(name_features[1]))
plt.ylim([np.min(feature2), np.max(feature2)])
plt.show();

2 SelectFromModel中不同的特征选择方法

2.1 基于L1范式进行特征选择

用L1范数惩罚的线性模型具有稀疏解:它们的许多估计系数为零。当目标是减少数据的维数以用于另一个分类器时,它们可以与特征一起使用。L1正则化将系数l1范数作为惩罚项添加损失函数上,由于正则项非零,这就迫使那些弱的特征所对应的系数变成0。因此L1正则化往往会使学到的模型很稀疏(系数w经常为0),这个使得L1正则化成为一种常用的征选择方法。特别的用于此目的的稀疏估计量是linear_model.Lasso用于回归,和linear_model.LogisticRegression以及svm.LinearSVC 用于分类。

简单实例如下:

from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel
X, y = load_iris(return_X_y=True)
X.shape lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X, y)
model = SelectFromModel(lsvc, prefit=True)
X_new = model.transform(X)
X_new.shape
(150, 4)
(150, 3)

对于SVM和logistic回归,参数C控制稀疏性:C越小,选择的特征就越少。使用Lasso,alpha参数越高,选择的特征就越少。

2.2 基于树的特征选择

基于树的评估器可以被用来计算特征的重要性,然后可以根据特征的重要性去除不相关的特征 (当配合sklearn.feature_selection.SelectFromModel meta-transformer):

from sklearn.ensemble import ExtraTreesClassifier
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel
X, y = load_iris(return_X_y=True)
X.shape clf = ExtraTreesClassifier(n_estimators=50)
clf = clf.fit(X, y)
print("特征重要性",clf.feature_importances_) model = SelectFromModel(clf, prefit=True)
X_new = model.transform(X)
# 最后保留的特征数
X_new.shape
(150, 4)

特征重要性 [0.07293638 0.06131363 0.44503667 0.42071333]

(150, 2)

以下例子展示了如何使用随机森林来评估人工分类任务中特征的重要性。红色柱状表示特征的重要性及标准差。不出所料,该图表明3个特征是有信息的,而其余特征则没有。

import numpy as np
import matplotlib.pyplot as plt from sklearn.datasets import make_classification
from sklearn.ensemble import ExtraTreesClassifier # Build a classification task using 3 informative features
# 构造一个数据集,特征数为10,但是有效特征只有三个
X, y = make_classification(n_samples=1000,
n_features=10,
n_informative=3,
n_redundant=0,
n_repeated=0,
n_classes=2,
random_state=0,
shuffle=False) # Build a forest and compute the impurity-based feature importances
# 通过随机森林进行分类,并计算各个特征的重要性
forest = ExtraTreesClassifier(n_estimators=250,
random_state=0) forest.fit(X, y)
# 获得重要性
importances = forest.feature_importances_
# 计算标准差
std = np.std([tree.feature_importances_ for tree in forest.estimators_],
axis=0)
indices = np.argsort(importances)[::-1] # Print the feature ranking
# 获得特征排名结果
print("Feature ranking:") for f in range(X.shape[1]):
print("%d. feature %d (%f)" % (f + 1, indices[f], importances[indices[f]])) # Plot the impurity-based feature importances of the forest
# 画出各个特征的重要性
plt.figure()
plt.title("Feature importances")
plt.bar(range(X.shape[1]), importances[indices],
color="r", yerr=std[indices], align="center")
plt.xticks(range(X.shape[1]), indices)
plt.xlim([-1, X.shape[1]]);
Feature ranking:
1. feature 1 (0.295902)
2. feature 2 (0.208351)
3. feature 0 (0.177632)
4. feature 3 (0.047121)
5. feature 6 (0.046303)
6. feature 8 (0.046013)
7. feature 7 (0.045575)
8. feature 4 (0.044614)
9. feature 9 (0.044577)
10. feature 5 (0.043912)

以下示例显示了在图像分类任务(面部)中使用随机森林评估像素点中特征的重要性。像素的热值越高,表明该点对于人脸分类越重要。

from time import time
import matplotlib.pyplot as plt from sklearn.datasets import fetch_olivetti_faces
from sklearn.ensemble import ExtraTreesClassifier # Number of cores to use to perform parallel fitting of the forest model
n_jobs = 1 # Load the faces dataset
data = fetch_olivetti_faces()
X, y = data.data, data.target mask = y < 5 # Limit to 5 classes
X = X[mask]
y = y[mask] # Build a forest and compute the pixel importances
print("Fitting ExtraTreesClassifier on faces data with %d cores..." % n_jobs)
t0 = time()
forest = ExtraTreesClassifier(n_estimators=1000,
max_features=128,
n_jobs=n_jobs,
random_state=0) forest.fit(X, y)
print("done in %0.3fs" % (time() - t0))
# 获得各点的重要性
importances = forest.feature_importances_
importances = importances.reshape(data.images[0].shape) # Plot pixel importances
plt.matshow(importances, cmap=plt.cm.hot)
plt.title("Pixel importances with forests of trees")
plt.show()
Fitting ExtraTreesClassifier on faces data with 1 cores...

ExtraTreesClassifier(bootstrap=False, class_weight=None, criterion='gini',
max_depth=None, max_features=128, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=1000, n_jobs=1,
oob_score=False, random_state=0, verbose=0, warm_start=False) done in 1.018s <matplotlib.image.AxesImage at 0x7feaf2f1f4d0> Text(0.5,1.05,'Pixel importances with forests of trees')

3 参考

https://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.SelectFromModel.html#sklearn.feature_selection.SelectFromModel

https://scikit-learn.org/stable/auto_examples/feature_selection/plot_select_from_model_diabetes.html#sphx-glr-auto-examples-feature-selection-plot-select-from-model-diabetes-py

https://scikit-learn.org/stable/auto_examples/ensemble/plot_forest_importances.html#sphx-glr-auto-examples-ensemble-plot-forest-importances-py

https://scikit-learn.org/stable/auto_examples/ensemble/plot_forest_importances_faces.html#sphx-glr-auto-examples-ensemble-plot-forest-importances-faces-py

[机器学习] 特征选择笔记4-使用SelectFromModel特征选择的更多相关文章

  1. Andrew 机器学习课程笔记

    Andrew 机器学习课程笔记 完成 Andrew 的课程结束至今已有一段时间,课程介绍深入浅出,很好的解释了模型的基本原理以及应用.在我看来这是个很好的入门视频,他老人家现在又出了一门 deep l ...

  2. 【读书笔记与思考】Andrew 机器学习课程笔记

    Andrew 机器学习课程笔记 完成 Andrew 的课程结束至今已有一段时间,课程介绍深入浅出,很好的解释了模型的基本原理以及应用.在我看来这是个很好的入门视频,他老人家现在又出了一门 deep l ...

  3. 《Python 机器学习》笔记(四)

    数据预处理--构建好的训练数据集 机器学习算法最终学习结果的优劣取决于两个主要因素:数据的质量和数据中蕴含的有用信息的数量. 缺失数据的处理 在实际应用过程中,样本由于各种原因缺少一个或多个值得情况并 ...

  4. 机器学习&数据挖掘笔记_14(GMM-HMM语音识别简单理解)

    为了对GMM-HMM在语音识别上的应用有个宏观认识,花了些时间读了下HTK(用htk完成简单的孤立词识别)的部分源码,对该算法总算有了点大概认识,达到了预期我想要的.不得不说,网络上关于语音识别的通俗 ...

  5. 机器学习&数据挖掘笔记(常见面试之机器学习算法思想简单梳理)

    机器学习&数据挖掘笔记_16(常见面试之机器学习算法思想简单梳理) 作者:tornadomeet 出处:http://www.cnblogs.com/tornadomeet 前言: 找工作时( ...

  6. [转]机器学习&数据挖掘笔记_16(常见面试之机器学习算法思想简单梳理)

    机器学习&数据挖掘笔记_16(常见面试之机器学习算法思想简单梳理) 转自http://www.cnblogs.com/tornadomeet/p/3395593.html 前言: 找工作时(I ...

  7. Andrew Ng机器学习课程笔记(五)之应用机器学习的建议

    Andrew Ng机器学习课程笔记(五)之 应用机器学习的建议 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7368472.h ...

  8. Andrew Ng机器学习课程笔记--week1(机器学习介绍及线性回归)

    title: Andrew Ng机器学习课程笔记--week1(机器学习介绍及线性回归) tags: 机器学习, 学习笔记 grammar_cjkRuby: true --- 之前看过一遍,但是总是模 ...

  9. Andrew Ng机器学习课程笔记--汇总

    笔记总结,各章节主要内容已总结在标题之中 Andrew Ng机器学习课程笔记–week1(机器学习简介&线性回归模型) Andrew Ng机器学习课程笔记--week2(多元线性回归& ...

随机推荐

  1. 『现学现忘』Git基础 — 36、标签tag(一)

    目录 1.标签介绍 2.列出标签 3.创建标签 (1)标签的分类 (2)附注标签 (3)轻量标签 4.后期打标签 1.标签介绍 软件的某个发行版本所对应的,其实就是软件开发过程中,某一个阶段的最后一次 ...

  2. windows设置开机启动程序

    1.新建文件,填写路径 @echo off cd F:\程序路径\ //后面填写3D所在的路径 F: //程序的个盘符 run.bat 把这个文件填写完成后,改个名字,后缀改为bat,并把这个文件放在 ...

  3. 痞子衡嵌入式:i.MXRT中FlexSPI外设不常用的读选通采样时钟源 - loopbackFromSckPad

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT中FlexSPI外设不常用的读选通采样时钟源 - loopbackFromSckPad. 最近碰到一个客户,他们在 i.MX ...

  4. 题解 SP10500 HAYBALE - Haybale stacking

    前言 想了好久树状数组啥的,后来想想写打个差分再说,结果写完一遍AC了-- 强烈安利 题意 一个由 \(n\) 个元素组成的序列,给出 \(k\) 个操作,每次将 \(a\sim b\) 加上 \(1 ...

  5. java-代码编写规范

    命名 变量/方法:小驼峰. mBtnHelloWorld 控件 mBtnTest: 按键 mTvTest:文本

  6. git的介绍、git的功能特性、git工作流程、git 过滤文件、git多分支管理、远程仓库、把路飞项目传到远程仓库(非空的)、ssh链接远程仓库,协同开发

    Git(读音为/gɪt/)是一个开源的分布式版本控制系统,可以有效.高速地处理从很小到非常大的项目版本管理. [1] 也是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码 ...

  7. 支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 前文链接 支持JDK19虚拟线程的web框架,之一:体 ...

  8. 嵌入式-C语言基础:字符串strlen和sizeof的区别

    strlen表示的实际的字符串长度,不会把字符串结束符'\0'计算进去,而sizeof则不是实际的字符串长度,它会把字符串的结束标识符'\0'也包含进去. #include<stdio.h> ...

  9. SpringBoot yml配置文件中,logging.level报错

    报错 *************************** APPLICATION FAILED TO START *************************** Description: ...

  10. Dockerfile 使用 SSH docker build

    如果在书写 Dockerfile 时,有些命令需要使用到 SSH 连接,比如从私有仓库下载文件等,那么我们应该怎么做呢? Dockerfile 文件配置 为了使得 Dockerfile 文件中的命令可 ...