【解决方案】成功解决将XGBoost中plot_importance绘图时出现的f0、f1、f2、f3、f4、f5等改为对应特征的字段名

本文主要是介绍【解决方案】成功解决将XGBoost中plot_importance绘图时出现的f0、f1、f2、f3、f4、f5等改为对应特征的字段名,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.问题描述

使用XGBoost中的plot_importance绘制特征重要性图时,纵坐标并不是特征名,而是f0、f1、f2、f3、f4、f5…fn等一系列符号。

2.问题结果

成功解决将XGBoost中plot_importance绘图时出现的f0、f1、f2、f3、f4、f5等改为对应特征的字段名。

3.解决方案

3.1 项目描述

使用XGBoost模型训练sklearn中的乳腺癌数据(二分类,这篇文章中,介绍过此数据集:【ML】机器学习数据集:sklearn中分类数据集介绍),对训练后的模型中的特征重要性进行排序,即可视化模型中的特征重要性。

3.2 项目初始代码

# -*- coding: utf-8 -*-
"""
Created on Thu Sep 29 13:47:06 2022@author: augustqi
"""# 导入需要的包
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score, accuracy_score, auc, recall_score, precision_score, f1_score
from sklearn.metrics import roc_curve, precision_recall_curve, average_precision_score
from xgboost import XGBClassifier
from xgboost import plot_importance# 加载数据集,这里直接使用datasets包里面的乳腺癌分类数据(二分类)
cancer = datasets.load_breast_cancer()X = cancer.data
y = cancer.target# 输出数据集的形状,该数据集里面有569个样本,每个样本有30个特征(569, 30)
print(X.shape)
# 输出标签的个数为 569
print(y.shape)# 使用train_test_split()函数对训练集和测试集进行划分,第一个参数是数据集特征,第二个参数是标签,第三个为测试集占总样本的百分比
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 6)# 使用XGBoost进行训练
model = XGBClassifier()
model.fit(x_train,y_train)# 绘制重要性曲线, max_num_feature参数设置输出前30重要的特征,【数据集中共有30个特征】
fig, ax = plt.subplots(figsize=(10,8))
plot_importance(model, max_num_features=30, ax=ax)
plt.savefig("demo_plot_importance.png", dpi=600)
plt.show()# 类别值
y_pred = model.predict(x_test)# 输出ACC的值
acc = accuracy_score(y_test, y_pred)
print("acc:", acc)
# 输出recall值
re = recall_score(y_test, y_pred)
print("recall:", re)
# 输出precision
pre = precision_score(y_test, y_pred)
print("precision:", pre)
# 输出f1 score
f1 = f1_score(y_test, y_pred)
print("f1 score:", f1)# 概率得分
y_score = model.predict_proba(x_test)[:,1]# 直接计算auc的值
auc_1 = roc_auc_score(y_test, y_score)
print("auc_1:", auc_1)# 绘制ROC曲线
fpr, tpr, thresholds_roc = roc_curve(y_test, y_score)
# 间接计算auc的值
auc_2 = auc(fpr, tpr) 
print("auc_2:", auc_2)# 间接计算auc的值的好处,就是可以知道fpr和tpr,绘制曲线
plt.plot(fpr,tpr,'r--', label='auc=%0.4f'%auc_2)
plt.title("ROC Curve")
plt.legend()
plt.savefig("demo_roc.png",dpi=600)
plt.show()# 绘制PR曲线
precision, recall, thresholds_pr = precision_recall_curve(y_test, y_score)
aupr = auc(recall, precision)
print("aupr:", aupr)
plt.plot(recall, precision, 'g--', label='aupr=%0.4f'%aupr)
plt.title("PR Curve")
plt.legend()
plt.savefig("demo_pr.png",dpi=600)
plt.show()

测试集上的一些统计指标:

在这里插入图片描述

ROC曲线:
在这里插入图片描述
PR曲线:

在这里插入图片描述
特征重要性图:

在这里插入图片描述

我们主要看特征重要性图(其他图和统计指标,是我附带送给各位的,不是本文的重点,嘿嘿),输入到XGBoost模型训练的数据共有30维,即30个特征,哪这30个特征分别对模型的影响是多少呢?请往下看。

随着科学技术的发展,机器学习这个黑盒子也在被慢慢打开,XGBoost中提供了一个plot_importance函数用于绘制特征的重要性。从特征重要性图可以看到f0、f1、f2、f3…f29,这些符号对应数据集中的30个特征,但是我们如何将纵坐标的这些符号换成对应的特征名呢?从而可以更直观看到特征的重要性。

我们只需在初始的项目代码中加入:

feature_names = cancer.feature_names
feature_names = list(feature_names)model.get_booster().feature_names = feature_names

然后绘制具有特征名的特征重要性图:

在这里插入图片描述
大功告成,f0、f1、f2、f3…f29成功和数据集中的特征名对应起来了,可以看到worst texture(f21)特征对模型的影响最大。

3.3 项目最终代码

