【AI理论学习】Python机器学习中的特征选择

news2025/6/9 15:57:54

Python机器学习中的特征选择

  • 特征选择方法
  • 特征选择的Python库
    • 使用Scikit-learn实现特征选择
      • 方差
      • 卡方检验
      • ANOVA
      • Lasso正则化
      • 递归特征消除
    • 使用Feature-engine进行特征选择
      • 单变量特征选择
      • 相关性
    • Python 中的更多特性选择方法
  • 参考资料

任何数据科学项目的一个重要步骤是选择最具预测性的变量。特征选择的方法有很多种。有些扩展性很好,但只考虑单独的特性,有些计算成本极高,因此只适用于相对较小的数据集,还有一些处于中间位置。

Python 中还有各种特征选择算法的实现,利用了开源库。在一篇文章中涵盖所有这些内容,几乎是不可能的。相反,在本博客中,将介绍用于特性选择的Python库,突出显示每个库中可用的选择方法,然后演示一些特性选择实现。

有关其他功能选择方法的教程和分步代码实现,请查看课程《机器学习中的特征选择》或书籍《Python机器学习的特征选择》。

course: 机器学习中的特征选择:https://www.trainindata.com/p/feature-selection-for-machine-learning
book: Python机器学习中的特征选择:https://leanpub.com/feature-selection-in-machine-learning/

那么如何在Python中特征选择吗?
在进入演示之前,首先简短地回顾一下特征选择和可以用来找到最佳特征子集的不同方法。

特征选择方法

在特征选择中,从数据集中选择一个特征子集来训练机器学习算法。特征选择技术不同于降维,因为它们不会改变变量的原始表示,而只是选择一组较小的特征。通过减少特征的数量,可以提高机器学习模型的性能(即,避免过度拟合) ,同时减少训练时间和创建更多可解释的机器学习模型。
传统的特征选择方法分为过滤法、包装法和嵌入法。
特征选择的方法
过滤法(Filter methods)基于特征的特性,选择最佳特征,忽略它们与机器学习模型的交互。他们对特征进行排名,然后选择排名靠前的特征。排名方法通常使用卡方(chi-square)、方差分析(ANOVA)、相关性(correlation)和互信息(mutual information)等统计检验。

包装法(Wrapper methods)围绕预测模型搜索最相关的特征。它们生成多个特征子集,然后根据分类器或回归模型评估它们的性能。所选特征是来自返回最佳性能模型的子集的特征。

嵌入法(Embedded methods)将选择过程“嵌入”到预测模型的训练中。决策树中的Lasso 和feature importance是嵌入式方法的经典例子。线性模型的系数也可以用来选择重要特征。

在数据预处理过程中,特征选择和特征工程被广泛应用于数据科学。那么我们如何在Python中做到这一点呢?

特征选择的Python库

有3个Python库包含特征选择模块:Scikit-learnMLXtendFeature-engine

  • Scikit-learn 包含过滤法、包装法和嵌入法的算法,包括递归特征消除。
  • MLXend 包含用于实现正向、反向和穷举搜索的transformers。
  • Feature-engine包含了基于机器学习模型性能的特征选择方法、特征重组以及支持分类变量的特征选择技术。

三个Python库的比较
在本文中,我们将使用 Scikit-learn 和 Feature-engine 实现各种特征选择技术。

使用Scikit-learn实现特征选择

Scikit-learn 包含过滤法、包装法和嵌入法的算法,包括递归特征消除。在各种滤波方法中,我们可以利用特征的方差或基于方差分析来选择特征。我们来研究一下这些程序。

方差

通过Scikit-learn,可以通过观察特征的可变性(variability)来去除不相关的特征。标准差为零的特征是常数,可以删除。在这个示例中,我们将创建一个具有3个常量变量的玩具数据集,然后我们将使用 Scikit-learn 删除它们。

import pandas as pd
from sklearn.datasets import make_classification
from sklearn.feature_selection import VarianceThreshold

# Toy dataset with redundant and constant features
X, y = make_classification(
    n_samples=1000,
    n_features=10,
    n_classes=2,
    random_state=10,
)

X = pd.DataFrame(X)

# Add constant features
X[[0, 5, 9]] = 1

# To remove constant features
sel = VarianceThreshold(threshold=0)

# fit finds the features with zero variance
X_t = sel.fit_transform(X)  

X_t包含可变性大于0的预测因子。

卡方检验

