Python特征选择

news2025/1/12 3:51:46

1  特征选择的目的

机器学习中特征选择是一个重要步骤,以筛选出显著特征、摒弃非显著特征。这样做的作用是:

  • 减少特征(避免维度灾难),提高训练速度,降低运算开销;

  • 减少干扰噪声,降低过拟合风险,提升模型效果;

  • 更少的特征,模型可解释性更好。

2 特征选择方法

特征选择方法一般分为三类:

图片

2.1 过滤法--特征选择

通过计算特征的缺失率、发散性、相关性、信息量、稳定性等指标对各个特征进行评估选择,常用如缺失情况、单值率、方差验证、pearson相关系数、chi2卡方检验、IV值、信息增益及PSI等方法。

2.1.1 缺失率

通过分析各特征缺失率,并设定阈值对特征进行筛选。阈值可以凭经验值(如缺失率<0.9)或可观察样本各特征整体分布,确定特征分布的异常值作为阈值。

# 特征缺失率
miss_rate_df = df.isnull().sum().sort_values(ascending=False) / df.shape[0]

图片

2.1.2 发散性

特征无发散性意味着该特征值基本一样,无区分能力。通过分析特征单个值的最大占比及方差以评估特征发散性情况,并设定阈值对特征进行筛选。阈值可以凭经验值(如单值率<0.9, 方差>0.001)或可观察样本各特征整体分布,以特征分布的异常值作为阈值。

# 分析方差 
var_features = df.var().sort_values()
 
# 特征单值率
sigle_rate = {}
for var in df.columns:
    sigle_rate[var]=(df[var].value_counts().max()/df.shape[0])

2.1.2 相关性

特征间相关性高会浪费计算资源,影响模型的解释性。特别对线性模型来说,会导致拟合模型参数的不稳定。常用的分析特征相关性方法如:

  • 方差膨胀因子VIF:

方差膨胀因子也称为方差膨胀系数(Variance Inflation),用于计算数值特征间的共线性,一般当VIF大于10表示有较高共线性。

from statsmodels.stats.outliers_influence import variance_inflation_factor
# 截距项
df['c'] = 1
name = df.columns
x = np.matrix(df)
VIF_list = [variance_inflation_factor(x,i) for i in range(x.shape[1])]
VIF = pd.DataFrame({'feature':name,"VIF":VIF_list})

  • person相关系数:

    图片

用于计算数值特征两两间的相关性,数值范围[-1,1]。

图片

import seaborn as sns
corr_df=df.corr()
# 热力图
sns.heatmap(corr_df)
# 剔除相关性系数高于threshold的corr_drop
threshold = 0.9
upper = corr_df.where(np.triu(np.ones(corr_df.shape), k=1).astype(np.bool))
corr_drop = [column for column in upper.columns if any(upper[column].abs() > threshold)]
  • Chi2检验

经典的卡方检验是检验类别型变量对类别型变量的相关性。

图片

Sklearn的实现是通过矩阵相乘快速得出所有特征的观测值和期望值,在计算出各特征的 χ2 值后排序进行选择。在扩大了 chi2 的在连续型变量适用范围的同时,也方便了特征选择。

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
x, y = load_iris(return_X_y=True)

x_new = SelectKBest(chi2, k=2).fit_transform(x, y)

2.1.3  信息量

分类任务中,可以通过计算某个特征对于分类这样的事件到底有多大信息量贡献,然后特征选择信息量贡献大的特征。常用的方法有计算IV值、信息增益。

  • 信息增益

如目标变量D的信息熵为 H(D),而D在特征A条件下的条件熵为 H(D|A),那么信息增益 G(D , A) 为:

图片

信息增益(互信息)的大小即代表特征A的信息贡献程度。

from sklearn.feature_selection import mutual_info_classif
from sklearn.datasets import load_iris
x, y = load_iris(return_X_y=True)
mutual_info_classif(x,y)
  • IV

IV值(Information Value),在风控领域是一个重要的信息量指标,衡量了某个特征(连续型变量需要先离散化)对目标变量的影响程度。其基本思想是根据该特征所命中黑白样本的比率与总黑白样本的比率,来对比和计算其关联程度。【Github代码链接】

图片

2.1.4 稳定性

对大部分数据挖掘场景,特别是风控领域,很关注特征分布的稳定性,其直接影响到模型使用周期的稳定性。常用的是PSI(Population Stability Index,群体稳定性指标)。

  • PSI

PSI表示的是实际与预期分布的差异,SUM( (实际占比 - 预期占比)* ln(实际占比 / 预期占比) )。

图片

在建模时通常以训练样本(In the Sample, INS)作为预期分布,而验证样本作为实际分布。验证样本一般包括样本外(Out of Sample,OOS)和跨时间样本(Out of Time,OOT)

