在SciKit-Learn中使用Pipeline进行排列重要性评估

3
我将使用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 的目的是什么?

enter image description here

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

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

enter image description here

我显然可以转换我的特征,然后使用permutation_importance,但似乎示例中呈现的步骤是有意为之的,并且permutation_importance不转换特征应该有其原因。

我可以从代码中看到它在X的原始列上进行迭代 (for col_idx in range(X.shape[1])),并在循环内部进行转换。想不出特定的情况会出错,但这就是正在发生的事情。 - towi_parallelism
1
这让我也很沮丧。由于所有内容都被组合成了管道,我找不到简单的置换重要性计算方法。如果我在置换之前拆分预处理器并进行转换,标签的列顺序会导致各种各样的问题。如果管道在置换重要性计算中得到正确应用,这一切都可以解决。 - Josh
@Josh,是的,我决定做同样的事情。我转换特征,然后将转换后的向量传递给管道。 - towi_parallelism
是否愿意接受(正确的)答案? - desertnaut
你如何将箱线图过滤为仅显示最重要的特征? - Josh Zwiebel
1个回答

4
这是预期的行为。排列重要性的工作方式是对输入数据进行洗牌,并将其应用于管道(或模型,如果您想这样做)。实际上,如果您想了解初始输入数据如何影响模型,则应将其应用于管道。
如果您对由预处理步骤生成的每个附加特征的特征重要性感兴趣,则应该生成带有列名称的预处理数据集,然后直接将该数据应用于模型(使用排列重要性),而不是管道。
在大多数情况下,人们不感兴趣学习管道生成的次要特征的影响。这就是为什么他们在此处使用管道来包括预处理和建模步骤的原因。

感谢您的回答。我猜还有另一个原因。独热编码会导致完美的多重共线性,将多重共线性特征提供给PI可能会误导。 - towi_parallelism

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接