当目标变量也是分类变量时,卡方检验适用于分类变量的选择。它根据检验返回的p值对特征进行排名,然后选择排名最高的特征。
注意Scikit-Learn的卡方功能没有执行预期的程序。这是一个已知的问题。而是使用scipy.stats.chi_contingency

ANOVA

当目标变量为分类变量时,方差分析适用于连续变量的选择。探索如何使用ANOVA和Scikit-learn来选择特征。我们将使用乳腺癌数据集:

import pandas as pd
import matplotlib.pyplot as plt

from sklearn.datasets import load_breast_cancer
from sklearn.feature_selection import SelectKBest
from sklearn.model_selection import train_test_split

# load dataset
breast_cancer = load_breast_cancer()
X = pd.DataFrame(breast_cancer.data, columns=breast_cancer.feature_names)
y = breast_cancer.target

# Separate data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

# Rank and select features
sel = SelectKBest(score_func = f_classif, k=10).fit(X_train, y_train)

# remove features
X_train_t = sel.transform(X_train)
X_test_t = sel.transform(X_test)

使用SelectKBest,我们指定要选择的特性的数量。这是一个任意值,但可以通过交叉验证优化。

Lasso正则化

Lasso可以将线性模型的一些系数缩小到0,从而选择开箱即用的特征。在这里,将展示如何使用分类和回归数据集使用Lasso选择特征。

从导入库、函数和类开始:

import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer, fetch_california_housing
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import Lasso, LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

接下来,从Scikit learn导入乳腺癌数据集,以预测肿瘤是良性还是恶性。这是一个分类数据集。接下来,我们将把数据分成训练集和测试集:

breast_cancer = load_breast_cancer()
X = pd.DataFrame(breast_cancer.data, columns=breast_cancer.feature_names)
y = breast_cancer.target
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

从Scikit-Learn进行标准化:

scaler = StandardScaler()
scaler.fit(X_train)

接下来,选择使用Logistic回归作为分类器的特征,并使用LASSO正则化:

selector = SelectFromModel(
    LogisticRegression(C=0.5, penalty='l1', solver='liblinear', random_state=10))

selector.fit(scaler.transform(X_train), y_train)

通过执行selector.get_support(),我们获得了具有非零系数的特征的布尔值矢量:

array([False,  True, False, False, False, False, False,  True,  True,
       False,  True, False, False, False, False,  True, False, False,
       False,  True,  True,  True,  True,  True,  True, False,  True,
        True,  True, False])

可以像下面这样确定要删除的一组特性的名称:

removed_feats = X_train.columns[(selector.estimator_.coef_ == 0).ravel().tolist()]

如果我们执行removed_feats,我们将获得以下数组,其中包含将被删除的功能:

Index(['mean radius', 'mean perimeter', 'mean area', 'mean smoothness',
       'mean compactness', 'mean concavity', 'mean fractal dimension',
       'texture error', 'perimeter error', 'area error', 'smoothness error',
       'concavity error', 'concave points error', 'symmetry error',
       'worst compactness', 'worst fractal dimension'],
      dtype='object')

我们可以像下面这样从训练和测试集中移除这些特性:

X_train_selected = selector.transform(scaler.transform(X_train))
X_test_selected = selector.transform(scaler.transform(X_test))

如果我们现在执行x_train_selected.shapex_test_selected.shape,我们将获得数据集的形状:((426,14),(143,14))。
继续并更改惩罚值©以查看结果是否更改。C的最佳值,也就是最佳特征子集,可以用交叉验证来确定

递归特征消除

递归特征消除是一个连续的过程,在每次迭代之后去除一个特征,并且在每次消除之后重新评估特征的重要性。在 Scikit-learn 中,我们可以使用 RFE 或 RFECV 实现递归特征消除。

让我们使用随机森林的重要性递归地选择特征。我们将使用乳腺癌数据集,并将数据分为训练数据集和测试数据集。应仅根据训练数据选择特征

import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import RFE
from sklearn.model_selection import train_test_split

# load dataset
breast_cancer = load_breast_cancer()
X = pd.DataFrame(breast_cancer.data, columns=breast_cancer.feature_names)
y = breast_cancer.target

# Separate data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

clf = RandomForestClassifier(n_estimators=10, random_state=10)

sel_ = RFE(
    clf,
    n_features_to_select=8,
    step=2,
)

sel_.fit(X_train, y_train)

X_train_selected = sel_.transform(X_train)
X_test_selected = sel_.transform(X_test)

结果由具有所选特征的 Numpy 数组组成。

使用Feature-engine进行特征选择

