XGBoost feature importance特征重要性-实战印第安人糖尿病数据集

使用梯度提升之类的决策树方法集成的一个好处是,它们可以从训练有素的预测模型中自动提供特征重要性的估计。

在这篇文章中,您将了解如何使用 Python 中的 XGBoost 库估计特征对预测建模问题的重要性。

看完这篇文章你会知道:

  • 如何使用梯度提升算法计算特征重要性。

  • 如何在 Python 中绘制 XGBoost 模型计算的特征重要性。

  • 如何使用 XGBoost 计算的特征重要性进行特征选择。


梯度提升中的特征重要性

使用梯度提升的一个好处是,在构建提升树之后,检索每个属性的重要性分数相对简单。

通常,重要性提供一个分数,表明每个特征在构建模型内的增强决策树中的有用性或价值。使用决策树做出关键决策的属性越多,其相对重要性就越高。

为数据集中的每个属性明确计算此重要性,允许对属性进行排名和相互比较。

单个决策树的重要性是通过每个属性分割点改进性能度量的量计算的,由节点负责的观察数加权。性能度量可以是用于选择分割点的纯度(基尼指数)或另一个更具体的误差函数。

然后对模型内所有决策树的特征重要性进行平均。

手动绘制特征重要性

经过训练的 XGBoost 模型会自动计算预测建模问题的特征重要性。

这些重要性分数在训练模型的feature_importances_成员变量中可用。例如,它们可以直接输出如下:

print(model.feature_importances_)

我们可以直接在条形图上绘制这些分数,以直观地表示数据集中每个特征的相对重要性。例如:

# plot
pyplot.bar(range(len(model.feature_importances_)), model.feature_importances_)
pyplot.show()

我们可以通过在皮马印第安人糖尿病数据集上训练 XGBoost 模型并根据计算出的特征重要性创建条形图来证明这一点。

下载数据集链接:

https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.csv

数据说明

1. 标题:皮马印第安人糖尿病数据库2. 来源:   (a) 原所有者:国立糖尿病与消化研究所                        肾脏疾病   (b) 数据库捐赠者:Vincent Sigillito ([email protected])                          研究中心,RMI 组长                          应用物理实验室                          约翰霍普金斯大学                          约翰霍普金斯路                          劳雷尔,医学博士 20707                          (301) 953-6231   (c) 收到日期:1990 年 5 月 9 日3. 过去的用法:    1. 史密斯,~J.~W.,埃弗哈特,~J.~E.,迪克森,~W.~C.,诺勒,~W.~C.,\&       约翰内斯,~R.~S. (1988)。使用 ADAP 学习算法进行预测       糖尿病的发作。在 {\it Proceedings of the Symposium       关于计算机应用和医疗保健}(第 261--265 页)。IEEE       计算机学会出版社。       所调查的诊断性二进制值变量是       世界卫生组织称患者有糖尿病迹象       标准(即,如果负荷后 2 小时血糖至少为        200 mg/dl 在任何调查检查中或如果在常规医疗中发现       护理)。人口居住在美国亚利桑那州凤凰城附近。       结果:他们的 ADAP 算法在       0 和 1。这被转换为使用截止值的二元决策        0.448。使用 576 个训练实例,敏感性和特异性       他们算法的 76% 在其余 192 个实例上。四、相关资料:      对这些实例的选择施加了一些限制      更大的数据库。特别是这里的所有患者都是女性      至少 21 岁的皮马印第安人血统。ADAP是一种自适应学习      生成和执行类似感知器的数字模拟的例程      设备。它是一种独特的算法;有关详细信息,请参阅论文。5. 实例数:7686.属性数:8+类 7. For Each Attribute: (都是数值型)   1.怀孕次数   2. 口服葡萄糖耐量试验中 2 小时的血浆葡萄糖浓度   3. 舒张压(毫米汞柱)   4. 三头肌皮褶厚度(mm)   5. 2 小时血清胰岛素(μ U/ml)   6. 体重指数(体重kg/(身高m)^2)   7.糖尿病谱系功能   8. 年龄(岁)   9. 类变量(0 或 1)8. 缺少属性值:是9. 类分布:(类值 1 被解释为“测试为阳性”   糖尿病”)   类值实例数   0 500   1 26810.简要统计分析:    属性编号:平均值:标准差:    1. 3.8 3.4    2. 120.9 32.0    3. 69.1 19.4    4. 20.5 16.0    5. 79.8 115.2    6. 32.0 7.9    7. 0.5 0.3    8. 33.2 11.8
# plot feature importance manually
from numpy import loadtxt
from xgboost import XGBClassifier
from matplotlib import pyplot
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
y = dataset[:,8]
# fit model no training data
model = XGBClassifier()
model.fit(X, y)
# feature importance
print(model.feature_importances_)
# plot
pyplot.bar(range(len(model.feature_importances_)), model.feature_importances_)
pyplot.show()

