数据分析 | 特征重要性分析 | 树模型、SHAP值法

前言

        在分析特征重要性的时候,相关性分析和主成分分析往往是比较简单的方法,相关性分析是通过计算特征与目标变量之间的相关系数来评估特征的重要性。它可以告诉我们特征和目标变量之间的线性关系程度,但对于非线性关系就无能为力了;主成分分析是一种降维技术,用于将高维特征数据转化为少数几个主成分。它可以帮助我们理解数据的主要变化模式,但却无法给出具体每个特征对目标变量的影响程度。

        本文基于集成学习的方法介绍另外两种可以分析特征重要性的方法:树模型、SHAP值法。


数据集

        本文使用的数据集为房价数据集,一共有20640个样本,8个特征,1个自变量,除了HouseAge是离散型变量,其余均为连续型变量。树模型分析重要性和贝叶斯优化时,均使用原始数据,SHAP值法时使用归一化后的数据。

d51445e4c2624312a5a6ef8ed17ba7eb.png

原始数据节选


TPE过程贝叶斯优化超参数寻优

        集成学习中超参数设置一直是大问题,本文通过调用Optuna库进行TPE过程的贝叶斯优化,对三种树模型进行超参数寻优。代码如下:

import optuna
from sklearn.model_selection import KFold,cross_validate
import pandas as pd
import numpy as np
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
import time
start_time = time.time()# 读取数据
data = pd.read_csv(r'D:\2暂存文件\Sth with Py\重要性程度分析\data.csv')
X = data.iloc[:,[0, 1, 2, 3, 4, 5, 6, 7]]
y = data.iloc[:,8]'''贝叶斯随机森林寻优'''
# 定义目标函数和参数空间
def optuna_objective(trial):# 定义参数空间n_estimators = trial.suggest_int('n_estimators', 10, 30, 1)max_depth = trial.suggest_int('max_depth', 10, 30, 1)max_features = trial.suggest_int('max_features', 10, 30, 1)# 定义评估器reg = RandomForestRegressor(n_estimators=n_estimators,max_depth=max_depth,max_features=max_features,random_state=1412,verbose=False,n_jobs=-1)# 定义交叉过程,输出负均方误差cv = KFold(n_splits=5, shuffle=True, random_state=1412)validation_loss = cross_validate(reg, X, y,scoring='neg_mean_squared_error',cv=cv,verbose=True,n_jobs=-1,error_score='raise')return np.mean(validation_loss['test_score'])# 定义优化目标函数
def optimizer_optuna(n_trials):study = optuna.create_study(sampler=optuna.samplers.TPESampler(n_startup_trials=20, n_ei_candidates=30),direction='maximize')study.optimize(optuna_objective, n_trials=n_trials, show_progress_bar=True)print('随机森林最优参数:\nbest_params:', study.best_trial.params,'随机森林最优得分:\nbest_score:', study.best_trial.values,'\n')return study.best_trial.params, study.best_trial.valuesimport warnings
warnings.filterwarnings('ignore',message='The objective has been evaluated at this point before trails')
optuna.logging.set_verbosity(optuna.logging.ERROR)
best_params, best_score = optimizer_optuna(100)# 保存最优参数和最优得分到文件
with open(r'D:\2暂存文件\Sth with Py\重要性程度分析\随机森林贝叶斯优化结果.txt', 'w') as f:for key, value in best_params.items():f.write(f'{key}: {value}\n')f.write(f'Best Score: {best_score}\n')'''贝叶斯决策树寻优'''
# 定义目标函数和参数空间
def optuna_objective(trial):# 定义参数空间max_depth = trial.suggest_int('max_depth', 10, 30, 1)min_samples_split = trial.suggest_int('min_samples_split',10,30,1)min_samples_leaf = trial.suggest_int('min_samples_leaf',10,30,1)max_features = trial.suggest_int('max_features', 10, 30, 1)# 定义评估器dtr = DecisionTreeRegressor(max_depth=max_depth,max_features=max_features,min_samples_split=min_samples_split,min_samples_leaf=min_samples_leaf,random_state=1412,)# 定义交叉过程,输出负均方误差cv = KFold(n_splits=5, shuffle=True, random_state=1412)validation_loss = cross_validate(dtr, X, y,scoring='neg_mean_squared_error',cv=cv,verbose=True,n_jobs=-1,error_score='raise')return np.mean(validation_loss['test_score'])# 定义优化目标函数
def optimizer_optuna(n_trials):study = optuna.create_study(sampler=optuna.samplers.TPESampler(n_startup_trials=20, n_ei_candidates=30),direction='maximize')study.optimize(optuna_objective, n_trials=n_trials, show_progress_bar=True)print('决策树最优参数:\nbest_params:', study.best_trial.params,'决策树最优得分:\nbest_score:', study.best_trial.values,'\n')return study.best_trial.params, study.best_trial.valuesimport warnings
warnings.filterwarnings('ignore',message='The objective has been evaluated at this point before trails')
optuna.logging.set_verbosity(optuna.logging.ERROR)
best_params, best_score = optimizer_optuna(100)# 保存最优参数和最优得分到文件
with open(r'D:\2暂存文件\Sth with Py\重要性程度分析\决策树贝叶斯优化结果.txt', 'w') as f:for key, value in best_params.items():f.write(f'{key}: {value}\n')f.write(f'Best Score: {best_score}\n')'''贝叶斯梯度提升树寻优'''# 定义目标函数和参数空间
def optuna_objective(trial):# 定义参数空间max_depth = trial.suggest_int('max_depth', 3, 10)learning_rate = trial.suggest_float('learning_rate', 0.001, 0.1, log=True)n_estimators = trial.suggest_int('n_estimators', 50, 200)subsample = trial.suggest_float('subsample', 0.5, 1.0)# 定义评估器gbr = GradientBoostingRegressor(max_depth=max_depth,learning_rate=learning_rate,n_estimators=n_estimators,subsample=subsample,random_state=1412, )# 定义交叉过程,输出负均方误差cv = KFold(n_splits=5, shuffle=True, random_state=1412)validation_loss = cross_validate(gbr, X, y,scoring='neg_mean_squared_error',cv=cv,verbose=True,n_jobs=-1,error_score='raise')return np.mean(validation_loss['test_score'])# 定义优化目标函数
def optimizer_optuna(n_trials):study = optuna.create_study(sampler=optuna.samplers.TPESampler(n_startup_trials=20, n_ei_candidates=30),direction='maximize')study.optimize(optuna_objective, n_trials=n_trials, show_progress_bar=True)print('梯度提升树最优参数:\nbest_params:', study.best_trial.params,'梯度提升树最优得分:\nbest_score:', study.best_trial.value, '\n')return study.best_trial.params, study.best_trial.valueimport warningswarnings.filterwarnings('ignore', message='The objective has been evaluated at this point before trails')
optuna.logging.set_verbosity(optuna.logging.ERROR)
best_params, best_score = optimizer_optuna(100)# 保存最优参数和最优得分到文件
with open(r'D:\2暂存文件\Sth with Py\重要性程度分析\梯度提升树贝叶斯优化结果.txt', 'w') as f:for key, value in best_params.items():f.write(f'{key}: {value}\n')f.write(f'Best Score: {best_score}\n')# 结束计时
end_time = time.time()# 输出执行时间
execution_time = end_time - start_time
print("模型训练执行时间: {:.2f}秒".format(execution_time))

