如何获得具有预处理和分类步骤的决策树管道的特征重要性?
Posted
技术标签:
【中文标题】如何获得具有预处理和分类步骤的决策树管道的特征重要性?【英文标题】:How do I get feature importances for decision tree pipeline that has preprocessing and classification steps? 【发布时间】:2021-12-05 03:48:06 【问题描述】:我正在尝试在 UCI 成人数据集上拟合决策树模型。为此,我构建了以下管道:
nominal_features = ['workclass', 'education', 'marital-status', 'occupation',
'relationship', 'race', 'sex', 'native-country']
nominal_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')),
('ohe', OneHotEncoder(handle_unknown='ignore'))
])
numeric_features = ['age', 'fnlwgt', 'capital-gain', 'capital-loss', 'hours-per-week']
numeric_transformer = Pipeline(steps=[
('scaler', StandardScaler())
])
preprocessor = ColumnTransformer(
transformers=[
('numeric', numeric_transformer, numeric_features),
('nominal', nominal_transformer, nominal_features)
]) # remaining columns will be dropped by default
clf = Pipeline(steps=[
('preprocessor', preprocessor),
('classifier', DecisionTreeClassifier(criterion='entropy', random_state=0))
])
然后我通过调用来拟合我的模型
clf.fit(X_train, y_train)
然后,当我尝试获取特征重要性时,
clf.named_steps['classifier'].feature_importances_
我得到一个形状数组 (104,)
array([1.39312528e-01, 1.92086014e-01, 1.15276068e-01, 4.01797967e-02,
7.08805229e-02, 3.99687904e-03, 6.68727677e-03, 0.00000000e+00,
1.02021005e-02, 5.06637671e-03, 7.97826949e-03, 5.64939616e-03,
0.00000000e+00, 9.09583016e-04, 1.84022196e-03, 9.29047900e-04,
1.74001682e-04, 8.55362503e-05, 2.32440522e-03, 4.65023589e-04,
4.13278579e-03, 3.68265995e-03, 1.78503960e-02, 8.33035943e-03,
6.94454768e-03, 1.75988171e-02, 5.40933687e-04, 7.51299294e-03,
6.07480929e-03, 2.28627732e-03, 1.32219786e-03, 1.92990938e-01,
1.18517448e-03, 1.61377248e-03, 5.72167000e-04, 1.34920904e-03,
5.41685180e-03, 0.00000000e+00, 9.16416279e-03, 1.05824472e-02,
3.07744966e-03, 3.07152204e-03, 5.06657379e-03, 5.21819782e-03,
0.00000000e+00, 7.49534136e-03, 2.83936918e-03, 8.62398812e-03,
5.78720378e-03, 5.37536831e-03, 2.99744077e-03, 1.87247908e-03,
4.87696805e-04, 1.58422357e-03, 2.20761597e-03, 5.57396015e-03,
1.17619435e-03, 1.87465473e-03, 4.08710965e-03, 6.73508851e-04,
6.02887867e-03, 2.38887308e-03, 4.52029746e-03, 7.28018074e-05,
5.13158297e-04, 2.66768058e-04, 0.00000000e+00, 3.28378333e-04,
0.00000000e+00, 8.55362503e-05, 0.00000000e+00, 7.89886262e-04,
1.84475320e-04, 1.37879652e-03, 0.00000000e+00, 3.27800552e-04,
1.95189232e-04, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 9.00792536e-04, 0.00000000e+00, 2.20606426e-04,
5.82787439e-04, 4.85000896e-04, 5.33409400e-04, 0.00000000e+00,
8.75840665e-04, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4.65546160e-04, 3.37472507e-04, 2.50837357e-04, 2.52474592e-04,
0.00000000e+00, 1.47818105e-04, 3.06829767e-04, 3.73651596e-04,
1.58778645e-04, 4.40566013e-03, 8.55362503e-05, 2.51672361e-04])
这是不正确的,因为我只有 13 个功能。我知道原因是 OneHotencoding。
如何获得实际的特征重要性?
【问题讨论】:
欢迎来到 SO;如果答案解决了您的问题,请接受 - 请参阅What should I do when someone answers my question? 【参考方案1】:恐怕您无法在此处了解您的初始功能的重要性。你的决策树对它们一无所知;它唯一看到和知道的是编码的,没有别的。
你可能想试试permutation importance,它比基于树的特征重要性有几个优点;它也很容易应用于管道 - 参见Permutation importance using a Pipeline in SciKit-Learn。
【讨论】:
是的,我尝试了排列重要性并且它有效。那么,每当我们必须对某些特征进行 onehot 编码时,特征重要性基本上是无法解释的? @chesslad 是的;另外,经典的特征重要性度量在实践中并不是很有用,因为不同的重要性度量可能会产生不一致的结果 - 请参阅towardsdatascience.com/…。【参考方案2】:从根本上说,数据列的重要性可以通过将所有基于它的特征的重要性相加来获得。手动识别列到特征的映射可能有点困难,但您始终可以使用自动化工具。
例如,SkLearn2PMML 包可以将 Scikit-Learn 管道转换为 PMML 表示,并在此过程中执行各种分析和转换。很好地支持聚合特征重要性的计算。
from sklearn2pmml import sklearn2pmml
from sklearn2pmml.pipeline import PMMLPipeline
pipeline = PMMLPipeline([
("preprocessor", preprocessor),
("classifier", clf)
])
pipeline.fit(X, y)
# Re-map the dynamic attribute to a static pickleable attribute
clf.pmml_feature_importances_ = clf.feature_importances_
sklearn2pmml(pipeline, "PipelineWithImportances.pmml.xml")
【讨论】:
以上是关于如何获得具有预处理和分类步骤的决策树管道的特征重要性?的主要内容,如果未能解决你的问题,请参考以下文章