scikit learn Pipeline中的后处理分类器输出

Posted

技术标签:

【中文标题】scikit learn Pipeline中的后处理分类器输出【英文标题】:Post-process classifier output in scikit learn Pipeline 【发布时间】:2016-02-07 16:59:50 【问题描述】:

我在 scikit learn 中使用Pipeline 将一些预处理与OneClassSVM 组合在一起作为最终分类器。为了计算合理的指标,我需要一个后处理,将OneClassSVM 的 -1,1 输出转换为 0 和 1。有没有任何结构化的方法可以将这种后处理添加到Pipeline? 在最终估算器之后不能使用变形金刚。

【问题讨论】:

您可以在第一个管道之上使用第二个管道:) @Olologin 真的:因为第一个管道不会在最后一步实现transform 但是你应该以某种方式从第一条管道制作变压器。因为如果它具有预测器作为最后的估计器 - 所有管道都将成为预测器。我认为最好继承 Pipeline 并使用您的自定义功能对其进行扩展。毕竟这种 OOP 技巧的可能性是 scikit-learn 的主要好处。 【参考方案1】:

您可以将类 sklearn.preprocessing.TransformedTargetRegressor 与您的 SVM 分类器一起用作回归器,并使用 inverse_func 参数在分类后转换您的标签。

但是,由于TransformedTargetRegressor 应该在拟合之前将您的标签转换为新空间并将预测的标签重新映射到原始空间,因此它希望在拟合之前转换标签数组并且不接受空或@987654324 @目标作为输入。因此,您需要为您的管道提供一个虚拟目标,这会使您的代码有点混乱。

例子:

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]])

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

【讨论】:

【参考方案2】:

我们开发了 PipeGraph,它是 Scikit-Learn Pipeline 的扩展,它允许您获取中间数据、构建类似工作流的图表,特别是解决这个问题(请参阅图库中的示例 http://mcasl.github.io/PipeGraph)

【讨论】:

谢谢。这以某种方式为问题提供了解决方案。所以我可以接受这个作为答案。 您能否详细解释一下如何解决模型后处理输出的问题? 在标准管道中,除了最后一步之外的所有步骤都是转换器,而最后一步是预测器。在 pipegraph 中没有这样的限制,因此您可以在预测器之后采取进一步的步骤来对输出进行后处理。事实上,作为一个图结构,这不仅可以发生在之前或之后,还可以发生在并行分支中。 是否还有其他库可以在管道内的估算器之间进行此类连接?我试过 PipeGraoh,但它不适用于 LBM @lucaschn 如果您添加一个玩具示例,我可以帮助您并找出它不适合您的原因。【参考方案3】:

另外 2 种考虑方式:

(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

【讨论】:

以上是关于scikit learn Pipeline中的后处理分类器输出的主要内容,如果未能解决你的问题,请参考以下文章

Scikit-Learn Pipeline 中的新功能 - 两个现有功能之间的交互

使用 Python Scikit-learn 中的 Pipeline 和 featureUnion 将多个功能合二为一

Scikit-learn 中的 GridSearchCV 输出问题

Scikits-learn:将自定义词汇表与 Pipeline 一起使用

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

Scikit-learn 多输出分类器使用:GridSearchCV、Pipeline、OneVsRestClassifier、SGDClassifier