Feature-engine包含许多类,它们基于递归特征消除或添加、特征重组、种群稳定性指数、平均目标值、基数等方法来选择特征。查看 Feature-engine 的文档了解更多细节。

单变量特征选择

Feature-engine包括基于每个类别或箱的目标变量平均值和单个特征分类器或回归器性能度量的单变量特征选择方法。

在单特征模型性能中,针对每个特征训练机器学习模型,仅将该特征作为输入,并基于该模型性能对特征进行排序。
让我们根据使用交叉验证的单特征模型性能选择特征:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.tree import RandomForestClassifier

from feature_engine.selection import SelectBySingleFeaturePerformance

# load dataset
breast_cancer = load_breast_cancer()
X = pd.DataFrame(breast_cancer.data, columns=breast_cancer.feature_names)
y = breast_cancer.target

# Separate data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

sel = SelectBySingleFeaturePerformance(
    estimator=RandomForestClassifier(random_state=10),
    scoring='roc_auc',
    cv=3,
    threshold=None,
)

X_train_t = sel.fit_transform(X_train, y_train)
X_test_t = sel.transform(X_test)

基于单个特征分类器,我们可以对特征进行可视化处理,探索特征的重要性:

pd.Series(sel.feature_performance_).sort_values(
    ascending=False).plot.bar(figsize=(10, 5))

plt.ylabel('roc-auc')
plt.title('Univariate performance')

单变量重要性

相关性

当训练线性或逻辑回归等线性模型时,多重共线性可能会影响模型性能。因此,删除相关特征可能很有用。

Feature-engine 包含基于特征相关性选择特征的算法。SmartCorrelationSelector 找到相关的特征组,然后保留缺少数据点较少、基数(cardinality )或可变性(variability)较高,或模型派生重要性较高的特征组。

如何找到相关的功能?我们可以使用pandas.corr方法。

import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme()

from sklearn.datasets import make_classification

# Toy dataset with correlated features

X, y = make_classification(
    n_samples=1000,
    n_features=10,
    n_redundant=7,
    n_classes=2,
    random_state=10,
)

X = pd.DataFrame(X)

# the default correlation method of pandas.corr is pearson
corrmat = X_train.corr(method='pearson')

# we can make a heatmap with seaborn
sns.heatmap(corrmat, annot=True)
plt.show()

相关性热图

Python 中的更多特性选择方法

  • course: Feature Selection for Machine Learning
  • book: Feature Selection in Machine Learning with Python

参考资料

[1] Feature selection in machine learning with Python

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

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

相关文章

vue实现文件下载

引言 最近在自己做项目的需求的过程中,需要vuespringboot实现文件的下载功能(导出博客文件)。 问题重现 在我后端文件下载接口开发完成后,使用vue前端去进行对接时出现了问题。 我是直接使用的axios去进行请求接口&#xff0c…

Python 炫技操作:条件语句的七种写法

原代码 这是一段非常简单的通过年龄判断一个人是否成年的代码,由于代码行数过多,有些人就不太愿意这样写,因为这体现不出自己多年的 Python 功力。 if age > 18:return "已成年" else:return "未成年"下面我列举了六…

SwiftUI 中创建谷歌字体浏览器

Google Fonts是设计用户界面时使用的免费字体的转到站点。本教程将展示如何编写一个简单的工具来预览这些字体,而无需在系统中注册每种字体。 该应用程序包含一个拆分视图,该视图在左侧面板中包含字体列表。右侧面板将显示字体样式选项的预览。 项目设置 创建一个名为 Googl…

Vue2之webpack篇(一)

目录 前言 1、什么是webpack? 2、传统开发模式 一、传统开发模式 1、场景 2、问题 3、原因 4、解决方案 二、ES6模块化 1、ES6的解决方案 3、拓展 4、取别名 5、*搭配取别名 6、导出default{} 三、CommonJS规范 1、推荐文档 2、使用CommonJS规范解决方…

十二、DockerFile构建过程解析

1、概述 Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。 在Docker 常用命令篇中,我们已经知道了2中构建镜像的方式 export\import 和 commit方式。这两种方式都需要先运行并创建容器,然后在容器…

python自学之《21天学通Python》(5)

第8章 复杂程序组织 当一个应用程序简单时,将程序代码写入一个文件即可。但随着应用程序或项目复杂度增加时,如果将所有代码都写入同一个文件中时,会出现文件过长或过大,即不方便代码浏览,也不方便代码的管理、使用与维…

人工智能人才缺口暴增,想转行的你赶紧把Python学起来...

