【问题标题】:Adaboost Sklearn Feature Importance NaNAdaboost Sklearn 特征重要性 NaN
【发布时间】:2021-09-02 07:04:56
【问题描述】:

我正在使用 Sklearn 构建一个 Ada 提升模型。去年,我用相同的数据制作了相同的模型,并且能够访问特征重要性。今年,当我用相同的数据构建模型时,特征重要性属性包含 NaN。我读过一些其他的东西,人们有同样的问题,并且他们的数据中有 NaN,但我的没有。

我不知道有什么不同,但我已将 Base_estimator DecisionTree max_depth 隔离为问题所在。 max_depth 越高,NaN 的数量就越多。但是我已经确定 max_depth=10 最适合我的工作。这是我的代码

谁能指出我哪里出错了?或者解释正在发生的事情或获得 feature_importance 的其他方式?

我用下面的 sklearn 数据集重新创建了相同的错误。

我有一个带有 python 2.7 的旧版本的 sklearn,并且使用相同的数据不会发生此错误。

谢谢

我正在使用的数据可在此处获得:https://github.com/scikit-learn/scikit-learn/discussions/20315

import pandas
import xarray
import numpy as np
from sklearn.tree import DecisionTreeClassifier 
from sklearn.ensemble import AdaBoostClassifier

 
train_data=pandas.read_csv('data_train.csv')
model_variables=['RH','t2m','tp_r5','swvl1','SM_r20','tp','cvh','vdi','SM_r10','SM_IDW']

X = train_data[model_variables] # Features
y = train_data.ignition_no 

np.count_nonzero(np.isnan(y))
0
#no missing target variables

tree = DecisionTreeClassifier(max_depth=10, random_state=12)
ada_model= AdaBoostClassifier(base_estimator = tree, random_state=12)
model= ada_model.fit(X,y)
model.feature_importances_
/home/mo/morc/.virtualenvs/newroo/lib/python3.6/site-packages/sklearn/tree/_classes.py:605: RuntimeWarning: invalid value encountered in true_divide
  return self.tree_.compute_feature_importances()
array([       nan,        nan,        nan,        nan,        nan,
              nan,        nan, 0.02568412,        nan,        nan])
>>> 

#Here is the same error recreated with the load_digits dataset from sklearn

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
 
from sklearn.metrics import accuracy_score
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import cross_val_predict
from sklearn.model_selection import train_test_split
from sklearn.model_selection import learning_curve
 
from sklearn.datasets import load_digits
>>> dataset = load_digits()
>>> X = dataset['data']
>>> y = dataset['target']
>>> 
>>> score = []
>>> for depth in [1,2,10] : 
...     reg_ada = AdaBoostClassifier(DecisionTreeClassifier(max_depth=depth))
...     scores_ada = cross_val_score(reg_ada, X, y, cv=6)
...     score.append(scores_ada.mean())
... 
score
>>>[0.2615310293571163, 0.6466908212560386, 0.9621609067261242]
#best depth is 10, so making ada_boost classifier with base_estimator of max_depth=10
reg_ada = AdaBoostClassifier(DecisionTreeClassifier(max_depth=10))
model=reg_ada.fit(X,y)
model.feature_importances_
/home/mo/morc/.virtualenvs/fox/lib/python3.6/site-packages/sklearn/tree/_classes.py:605: RuntimeWarning: invalid value encountered in true_divide
  return self.tree_.compute_feature_importances()
array([0.00000000e+00, 3.97071545e-03,            nan, 1.04739889e-02,
       1.71911851e-02, 1.13877668e-02, 5.53334918e-03, 3.48635371e-03,
       3.81562332e-16, 2.97882448e-04, 5.21107270e-03, 1.90482369e-03,
       9.54317398e-03,            nan, 4.04579846e-03, 2.85770367e-03,
       2.41466161e-03, 2.22172771e-04,            nan,            nan,
       2.64452796e-02, 2.35455672e-02, 5.91982800e-03, 9.63862404e-15,
       2.51667106e-05, 8.22347398e-03, 3.53522516e-02, 3.49199633e-02,
                  nan,            nan, 7.85924750e-03, 0.00000000e+00,
       0.00000000e+00, 2.43861329e-02,            nan, 4.52136284e-03,
       2.84309340e-02, 8.70846798e-03,            nan, 0.00000000e+00,
       0.00000000e+00, 8.51258472e-03,            nan, 4.08880381e-02,
       6.47568594e-03, 1.75046890e-02, 1.37183583e-02, 3.95955193e-32,
       0.00000000e+00, 6.36631892e-05, 2.06906508e-02,            nan,
                  nan,            nan, 9.47079562e-03, 3.71242630e-03,
       0.00000000e+00, 7.14153611e-06,            nan, 5.14482654e-03,
       2.23621689e-02, 1.79753787e-02, 3.05869803e-03, 4.80512718e-03])





【问题讨论】:

  • 一个可重现的例子会很棒:数据的一个子集,或者使用 sklearn 的内置数据集之一重新创建问题。还可以尝试将警告升级为错误,以便我们可以获取完整的错误回溯。
  • 但是,警告表明存在问题here;我看到一个无人看守的部门的唯一地方是here,但是加权样本大小可以从根本上为零吗?...也许最后的估计量以某种方式被破坏了,通过充分学习训练数据?尝试打印/绘制最后拟合的树?
  • 感谢您的回复@BenReiniger 我已经用 sklearn 数据集添加了重新创建的错误。
  • 我无法在 sklearn 版本 0.22.2.post1 中重新创建它;你运行的是什么版本?
  • 我使用的是 0.24.2 版本,你认为它是某种错误吗?

标签: scikit-learn adaboost


【解决方案1】:

我在您的数字示例中缩小了范围。在树 20 中,特征 38 用于五个分裂,在最后一个(节点 353)中,右孩子的 impurity-np.inf (!?)。因此,该拆分处的原始(未归一化)重要性为+inf,因此该树的特征的总原始重要性为+inf,因此当对这棵树的重要性进行归一化时,其他所有特征都得到something / inf = 0 ,而此功能获得inf / inf = nan。然后跨树聚合,这个特征(以及其他特征,因为可能在其他树中存在类似问题)具有重要性nan(并且其他特征的重要性因没有从这棵树中获得真正的贡献而出现偏差)。

我看不到导致此问题的 0.22 和 0.23 之间发生了什么变化,我也不真正理解基尼系数是如何计算出-inf 的;也许是一些溢出问题?

【讨论】:

  • 哇!您真的设法解决了问题的核心,这完全有道理。我已将其作为可能的错误记录在 Github 上。非常感谢您查看并解决它(为什么杂质最终成为 -np-inf是另一个故事!)
  • 这是该问题的链接:github.com/scikit-learn/scikit-learn/issues/20320,谢谢!
猜你喜欢
  • 2014-02-17
  • 2019-11-05
  • 2019-05-30
  • 2021-08-22
  • 2014-08-06
  • 2013-04-26
  • 2019-08-10
  • 2016-12-11
  • 2018-12-14
相关资源
最近更新 更多