注意:程序运行的结果可能会因算法或评估程序的随机性或数值精度的差异而有所不同。考虑多次运行该示例并比较平均结果。

运行此示例首先输出重要性分数。

[ 0.089701    0.17109634  0.08139535  0.04651163  0.10465116  0.2026578 0.1627907   0.14119601]

我们还得到了一个相对重要性的条形图。

XGBoost feature importance特征重要性-实战印第安人糖尿病数据集_第1张图片

这个图的一个缺点是特征是按输入索引而不是重要性排序的。我们可以在绘图之前对特征进行排序。

值得庆幸的是,有一个内置的绘图功能可以帮助我们。

使用内置的 XGBoost 特征重要性图

XGBoost 库提供了一个内置函数来绘制按重要性排序的特征。

该函数称为plot_importance()并且可以按如下方式使用:

# plot feature importance
plot_importance(model)
pyplot.show()

例如,下面是一个完整的代码清单,它使用内置的plot_importance()函数绘制了皮马印第安人数据集的特征重要性。

# plot feature importance using built-in function
from numpy import loadtxt
from xgboost import XGBClassifier
from xgboost import plot_importance
from matplotlib import pyplot
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
y = dataset[:,8]
# fit model no training data
model = XGBClassifier()
model.fit(X, y)
# plot feature importance
plot_importance(model)
pyplot.show()

注意:程序的结果可能会因算法或评估程序的随机性或数值精度的差异而有所不同。考虑多次运行该示例并比较平均结果。

运行该示例为我们提供了一个更有用的条形图。

XGBoost feature importance特征重要性-实战印第安人糖尿病数据集_第2张图片

您可以看到,要素是根据它们在输入数组 (X) 中的索引(从 F0 到 F7)自动命名的。

手动将这些指数映射到问题描述中的名称,我们可以看到图中显示 F5(体重指数)的重要性最高,而 F3(皮褶厚度)的重要性最低。

使用 XGBoost 特征重要性评分的特征选择

特征重要性分数可用于 scikit-learn 中的特征选择。

这是使用SelectFromModel类完成的,该类采用模型并将数据集转换为具有选定特征的子集。

此类可以采用预先训练的模型,例如在整个训练数据集上训练的模型。然后它可以使用阈值来决定选择哪些特征。当您在SelectFromModel实例上调用transform()方法以一致地选择训练数据集和测试数据集上的相同特征时,将使用此阈值。

在下面的示例中,我们首先训练,然后分别在整个训练数据集和测试数据集上评估 XGBoost 模型。

使用从训练数据集计算出的特征重要性,然后我们将模型包装在 SelectFromModel 实例中。我们使用它来选择训练数据集上的特征,从选定的特征子集中训练模型,然后在测试集上评估模型,遵循相同的特征选择方案。

例如:

# select features using threshold
selection = SelectFromModel(model, threshold=thresh, prefit=True)
select_X_train = selection.transform(X_train)
# train model
selection_model = XGBClassifier()
selection_model.fit(select_X_train, y_train)
# eval model
select_X_test = selection.transform(X_test)
y_pred = selection_model.predict(select_X_test)

出于兴趣,我们可以测试多个阈值以通过特征重要性选择特征。具体来说,每个输入变量的特征重要性,本质上允许我们按重要性测试每个特征子集,从所有特征开始,以具有最重要特征的子集结束。

下面提供了完整的代码清单。

