首页 > 解决方案 > Adaboost Sklearn 特征重要性 NaN

问题描述

我正在用 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])





标签: scikit-learnadaboost

解决方案


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

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


推荐阅读