决策树模型最优参数及最佳得分如下:

max_depth: 11、min_samples_split: 18、min_samples_leaf: 13、max_features: 12
Best Score: -0.24607607821335736

随机森林模型最优参数及最佳得分如下:

n_estimators: 30、max_depth: 19、max_features: 24
Best Score: -0.18016603147647478

梯度提升树模型最优参数及最佳得分如下:

max_depth: 9、learning_rate: 0.0418665547136736、n_estimators: 188、subsample: 0.676537978032126
Best Score: -0.16401985559476492


树模型

        树模型,例如决策树和随机森林,能够通过对数据的划分建立一棵树形结构。它可以考虑不仅是线性关系,还包括非线性和交互作用。树模型不仅能够判断特征的重要性,还能够提供每个特征对目标变量的具体影响程度。通过这种方式,我们可以更好地理解和解释特征的重要性。另外,树模型还能够处理缺失值和离群点,使得分析结果更加鲁棒。此外,树模型还可以处理各种类型的特征,包括连续型、分类型以及文本型特征,具有很强的适应性。

        其中源码和绘图结果如下:

import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import GradientBoostingRegressor
import matplotlib.pyplot as plt
import time
plt.rcParams['font.sans-serif']=['SimHei'] # 把中文字体改成国际黑体
plt.rcParams['axes.unicode_minus'] = False # 显示负号
start_time = time.time()# 读取数据
data = pd.read_csv(r'D:\2暂存文件\Sth with Py\重要性程度分析\data.csv')
X = data.iloc[0:5000,[0, 1, 2, 3, 4, 5, 6, 7]]
y = data.iloc[0:5000,8]'''决策树'''
model_dtr = DecisionTreeRegressor(max_depth=11,min_samples_split=18,min_samples_leaf=13,max_features=12)
model_dtr.fit(X, y)
importances_dtr = model_dtr.feature_importances_'''随机森林'''
model_rfr = RandomForestRegressor(n_estimators=30,max_depth=19,max_features=24)
model_rfr.fit(X, y)
importances_rfr = model_rfr.feature_importances_'''梯度提升树'''
model_gbr = GradientBoostingRegressor(max_depth=9,learning_rate=0.0418665547136736,n_estimators=188,subsample=0.676537978032126)
model_gbr.fit(X, y)
importances_gbr = model_gbr.feature_importances_# 创建特征名称列表
feature_names = ['MedInc','HouseAge','AveRooms','AveBedrms','Population','AveOccup','Latitude','Longitude']# 将特征名称和重要性值进行配对
feature_importances_dtr = list(zip(feature_names, importances_dtr))
print('决策树特征重要性:',feature_importances_dtr)
feature_importances_rfr = list(zip(feature_names, importances_rfr))
print('\n随机森林特征重要性:',feature_importances_rfr)
feature_importances_gbr = list(zip(feature_names, importances_gbr))
print('\n梯度提升树特征重要性:',feature_importances_gbr)'''绘图'''
tree = pd.read_excel(r'D:\2暂存文件\Sth with Py\重要性程度分析\树模型重要性.xlsx')
labels=["特征","Decision trees","Random Forest","GBDT","Average"]# 把dataframe转换为list
x = tree['特征'].values.tolist()
y1 = tree['Decision trees'].values.tolist()
y2 = tree['Random Forest'].values.tolist()
y3 = tree['GBDT'].values.tolist()
y4 = tree['Average'].values.tolist()plt.bar(x=np.arange(len(x))-0.2,height=y1,label="Decision trees",color="#AADCE0",width=0.1)
plt.bar(x=np.arange(len(x))-0.1,height=y2,label="Random Forest",color="#FFD06F",width=0.1)
plt.bar(x=x,height=y3,label="GBDT",color="#FFE6B7",width=0.1)
plt.bar(x=np.arange(len(x))+0.1,height=y4,label="Average",color="#E76254",width=0.1)plt.legend(loc="upper right")
plt.xticks(x)
轴=plt.gca()
轴.set_xticklabels(x,rotation=45,ha="center")
图形=plt.gcf()
plt.xlabel('Feature',fontsize=15)
plt.ylabel('Importance',fontsize=15)
plt.title('Feature Importance',fontsize=18)
图形.subplots_adjust(left=0.1,bottom=0.3)
plt.savefig(r'D:\2暂存文件\Sth with Py\重要性程度分析\树模型重要性.png',dpi=600)
# 输出执行时间
end_time = time.time()
execution_time = end_time - start_time
print("模型训练执行时间: {:.2f}秒".format(execution_time))
plt.show()
0f72ad78b27b4895ac4f2c83718ef77f.png

