特征选择方法和sklearn中的特征选择应用

本文深入探讨特征工程在模型构建中的核心作用,特别是特征选择的三种关键方法:统计量过滤筛选、模型嵌入式选择和递归包装选择。通过实例演示如何运用sklearn库进行特征选择,并对比各方法优劣。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

特征工程一直都是模型的核心,坊间一直流传一种说法,特征工程决定了模型的上限。而特征选择在特征工程中有着重要地位,一是由于愈发庞大的数据集导致模型计算困难,二是构造特征容易筛选特征却困难,所幸调包解决一切,sklearn中一般有以下几种方式进行特征选择:

  • 通过特征的统计分量选择
  • 通过模型选择的嵌入式选择
  • 通过递归包装选择

1 通过统计分量的特征选择

数据类型可用方法
连续-连续相关系数、假设检验
连续-离散相关系数、连续二值化(最小Gini切分、最大熵增益切分)
连续-离散相关系数(定序)
连续-离散相关系数,熵相关、F分值
离散-离散(非二值)熵相关、Gini、相关系数(定序)

sklearn中常用的类是variance_threshold, SelectKBest和SelectPercentile,第一个为过滤,后面两个为选择,本质都是对特征和目标target的统计量进行排序,既然是统计分量,就需要用到统计函数,sklearn中提供的统计函数主要有以下几种:

  • chi2:卡方检验,通过用于2分类任务
  • f_classif:分类任务中的f检验
  • f_regression:回归任务中的f检验
  • mutual_info_classif:分类任务中的互信息
  • mutual_info_regression:回归任务中的互信息

下面的代码给出了常用的方法,特征个数的选择一般采用cv进行调整。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC
from sklearn.feature_selection import variance_threshold, SelectKBest, SelectPercentile,chi2,f_classif,mutual_info_classif
#用sklearn中自带的肺癌数据集进行测试
data = load_breast_cancer()
X, y = data.get('data'), data.get('target')
#利用互信息进行特征选择,同时利用cv对k进行调参
estimator = SVC()
ks = [i for i in range(10,20)]
scores = []
for k in ks:
    X_select = SelectKBest(mutual_info_classif, k = k).fit_transform(X, y)
    once = cross_val_score(estimator, X_select, y).mean()
    scores.append(once)
plt.plot(ks,scores)    
plt.show()

关于卡方检验,F检验和互信息的内容可以参考文章,一般来说,互信息要比F检验和卡方检验来要的有效,因为后者一般只反映了线性关系。

2 通过模型的嵌入式特征选择

直接通过模型选择的方式往往比利用特征量过滤筛选来得更有效,这也是一种嵌入式的思想,这里也需要调参,特征的重要度threshold,我们可以用cv对所有特征的重要度范围进行筛选,选择合适的阈值。

from sklearn.feature_selection import SelectFromModel
estimator = SVC()
thresholds = np.linspace(0, (estimator.fit(X_train, y_train).feature_importances_).max(),20)
score = []
for i in thresholds:
    X_embeded = SelectFromModel(estimator,  threshold=i).fit_transform(X_train,y_train)
    once = cross_val_score(estimator, X_embeded, y_train, cv=10).mean()
    score.append(once)
plt.figure(figsize=(15,7))
plt.plot(thresholds,score)
plt.show()
best_threshold = thresholds[np.argmax(score)]

3 通过递归包装选择

最后一种方式,是将前两种方式相结合的方式,本质是嵌入式的方式,但是也包装了过滤筛选的方法,函数设定一个step值,每轮对特征进行全排列采样(每次筛选n-step个特征,每次不重复),并利用模型进行计算,计算结果再进行排序,将评价指标较低step的直接抛弃。每轮完成后将递归地调用下一轮计算,直到模型计算的评价指标不再上升,或者满足了最小样本数量要求为止,sklearn提供了两个函数RFE和RFECV,后者在其中添加了cv验证,就不需要再单独使用cv了。

from sklearn.feature_selection import RFECV, RFE

estimator = SVC()
rfe = RFECV(estimator, min_features_to_select=10, step=1, cv=10)
rfe.fit(X, y)
print([i for i,v in enumerate(rfe.get_support()) if v])
X_wrapper = rfe.transform(X)

其中,min_features_to_select为留下的最少的特征数,step为每一步过滤掉的特征数。
递归包装选择虽然高效,但是由于需要递归调用,所以需要比较长的计算时间。

总结

每种方法都不难理解,每种方法都有其优缺点:
(1)统计量过滤筛选:计算快速,但比较粗糙
(2)模型嵌入选择:根据某一算法进行选择,针对性强,用该算法选择的特征来训练模型,可以有效提高训练效果,缺点是需要优化阈值进行筛选,但结果在测试中更容易过拟合一些(高方差)。
(3)包装选择:同样继承了嵌入法的特点,同时不容易丢弃重要的特征组合情况,但是由于需要递归筛选,计算量很大,在一些大的数据集或复杂的算法中需要时间很长。
一般在数据量(维度)大时候,优先采用方差检验和互信息过滤,逻辑回归优先采用嵌入法,SVM优先采用包装法。具体情况再做具体调整。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值