当前AI人才极度紧缺,据《中国ICT人才生态白皮书》研究分析,到2018年底,我国人工智能人才缺口将突破100万,到2020年,这一数字将攀升到226万。 在过去的几年中,Python已经成为现代软件开发,基础设…

Web测试的各个测试点,居然这么全!(文末送web测试方法大全一份)

1 什么是Web测试? Web测试测试Web或Web应用程序的潜在错误。它是在上线前对基于网络的应用程序进行完整的测试。 UI测试功能测试数据库测试性能测试兼容性测试安全测试自动化测试 2 WEB测试主要测试场景 1.UI测试 界面是否美观,风格、字体、样式是否…

初识: 对象的属性特征

1. 前言 2. 什么是对象的属性特征 3. 灵活控制对象的属性特征 4. configurable: false 是单向设置的 1. 前言 众所周知,默认情况下我们可以任意对自己定义的对象进行增删改的。但是,在某些情况下,我们不能让别人去随便修改我们定义的对象的…

《数据结构》二叉数

学习目录树型结构概念树的重要概念树的表示形式二叉数概念特殊的二叉树二叉树的性质练习题树型结构 概念 树是一种非线性的数据结构,由 n 个有限节点组成一个有层次关系的集合 它具有以下的特点: 有一个特殊的结点,称为根结点,…

【 Threejs 】- Shader 着色器实例渲染教程

着色器在threejs中是一个难点,话不多说,先来看看着色器是什么? 如果您已经有使用计算机绘图的经验,您就会知道在这个过程中您先画一个圆,然后画一个矩形、一条线、一些三角形,直到您组成您想要的图像。这个…

面试真题 | 什么是 Redis ? Redis缓存应用场景有哪些?

面试官问题 redis击穿、穿透有什么区别?如何设计用例及测试 Redis 的基本概念 在没有添加 Redis 的时候,后端的查询流程是: 用户访问页面。请求后端服务。经过逻辑处理后,去数据库查询信息。 在添加 Redis 的之后,…

MySQL 服务端口大全

介绍 MySQL默认服务端口3306/TCP都不会陌生,但MySQL提供服务只有单纯的这个端口吗。在8.0版本默认启动的时候会发现,出现新的端口。 可以说MySQL使用的端口数量取决于所启用的特性、所使用的组件、应用程序连接的方式以及环境的其他方面。 按照官方说…

转速传感器信号隔离变送器正弦波输入方波信号输出

特点 转速传感器信号直接输入,方波信号输出正弦波、锯齿波信号输入,方波信号输出200mV峰值微弱信号的放大与整形不改变原波形频率,响应速度快电源、信号:输入/输出 3000VDC三隔离辅助电源:5V、12V、15V或24V直流单电源…

Huffman编码

目录背景Huffman编码代码部分背景 在数据传输,保存的时候,特别是在数据量特别大的时候传输,保存数据是一件特别麻烦的事。比如逛淘宝的时候,首页会有很多商家展示自己产品的高清图片,如果不对图片进行压缩服务端保存图…

经历百度、美团两次被裁后,我能在小公司躺平吗?

百度裁员后我进入体制内,专心学习自动化 百度被裁后,我意识到自学效果不佳,跟不上职场的所需,于是有了系统学习的想法。 这时的新工作是在体制内,工作强度不大,时间上也比较自由,便正式成为了…

非零基础自学Golang 第12章 接口与类型 12.5 类型断言

非零基础自学Golang 文章目录非零基础自学Golang第12章 接口与类型12.5 类型断言12.5.1 ok-pattern12.5.2 switch-type第12章 接口与类型 12.5 类型断言 类型断言是使用在接口变量上的操作。 简单来说,接口类型向普通类型的转换就是类型断言。 类型断言的语法是…

【关于时间序列的ML】项目 1 :使用 Python 进行 Covid-19 病例 预测

🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…

rk3568 | 瑞芯微平台GPIO引脚驱动编写

最近在玩瑞芯微平台的产品,移植了几个设备的驱动,遇到了一些问题,总结后发现大部分问题都出在了GPIO配置的问题上,写下本篇文章,用来分享一下调试的心得。 有喜欢瑞芯微的朋友,可以加我好友,拉…

JVM的作用,结构

源文件经过编译,生成字节码文件 JVM执行字节码文件(实际上就是将字节码解释成具体平台上的机器指令) jdk,jre,jvm三者的关系: jvm的组成: (1)类加载器子系统:负责将.class文件加载到JVM中 (2)…