树模型重要性分析图


SHAP值法

        SHAP值法采用了一种更为细致的方法来解释特征重要性。它通过计算每个特征对模型预测结果的贡献程度,从而揭示出特征之间的相互作用和非线性关系。这使得我们能够更全面地了解特征对目标的影响,而不仅仅局限于线性关系的分析。本文使用随机森林回归模型,其中数据使用归一化后的数据。代码和摘要图、特征重要性图如下:

import pandas as pd
import shap
from sklearn.preprocessing import MinMaxScaler
from sklearn.ensemble import RandomForestRegressor
import matplotlib.pyplot as plt
import time
plt.rcParams['font.sans-serif']=['SimHei'] # 把中文字体改成国际黑体
plt.rcParams['axes.unicode_minus'] = False # 显示负号# 读取数据
normalized_data = pd.read_excel(r'D:\2暂存文件\Sth with Py\重要性程度分析\归一化数据.xlsx')
X = normalized_data.iloc[:,[0, 1, 2, 3, 4, 5, 6, 7]]
y = normalized_data.iloc[:,8]start_time = time.time()# 初始化随机森林模型
model = RandomForestRegressor(n_estimators=30,max_depth=19,max_features=24)# 训练模型
model.fit(X, y)# 创建一个Explainer对象
explainer = shap.Explainer(model)# 计算SHAP值
shap_values = explainer.shap_values(X)# 结束计时
end_time = time.time()# 输出执行时间
execution_time = end_time - start_time
print("模型训练执行时间: {:.2f}秒".format(execution_time))# 打印特征重要性得分
shap.summary_plot(shap_values, X)# 打印每个特征的重要性图
shap.summary_plot(shap_values, X, plot_type="bar")
a27c7ab21c2145f5a1881b188d74049b.png