# -*- coding: utf-8 -*-
"""
Created on Thu Sep 29 13:47:06 2022@author: augustqi
"""# 导入需要的包
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score, accuracy_score, auc, recall_score, precision_score, f1_score
from sklearn.metrics import roc_curve, precision_recall_curve, average_precision_score
from xgboost import XGBClassifier
from xgboost import plot_importance# 加载数据集,这里直接使用datasets包里面的乳腺癌分类数据(二分类)
cancer = datasets.load_breast_cancer()X = cancer.data
y = cancer.target
feature_names = cancer.feature_names
feature_names = list(feature_names)# 输出数据集的形状,该数据集里面有569个样本,每个样本有30个特征(569, 30)
print(X.shape)
# 输出标签的个数为 569
print(y.shape)# 使用train_test_split()函数对训练集和测试集进行划分,第一个参数是数据集特征,第二个参数是标签,第三个为测试集占总样本的百分比
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 6)# 使用XGBoost进行训练
model = XGBClassifier()
model.fit(x_train,y_train)model.get_booster().feature_names = feature_names# 绘制重要性曲线, max_num_feature参数设置输出前30重要的特征,【数据集中共有30个特征】
fig, ax = plt.subplots(figsize=(16,10))
plot_importance(model, max_num_features=30, ax=ax)
plt.savefig("demo_plot_importance.png", dpi=600)
plt.show()# 类别值
y_pred = model.predict(x_test)# 输出ACC的值
acc = accuracy_score(y_test, y_pred)
print("acc:", acc)
# 输出recall值
re = recall_score(y_test, y_pred)
print("recall:", re)
# 输出precision
pre = precision_score(y_test, y_pred)
print("precision:", pre)
# 输出f1 score
f1 = f1_score(y_test, y_pred)
print("f1 score:", f1)# 概率得分
y_score = model.predict_proba(x_test)[:,1]# 直接计算auc的值
auc_1 = roc_auc_score(y_test, y_score)
print("auc_1:", auc_1)# 绘制ROC曲线
fpr, tpr, thresholds_roc = roc_curve(y_test, y_score)
# 间接计算auc的值
auc_2 = auc(fpr, tpr) 
print("auc_2:", auc_2)# 间接计算auc的值的好处,就是可以知道fpr和tpr,绘制曲线
plt.plot(fpr,tpr,'r--', label='auc=%0.4f'%auc_2)
plt.title("ROC Curve")
plt.legend()
plt.savefig("demo_roc.png",dpi=600)
plt.show()# 绘制PR曲线
precision, recall, thresholds_pr = precision_recall_curve(y_test, y_score)
aupr = auc(recall, precision)
print("aupr:", aupr)
plt.plot(recall, precision, 'g--', label='aupr=%0.4f'%aupr)
plt.title("PR Curve")
plt.legend()
plt.savefig("demo_pr.png",dpi=600)
plt.show()

本篇博文,首发在AIexplore微信公众号,内容总体相同,均为原创,特此申明。

参考资料

[1] https://www.cnblogs.com/hellojiaojiao/p/10755878.html
[2] https://zhuanlan.zhihu.com/p/361214293
[3] https://www.lmlphp.com/user/16834/article/item/504015/
[4] https://stackoverflow.com/questions/46943314/xgboost-plot-importance-doesnt-show-feature-names

这篇关于【解决方案】成功解决将XGBoost中plot_importance绘图时出现的f0、f1、f2、f3、f4、f5等改为对应特征的字段名的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/247705

相关文章

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

C#文件复制异常:"未能找到文件"的解决方案与预防措施

《C#文件复制异常:未能找到文件的解决方案与预防措施》在C#开发中,文件操作是基础中的基础,但有时最基础的File.Copy()方法也会抛出令人困惑的异常,当targetFilePath设置为D:2... 目录一个看似简单的文件操作问题问题重现与错误分析错误代码示例错误信息根本原因分析全面解决方案1. 确保

504 Gateway Timeout网关超时的根源及完美解决方法

《504GatewayTimeout网关超时的根源及完美解决方法》在日常开发和运维过程中,504GatewayTimeout错误是常见的网络问题之一,尤其是在使用反向代理(如Nginx)或... 目录引言为什么会出现 504 错误?1. 探索 504 Gateway Timeout 错误的根源 1.1 后端

解决升级JDK报错:module java.base does not“opens java.lang.reflect“to unnamed module问题

《解决升级JDK报错:modulejava.basedoesnot“opensjava.lang.reflect“tounnamedmodule问题》SpringBoot启动错误源于Jav... 目录问题描述原因分析解决方案总结问题描述启动sprintboot时报以下错误原因分析编程异js常是由Ja

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

MySQL 表空却 ibd 文件过大的问题及解决方法

《MySQL表空却ibd文件过大的问题及解决方法》本文给大家介绍MySQL表空却ibd文件过大的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录一、问题背景:表空却 “吃满” 磁盘的怪事二、问题复现:一步步编程还原异常场景1. 准备测试源表与数据