在scikit learn Pipeline中对分类器输出进行后处理

10
我在scikit learn中使用Pipeline将一些预处理与OneClassSVM分类器组合在一起。为了计算合理的指标,我需要进行后处理,将OneClassSVM的-1,1输出转换为0和1。是否有结构化的方法将这样的后处理添加到Pipeline中? 不能在最终评估器之后使用变换器。

你可以在第一个管道的基础上使用第二个管道 :) - Ibraim Ganiev
@Olologin 真的:因为第一个管道在其最后一步中不会实现 transform - languitar
但是你应该从第一个管道中制作变压器。因为如果它有预测器作为最后的估计器 - 所有管道都会成为预测器。 我认为最好继承Pipeline并用自定义功能扩展它。毕竟,这种OOP技巧的可能性是scikit-learn的主要优势。 - Ibraim Ganiev
3个回答

5
您可以使用类sklearn.preprocessing.TransformedTargetRegressor作为回归器,将inverse_func参数用于分类后的标签转换。
然而,由于TransformedTargetRegressor需要在拟合之前将标签转换为新空间并将预测结果重新映射到原始空间,因此它需要一组要在拟合之前转换的标签,并且不接受空目标或None作为输入。因此,您需要为您的管道提供一个虚拟目标,这可能会让您的代码有点混乱。
例如:
import numpy as np
from sklearn.compose import TransformedTargetRegressor
from sklearn.svm import OneClassSVM
from sklearn.pipeline import Pipeline

X = np.random.random((10, 2))

regressor = OneClassSVM(gamma='auto')
svm = TransformedTargetRegressor(regressor=regressor,
    inverse_func=lambda x: (x+1)//2, # Function that remaps your labels
    check_inverse=False) # If not set to False, this code will generate an error since the provided inverse_func is not the inverse of the default func argument, which is the identity function

pipeline = Pipeline([
    ('svm', svm)
])

pipeline.fit(X, np.zeros((1,1))) # An array of fake label is provided to the pipeline
pipeline.predict(X)

输出:

array([[0],
       [1],
       [1],
       [1],
       [1],
       [0],
       [1],
       [0],
       [0],
       [0]])

请注意,如果您需要通过字典将参数传递给 OneClassSVM 分类器,并使用 Pipeline 进行实例化,例如在 GridSearchCV 中进行网格搜索,则需要在参数键名之间添加 regressor__ ,并在 svm__ 和参数名称之间。例如,svm__kernel变成了svm__regressor__kernel

2
我们开发了PipeGraph,这是Scikit-Learn Pipeline的一个扩展,可以让您获取中间数据、构建类似于工作流的图形,并特别解决此问题(请参见示例画廊:http://mcasl.github.io/PipeGraph)。

1
谢谢。这在某种程度上提供了解决问题的方案。所以我可以接受这个答案。 - languitar
你能详细解释一下你是如何处理模型输出的后处理问题吗? - Long Le
在标准的管道中,除了最后一步是预测器外,其余步骤都是变换器。但在管道图中没有这样的限制,因此您可以在预测器之后放置进一步的步骤来对输出进行后处理。实际上,作为图形结构,这不仅可以发生在之前或之后,还可以发生在并行分支中。 - Manuel Castejón Limas
有其他库可以在管道内的估计器之间建立这样的连接吗?我尝试了PipeGraoh,但它与LBM不兼容。 - lucaschn
@lucaschn 如果您提供一个玩具示例,我可以帮助您找出原因,为什么它对您不起作用。 - Manuel Castejón Limas
显示剩余2条评论

0

另外两种考虑方法:

(1) 创建一个OneClassSVM的包装分类器。在包装分类器的预测函数中,您调用OneClassSVM的预测,并在返回之前进行转换。请参见下面的链接以获取分类器模板: https://scikit-learn.org/stable/developers/develop.html

(2) 创建一个简单的分类器来进行转换,然后使用StackingClassifier将OneClassSVM和简单分类器链接在一起: https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.StackingClassifier.html


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