SHAP值摘要图

1f62ce3cf6c54131a4479dde6ac7a8a5.png

SHAP值特征重要性图

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

虹科产线实时数采检测方案——高速采集助力智能化升级

01 产线数采检测相关技术背景 1.1 典型场景 对于产线数采检测,让我们从典型的工厂场景开始介绍。 每个工位都有上位机监控下方的PLC控制器。指令、执行单元和作用对象的状态通过内置传感器进行采集和测量,反馈给PLC实现闭环控制。 工业4.0和智能制…

输出归一化位置式PID(COTRUST完整梯形图代码)

SMART PLC单自由度和双自由度位置式PID的完整源代码,请参看下面文章链接: 位置式PID(S7-200SMART 单自由度、双自由度梯形图源代码)_RXXW_Dor的博客-CSDN博客有关位置型PID和增量型PID的更多详细介绍请参看PID专栏的相关文章,链接如下:SMART PLC增量型PID算法和梯形图代码…

pdf怎么转换成word?

随着数字化时代的到来,PDF(Portable Document Format)已成为最受欢迎的文档格式之一,因其在各种设备上的可视性和稳定性而备受推崇。然而在某些情况下,将PDF转换为Word文档可能是必要的,这使得编辑、修改和重新格式化文本变得更加…

freemarker学习+集成springboot+导出word

目录 一 FreeMarker简介 二 集成springboot,实现案例导出 三 常见面试题总结 一 FreeMarker简介 FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件&…

【Sword系列】Vulnhub靶机HACKADEMIC: RTB1 writeup

靶机介绍 官方下载地址:https://www.vulnhub.com/entry/hackademic-rtb1,17/ 需要读取靶机的root目录下key.txt 运行环境: 虚拟机网络设置的是NAT模式 靶机:IP地址:192.168.233.131 攻击机:kali linux,IP地…

开发一个npm包

1 注册一个npm账号 npm https://www.npmjs.com/ 2 初始化一个npm 项目 npm init -y3编写一段代码 function fn(){return 12 }exports.hellofn;4发布到全局node_module npm install . -g5测试代码 创建一个text文件 npm link heath_apisnode index.js6登录(我默认的 https…

系统中出现大量不可中断进程和僵尸进程(理论)

一 进程状态 当 iowait 升高时,进程很可能因为得不到硬件的响应,而长时间处于不可中断状态。从 ps 或者 top 命令的输出中,你可以发现它们都处于 D 状态,也就是不可中断状态(Uninterruptible Sleep)。 R …

开源django+mysql+vue3前后端分离商城baykeShop使用指南

baykeShop开源商城系统 项目简介 baykeShop(拜客商城系统)是一款全开源Python栈商城系统,管理后台完全前后端分离重写以适配项目,前后端100%开源,后台前端采用开源SCUI开源库对接开发,美观、易用、符合当…

