在 SciKit-Learn 中使用管道的排列重要性

Posted

技术标签:

【中文标题】在 SciKit-Learn 中使用管道的排列重要性【英文标题】:Permutation importance using a Pipeline in SciKit-Learn 【发布时间】:2020-09-18 05:14:08 【问题描述】:

我正在使用来自SciKit 的确切示例,它将permutation_importancetree feature_importances 进行比较

如您所见,使用了 Pipeline:

rf = Pipeline([
    ('preprocess', preprocessing),
    ('classifier', RandomForestClassifier(random_state=42))
])
rf.fit(X_train, y_train)

permutation_importance

现在,当您拟合 Pipeline 时,它会一个接一个地拟合所有转换并转换数据,然后使用最终估计器拟合转换后的数据。

在示例的后面,他们在拟合模型上使用了permutation_importance

result = permutation_importance(rf, X_test, y_test, n_repeats=10,
                                random_state=42, n_jobs=2)

问题:我不明白的是result中的特征还是原来的未转换特征。为什么会这样?这工作正常吗?那么Pipeline的目的是什么?

tree feature_importance: 在同一个示例中,当他们使用feature_importance 时,结果会被转换:

tree_feature_importances = (
    rf.named_steps['classifier'].feature_importances_)

我显然可以转换我的特征然后使用permutation_importance,但是示例中提供的步骤似乎是故意的,应该有permutation_importance不转换特征的原因。

【问题讨论】:

我可以从代码中看到它遍历 X (for col_idx in range(X.shape[1])) 的原始列并在循环内进行转换。想不出一个可能出错的特殊情况,但这就是正在发生的事情 这也让我很沮丧。由于所有内容都组装到管道中,因此我找不到一种简单的方法来进行排列重要性。如果我打破预处理器并在排列之前进行转换,我会对标签的列排序感到头疼。如果在 permutation_importance 中正确应用管道,这一切都可以解决 @Josh,是的,我决定这样做。我转换特征,然后将转换后的向量传递给管道。 愿意接受(正确)答案吗? 【参考方案1】:

这是预期的行为。排列重要性的工作方式是打乱输入数据并将其应用于管道(或模型,如果这是你想要的)。事实上,如果您想了解初始输入数据如何影响模型,那么您应该将其应用于管道。

如果您对预处理步骤生成的每个附加特征的特征重要性感兴趣,那么您应该生成带有列名的预处理数据集,然后将该数据直接应用于模型(使用排列重要性)管道。

在大多数情况下,人们对了解管道生成的次要特征的影响不感兴趣。这就是为什么他们在这里使用管道来包含预处理和建模步骤。

【讨论】:

感谢您的回答。我想还有另一个原因。 one-hot 编码导致完美的多重共线性,给 PI 提供多重共线性特征可能会产生误导

以上是关于在 SciKit-Learn 中使用管道的排列重要性的主要内容,如果未能解决你的问题,请参考以下文章

从 Sklearn 管道中提取具有特征名称的特征重要性

scikit-learn:在管道中使用 SelectKBest 时获取选定的功能

为啥在 scikit-learn 中使用 make_pipeline 时出现“管道的最后一步”错误?

scikit-learn 在管道中使用多个类预处理 SVM

在 scikit-learn 管道中插入或删除步骤

使用 GridSearchCV scikit-learn 在管道中的 KMeans