2.2 嵌入法--特征选择

嵌入法是直接使用模型训练得到特征重要性,在模型训练同时进行特征选择。通过模型得到各个特征的权值系数,根据权值系数从大到小来选择特征。常用如基于L1正则项的逻辑回归、Lighgbm特征重要性选择特征。

  • 基于L1正则项的逻辑回归

L1正则方法具有稀疏解的特性,直观从二维解空间来看L1-ball 为正方形,在顶点处时(如W2=C, W1=0的稀疏解),更容易达到最优解。可见基于L1正则方法的会趋向于产生少量的特征,而其他的特征都为0。

图片

from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression

x_new = SelectFromModel(LogisticRegression(penalty="l1", C=0.1)).fit_transform(x,  y)
  • 基于树模型的特征排序

基于决策树的树模型(随机森林,Lightgbm,Xgboost等),树生长过程中也是启发式搜索特征子集的过程,可以直接用训练后模型来输出特征重要性。

import matplotlib.pyplot as plt
from lightgbm import plot_importance
from lightgbm import LGBMClassifier


model = LGBMClassifier()
model.fit(x, y)
plot_importance(model,  max_num_features=20, figsize=(10,5),importance_type='split')
plt.show()
feature_importance = pd.DataFrame({
        'feature': model.booster_.feature_name(),
        'gain': model.booster_.feature_importance('gain'),
        'split': model.booster_.feature_importance('split')
    }).sort_values('gain',ascending=False)

当特征数量多时,对于输出的特征重要性,通常可以按照重要性的拐点划定下阈值选择特征。

图片

2.3 包装法--特征选择

包装法是通过每次选择部分特征迭代训练模型,根据模型预测效果评分选择特征的去留。一般包括产生过程,评价函数,停止准则,验证过程,这4个部分。

(1) 产生过程( Generation Procedure )是搜索特征子集的过程,首先从特征全集中产生出一个特征子集。搜索方式有完全搜索(如广度优先搜索、定向搜索)、启发式搜索(如双向搜索、后向选择)、随机搜索(如随机子集选择、模拟退火、遗传算法)。(2) 评价函数( Evaluation Function )  是评价一个特征子集好坏程度的一个准则。(3) 停止准则( Stopping Criterion )停止准则是与评价函数相关的,一般是一个阈值,当评价函数值达到这个阈值后就可停止搜索。(4) 验证过程( Validation Procedure )是在验证数据集上验证选出来的特征子集的实际效果。

图片

首先从特征全集中产生出一个特征子集,然后用评价函数对该特征子集进行评价,评价的结果与停止准则进行比较,若评价结果比停止准则好就停止,否则就继续产生下一组特征子集,继续进行特征选择。最后选出来的特征子集一般还要验证其实际效果。

  • RFE

RFE递归特征消除是常见的特征选择方法。原理是递归地在剩余的特征上构建模型,使用模型判断各特征的贡献并排序后做特征选择。

from sklearn.feature_selection import RFE
rfe = RFE(estimator,n_features_to_select,step)
rfe = rfe.fit(x, y)
print(rfe.support_)
print(rfe.ranking_)
  • 双向搜索特征选择

鉴于RFE仅是后向迭代的方法,容易陷入局部最优,而且不支持Lightgbm等模型自动处理缺失值/类别型特征,便基于启发式双向搜索及模拟退火算法思想,简单码了一个特征选择的方法【Github代码链接】,如下代码:

import pandas as pd 
import random 

from sklearn.metrics import precision_score, recall_score, f1_score, accuracy_score, roc_curve, auc


def model_metrics(model, x, y, pos_label=1):
    """ 
    评价函数 
    
    """
    yhat = model.predict(x)
    yprob = model.predict_proba(x)[:,1]
    fpr, tpr, _ = roc_curve(y, yprob, pos_label=pos_label)
    result = {'accuracy_score':accuracy_score(y, yhat),
              'f1_score_macro': f1_score(y, yhat, average = "macro"),
              'precision':precision_score(y, yhat,average="macro"),
              'recall':recall_score(y, yhat,average="macro"),
              'auc':auc(fpr,tpr),
              'ks': max(abs(tpr-fpr))
             }
    return result