C++算法 —— 动态规划(1)斐波那契数列模型

文章目录 1、动规思路简介2、第N个泰波那契数列3、三步问题4、使用最小花费爬楼梯5、解码方法6、动规分析总结 1、动规思路简介 动规的思路有五个步骤,且最好画图来理解细节,不要怕麻烦。当你开始画图,仔细阅读题时,学习中的沉浸…

uni-app之android离线打包

一 AndroidStudio创建项目 1.1,上一节演示了uni-app云打包,下面演示怎样androidStudio离线打包。在AndroidStudio里面新建空项目 1.2,下载uni-app离线SDK,离线SDK主要用于App本地离线打包及扩展原生能力,SDK下载链接h…

k8s使用ECK(2.4)形式部署elasticsearch+kibana-http协议

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、准备elasticsearch-cluster.yaml二、部署并测试总结 前言 之前写了eck2.4部署eskibana,默认的话是https协议的,这里写一个使用http…

开源照片管理服务LibrePhotos

本文是为了解决网友 赵云遇到的问题,顺便折腾的。虽然软件跑起来了,但是他遇到的问题,超出了老苏的认知。当然最终问题还是得到了解决,不过与 LibrePhotos 无关; 什么是 LibrePhotos ? LibrePhotos 是一个自托管的开源…

微服务设计和高并发实践

文章目录 1、微服务的设计原则1.1、服务拆分方法1.2、微服务的设计原则1.3、微服务架构 2、高并发系统的一些优化经验2.1、提高性能2.1.1、数据库优化2.1.2、使用缓存2.1.3、服务调用优化2.1.4、动静分离2.1.5、数据库读写分离 2.2、服务高可用2.2.1、限流和服务降级2.2.2、隔离…

美团 Flink 资源调度优化实践

摘要:本文整理自美团数据平台计算引擎组工程师冯斐,在 Flink Forward Asia 2022 生产实践专场的分享。本篇内容主要分为四个部分: 相关背景和问题解决思路分析资源调度优化实践后续规划 点击查看原文视频 & 演讲PPT 一、相关背景和问题 在…

企业数字化转型的关键技术有哪些?_光点科技

随着科技的不断进步和信息技术的快速发展,企业数字化转型已经成为保持竞争力和适应市场变化的关键举措。在这个数字化时代,企业需要借助先进的技术来优化业务流程、提升效率,以及更好地满足客户需求。以下是企业数字化转型过程中的关键技术。…

list根据对象中某个字段属性去重Java流实现

list根据对象中某个字段属性去重Java流实现? 在Java的流(Stream)中,你可以使用distinct方法来实现根据对象中某个字段属性去重的功能。要实现这个功能,你需要重写对象的hashCode和equals方法,以确保相同字段属性的对象被认为是相…

因为axios请求后端,接收不到token的问引出的问题

vue axios请求后端接受不到token的问题。 相关概念 什么是跨域? 跨域指的是在浏览器环境下,当发起请求的域(或者网站)与请求的资源所在的域之间存在协议、主机或端口中的任何一个条件不同的情况。换句话说,只要协议、…

服务器数据恢复- Ext4文件系统分区挂载报错的数据恢复案例

Ext4文件系统相关概念: 块组:Ext4文件系统的空间被划分为若干个块组,每个块组内的结构大致相同。 块组描述符表:每个块组都对应一个块组描述符,这些块组描述符统一放在文件系统的前部,称为块组描述符表。每…

ssm+vue在线购书商城系统源码和论文

ssmvue在线购书商城系统源码和论文119 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 摘 要 本课题是根据用户的需要以及网络的优势建立的一个在线购书商城系统,来满足用户网络查看、购买所需图书…

设计模式-9--迭代器模式(Iterator Pattern)

一、什么是迭代器模式 迭代器模式(Iterator Pattern)是一种行为型设计模式,用于提供一种统一的方式来访问一个聚合对象中的各个元素,而不需要暴露该聚合对象的内部结构。迭代器模式将遍历集合的责任从集合对象中分离出来&#xf…