scikit-learn - 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])
解决方案
我在您的数字示例中缩小了范围。在树 20 中,特征 38 被用于五个分裂,并且在其中的最后一个(节点 353)中,右孩子的杂质是-np.inf
(!?)。因此,该分割处的原始(未归一化)重要性为+inf
,因此该树的特征的总原始重要性为+inf
,因此当对这棵树的重要性进行归一化时,其他所有特征都得到something / inf = 0
,而该特征得到inf / inf = nan
。然后跨树聚合,这个特征(以及其他特征,因为在其他树中可能存在类似问题)具有重要性nan
(并且其他特征的重要性因没有从这棵树中获得真正的贡献而出现偏差)。
我看不到导致此问题的 0.22 和 0.23 之间发生了什么变化,我也不真正理解-inf
基尼系数的计算是如何得出的;也许是一些溢出问题?
推荐阅读
- angular - Angular 中的小部件 Eventbrite
- unix - Unix - 将 GMT 时间字段转换为 PST 时间
- c++ - 为什么当我使用不同版本的 GCC 时使用 strtok 函数会显示此错误?
- amazon-web-services - 使用 boto3 调用 AWS SageMaker 终端节点时出错:“无法将数据解析为 JSON。确保 Content-Type 标头设置为“application/json”
- python - Raspberry Pi 长按按钮与短按控制 LED
- javascript - 尝试在谷歌脚本中运行两个函数和两个不同的电子邮件
- c# - 如何覆盖在帐户管理 mvc 部分的 dotnet 核心中生成的默认“site.css”
- android - 如何在 Android 中暂停 MediaPlayer
- java - Keycloak - 通过 Action Token SPI 完成登录流程的定制
- c# - 带有c#脚本任务的SSIS引用了一个自定义dll,其中命名空间中有一个点