def bidirectional_selection(model, x_train, y_train, x_test, y_test, annealing=True, anneal_rate=0.1, iters=10,best_metrics=0,
                         metrics='auc',threshold_in=0.0001, threshold_out=0.0001,early_stop=True, 
                         verbose=True):
    """
    model  选择的模型
    annealing     模拟退火算法
    threshold_in  特征入模的>阈值
    threshold_out 特征剔除的<阈值
    """
    included = []
    best_metrics = best_metrics
    
    for i in range(iters):
        # forward step     
        print("iters", i)
        changed = False 
        excluded = list(set(x_train.columns) - set(included))
        random.shuffle(excluded) 
        for new_column in excluded:             
            model.fit(x_train[included+[new_column]], y_train)
            latest_metrics = model_metrics(model, x_test[included+[new_column]], y_test)[metrics]
            if latest_metrics - best_metrics > threshold_in:
                included.append(new_column)
                change = True 
                if verbose:
                    print ('Add {} with metrics gain {:.6}'.format(new_column,latest_metrics-best_metrics))
                best_metrics = latest_metrics
            elif annealing:
                if random.randint(0, iters) <= iters * anneal_rate:
                    included.append(new_column)
                    if verbose:
                        print ('Annealing Add   {} with metrics gain {:.6}'.format(new_column,latest_metrics-best_metrics))
                    
        # backward step                      
        random.shuffle(included)
        for new_column in included:
            included.remove(new_column)
            model.fit(x_train[included], y_train)
            latest_metrics = model_metrics(model, x_test[included], y_test)[metrics]
            if latest_metrics - best_metrics < threshold_out:
                included.append(new_column)
            else:
                changed = True 
                best_metrics= latest_metrics 
                if verbose:
                    print('Drop{} with metrics gain {:.6}'.format(new_column,latest_metrics-best_metrics))
        if not changed and early_stop:
            break 
    return included      

#示例
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y)

model = LGBMClassifier()
included =  bidirectional_selection(model, x_train, y_train, x_test, y_test, annealing=True, iters=50,best_metrics=0.5,
                     metrics='auc',threshold_in=0.0001, threshold_out=0,
                     early_stop=False,verbose=True)

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

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

相关文章

Leetcode 第 365 场周赛题解

Leetcode 第 365 场周赛题解 Leetcode 第 365 场周赛题解题目1&#xff1a;2873. 有序三元组中的最大值 I思路代码复杂度分析 题目2&#xff1a;2874. 有序三元组中的最大值 II思路代码复杂度分析思路2 题目3&#xff1a;2875. 无限数组的最短子数组思路代码复杂度分析 题目4&a…

Oracle的立场:官网更换首页与以色列站在一起

Oracle公司的官网&#xff0c;更换了首页内容&#xff0c;明确表明立场&#xff1a;Oracle与以色列站在一起。 声明指出&#xff1a; Oracle谴责针对以色列及其公民的恐怖袭击。Oracle将为其员工、以色列政府和国防机构提供一切必要的支持。 Magen David Adom是一家为以色列公民…

Java代码审计-因酷网校在线教育系统-越权漏洞分析

登录个人账号后&#xff0c;点击基本资料。有更新资料的功能。 查看这个页面的html源码&#xff0c;进行代码审计。&#xff08;这点怎么通过源码怎么找到的就不提了&#xff0c;写上实在啰嗦了。&#xff09; 代码jsp页面源码如下&#xff0c;查看这个表单信息 注意&#xf…

【Mysql】Mysql中的B+树索引

概述 从上一章节我们了解到InnoDB 的数据页都是由7个部分组成&#xff0c;然后各个数据页之间可以组成一个双向链表 &#xff0c;而每个数据页中的记录会按照主键值从小到大的顺序组成一个单向链表 &#xff0c;每个数据页都会为存储在它里边儿的记录生成一个页目录 &#xff…

【AIGC核心技术剖析】大型语言和视觉助手——LLaVA(论文+源码)