# use feature importance for feature selection
from numpy import loadtxt
from numpy import sort
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.feature_selection import SelectFromModel
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
Y = dataset[:,8]
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=7)
# fit model on all training data
model = XGBClassifier()
model.fit(X_train, y_train)
# make predictions for test data and evaluate
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
# Fit model using each importance as a threshold
thresholds = sort(model.feature_importances_)
for thresh in thresholds:

  # select features using threshold
  selection = SelectFromModel(model, threshold=thresh, prefit=True)
  select_X_train = selection.transform(X_train)
  # train model
  selection_model = XGBClassifier()
  selection_model.fit(select_X_train, y_train)
  # eval model
  select_X_test = selection.transform(X_test)
  y_pred = selection_model.predict(select_X_test)
  predictions = [round(value) for value in y_pred]
  accuracy = accuracy_score(y_test, predictions)
  print("Thresh=%.3f, n=%d, Accuracy: %.2f%%" % (thresh, select_X_train.shape[1], accuracy*100.0))

请注意,如果您使用的是 XGBoost 1.0.2(可能还有其他版本),则 XGBClassifier 类中存在导致错误的错误:

KeyError: 'weight'

这可以通过使用自定义_XGBClassifier_类来修复,该类为_coef_属性返回_None

下面列出了完整的示例。

# use feature importance for feature selection, with fix for xgboost 1.0.2
from numpy import loadtxt
from numpy import sort
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.feature_selection import SelectFromModel
 
# define custom class to fix bug in xgboost 1.0.2
class MyXGBClassifier(XGBClassifier):
  @property
  def coef_(self):
    return None
 
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
Y = dataset[:,8]
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=7)
# fit model on all training data
model = MyXGBClassifier()
model.fit(X_train, y_train)
# make predictions for test data and evaluate
predictions = model.predict(X_test)
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
# Fit model using each importance as a threshold
thresholds = sort(model.feature_importances_)
for thresh in thresholds:
  # select features using threshold
  selection = SelectFromModel(model, threshold=thresh, prefit=True)
  select_X_train = selection.transform(X_train)
  # train model
  selection_model = XGBClassifier()
  selection_model.fit(select_X_train, y_train)
  # eval model
  select_X_test = selection.transform(X_test)
  predictions = selection_model.predict(select_X_test)
  accuracy = accuracy_score(y_test, predictions)
  print("Thresh=%.3f, n=%d, Accuracy: %.2f%%" % (thresh, select_X_train.shape[1], accuracy*100.0))

运行此示例将打印以下输出。

Accuracy: 77.95%
Thresh=0.071, n=8, Accuracy: 77.95%
Thresh=0.073, n=7, Accuracy: 76.38%
Thresh=0.084, n=6, Accuracy: 77.56%
Thresh=0.090, n=5, Accuracy: 76.38%
Thresh=0.128, n=4, Accuracy: 76.38%
Thresh=0.160, n=3, Accuracy: 74.80%
Thresh=0.186, n=2, Accuracy: 71.65%
Thresh=0.208, n=1, Accuracy: 63.78%

我们可以看到模型的性能通常随着所选特征的数量而下降。但有时候踢除一些噪音变量后,模型性能反而会提升。我建议模型仅保留有效变量,踢除无用变量。

在这个问题上,需要权衡特征与测试集的准确度,我们可以决定采用一个不太复杂的模型(更少的属性,例如 n=4),并接受估计准确度从 77.95% 下降到 76.38% 的适度下降。

这可能是对如此小的数据集的一种清洗,但对于更大的数据集并使用交叉验证作为模型评估方案可能是更有用的策略。

总结

在这篇博文中,您了解了如何在经过训练的 XGBoost 梯度提升模型中访问特征和使用重要性。

具体来说,你学到了:

  • 特征重要性是什么以及在 XGBoost 中通常是如何计算的。

  • 如何从 XGBoost 模型访问和绘制特征重要性分数。

  • 如何使用 XGBoost 模型中的特征重要性进行特征选择。


xgboost特征重要性就为大家讲解到这里,欢迎各位同学学习《python机器学习生物信息学 》学习更多相关知识
https://edu.csdn.net/combo/detail/1930

版权声明:文章来自公众号(python风控模型),未经许可,不得抄袭。遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

你可能感兴趣的:(python生物信息学,python,机器学习,糖尿病,xgboost,特征重要性)