🔥 [新!LLaVA-1.5 在 11 个基准测试上实现了 SoTA,只需对原始 LLaVA 进行简单的修改,利用所有公共数据,在单个 1-A8 节点上在 ~100 天内完成训练,并超越使用数十亿级数据的方法。 LLaVA代表了一种新颖的端到端训练大型多模态模型,结合了视觉编码器和骆马 对于通用的视…

微信小程序开发的OA会议之会议个人中心的页面搭建及模板,自定义组件的学习

目录 一.自定义组件及会议效果编写 效果显示 二.个人中心布局 编写结果 ​编辑 一.自定义组件及会议效果编写 在页面中创建一个以components命名的项目来存放组件 再在components文件夹中创建一个组件&#xff0c;名为 :tabs &#xff0c;创建操作如图所示 刚刚创建好会报…

Android中级——MVVM

MVVM MVVM是什么&#xff1f;MVVM实现前提ModelViewModelView MVVM是什么&#xff1f; Model-View-ViewMode架构&#xff0c;可看作MVP改进版&#xff0c;将此前Presenter的逻辑操作交给ViewMode中的Binder去处理 Mode&#xff1a;封装数据存储及相关操作逻辑&#xff0c;与MV…

LeetCode 799. 香槟塔【数组,模拟,简单线性DP】1855

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

Py之tiktoken:tiktoken的简介、安装、使用方法之详细攻略

Py之tiktoken&#xff1a;tiktoken的简介、安装、使用方法之详细攻略 目录 tiktoken的简介 1、性能&#xff1a;tiktoken比一个类似的开源分词器快3到6倍 tiktoken的安装 tiktoken的使用方法 1、基础用法 (1)、用于OpenAI模型的快速BPE标记器 (2)、帮助可视化BPE过程的代…

【SA8295P 源码分析 (三)】97 - QNX AIS Camera 框架介绍 及 Camera 工作流程分析

【SA8295P 源码分析】97 - QNX AIS Camera 框架介绍 及 Camera 工作流程分析 一、QNX AIS Server 框架分析二、QNX Hypervisor / Android GVM 方案介绍三、Camera APP 调用流程分析四、QCarCam 状态转换过程介绍五、Camera 加串-解串 硬件链路分析六、摄像头初始化检测过程介绍…

观察者模式-对象间的联动

有个商城小程序&#xff0c;用户希望当有新品上市的时候能通知他们。这样用户就可以不要时刻盯着小程序了。在这个场景中&#xff0c;用户向小程序订阅了一个服务——发送新品短信。小程序在有新品上线时负责向订阅客户发出这个消息。 这就是发布-订阅模式&#xff0c;也称观察…

YOLOv5-调用官方权重进行检验(目标检测)

&#x1f368; 本文为[&#x1f517;365天深度学习训练营学习记录博客 &#x1f366; 参考文章&#xff1a;365天深度学习训练营-第7周&#xff1a;咖啡豆识别&#xff08;训练营内部成员可读&#xff09; &#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制](https…

运放的单电源供电设计

文章目录 运放单电源供电同向比例单电源放大电路设计反向比例单电源放大电路设计 运放单电源供电 同向比例单电源放大电路设计 不放大直流&#xff0c;对直流来说是一个电压跟随器&#xff0c;对交流来说是同向比例 反向比例单电源放大电路设计 注&#xff1a;仪表放大器不能直…

Redis内存回收机制-内存淘汰策略和过期策略

Redis是基于内存操作的非关系型数据库&#xff0c;在内存空间不足的时候&#xff0c;为了保证程序的运行和命中率&#xff0c;就会淘汰一部分数据。如何淘汰数据&#xff1f;这就是Redis的内存回收策略。 Redis中的内存回收策略主要有两个方面&#xff1a; Redis过期策略&#…

nodejs+vue云旅青城系统-旅游网站

用户可以实现首页、个人中心、订票信息管理、路线制定管理等。不仅使服务管理难度变低了&#xff0c;还提升了管理的灵活性。目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 …

【四:Spring整合Junit】

目录 相同点不同点1、导入依赖增加2、编写的位置不同。。路径一定要与实现类一致 相同点 前面都一样和Spring整合mybatis&#xff08;基于注解形式&#xff09;一样Spring整合Mybatis 不同点 1、导入依赖增加 <!-- 单元测试 --><dependency><groupId>junit&…

【MySql】8- 实践篇(六)

文章目录 1. MySql保证主备一致1.1 MySQL 主备的基本原理1.2 binlog 的三种格式对比1.3 循环复制问题 2. MySql保证高可用2.1 主备延迟2.2 主备延迟的来源2.3 可靠性优先策略2.4 可用性优先策略 3. 备库为何会延迟很久-备库并行复制能力3.1 MySQL 5.6 版本的并行复制策略3.2 Ma…

Unity之ShaderGraph如何实现马赛克效果

前言 今天我们来实现一个马赛克的效果 如下所示&#xff1a; 关键节点 Posterize&#xff1a;色调分离节点 图像的色调分离或色调分离需要将色调的连续渐变转换为色调较少的几个区域&#xff0c;并从一种色调突然改变为另一种色调。 原理 原理就是通过色调分离节点&…

华纳云:linux怎么搭建node.js开发环境

搭建Node.js开发环境在Linux系统上非常简单&#xff0c;以下是一些基本步骤&#xff0c;以帮助您开始&#xff1a; 1. 安装Node.js&#xff1a; 您可以通过包管理器来安装Node.js。不同的Linux发行版使用不同的包管理器。以下是一些常见的Linux发行版和它们的包管理器&#xff…

虚拟音频设备软件 Loopback mac中文版软件介绍

创建虚拟音频设备以从应用程序和音频输入设备获取声音&#xff0c;然后将其发送到音频处理应用程序&#xff0c;它就是—Loopback for Mac&#xff0c;Loopback mac为您提供高端工作室混音板的强大功能&#xff0c;有了它在Mac上传递音频会变得很容易。 Loopback for mac中文版…