Sklearn 自定义转换器:使用 FunctionTransformer 和子类化 TransformerMixin 的区别

Posted

技术标签:

【中文标题】Sklearn 自定义转换器:使用 FunctionTransformer 和子类化 TransformerMixin 的区别【英文标题】:Sklearn custom transformers: difference between using FunctionTransformer and subclassing TransformerMixin 【发布时间】:2018-11-30 13:52:08 【问题描述】:

为了进行正确的 CV,建议使用管道,以便可以将相同的转换应用于 CV 中的每个折叠。我可以使用sklearn.preprocessing.FunctionTrasformersubclassing sklearn.base.TransformerMixin 定义自定义转换。推荐的方法是哪一种?为什么?

【问题讨论】:

【参考方案1】:

这完全取决于你,两者或多或少都会达到相同的结果,只是你编写代码的方式不同。

例如,在使用 sklearn.preprocessing.FunctionTransformer 时,您可以简单地定义要使用的函数并像这样直接调用它 (code from official documentation)

def all_but_first_column(X):
    return X[:, 1:]

def drop_first_component(X, y):
    """
    Create a pipeline with PCA and the column selector and use it to
    transform the dataset.
    """
    pipeline = make_pipeline(PCA(), FunctionTransformer(all_but_first_column),)

    X_train, X_test, y_train, y_test = train_test_split(X, y)
    pipeline.fit(X_train, y_train)
    return pipeline.transform(X_test), y_test

另一方面,在使用subclassing sklearn.base.TransformerMixin 时,您必须定义整个类以及该类的fittransform 函数。 所以你必须创建一个这样的类(示例代码取自this blog post)

class FunctionFeaturizer(TransformerMixin):
    def __init__(self, *featurizers):
        self.featurizers = featurizers

    def fit(self, X, y=None):
        return self

    def transform(self, X):
        #Do transformations and return
        return transformed_data

如您所见,TransformerMixin 在转换功能方面与 FunctionTransformer 相比为您提供了更大的灵活性。您可以根据值应用多个转换或部分转换等。一个示例可以是,对于您想要记录的前 50 个值,而对于接下来的 50 个值,您希望采用逆对数等。您可以轻松定义转换方法以选择性地处理数据。

如果你只是想直接使用一个函数,使用sklearn.preprocessing.FunctionTrasformer,否则如果你想做更多的修改或者说复杂的转换,我建议subclassing sklearn.base.TransformerMixin

在这里,看看以下链接以获得更好的想法

handling unknown categories in sklearn Building sklearn compatible transformer official documentation example of function transformer

【讨论】:

您是否必须同时继承 BaseEstimatorTransformerMixin 才能使 FunctionFeaturizer 正常工作?【参考方案2】:

FunctionTransformerTransformerMixin 的子类之间的主要区别在于,对于后者,您可以通过应用 fit 方法来学习自定义转换器。

例如StandardScalerfit 方法中学习列的均值和标准差,在transform 方法中这些属性用于转换。这不能通过简单的FunctionTransformer 来实现,至少不能以规范的方式实现,因为您必须以某种方式通过火车。

这种学习的可能性实际上是使用自定义转换器和管道的原因 - 如果您只是通过使用 FunctionTransformer 应用普通函数,则在交叉验证过程中没有任何收获。是在交叉验证之前转换一次还是在交叉验证的每个步骤中转换都没有区别(除了后者会花费更多时间)。

【讨论】:

这应该是公认的答案。 FunctionTransformer 仅用于无状态转换。

以上是关于Sklearn 自定义转换器:使用 FunctionTransformer 和子类化 TransformerMixin 的区别的主要内容,如果未能解决你的问题,请参考以下文章

使用自定义转换器子类对 sklearn 管道进行评分时出现 AttributeError,但在拟合时却没有

管道中的自定义 sklearn 转换器为 cross_validate 抛出 IndexError 但在使用 GridSearchCV 时不会

在 sklearn 中创建自定义转换器时出错 - 需要 2 个位置参数,但给出了 3 个

如何在 sklearn 中修复这个自定义转换器?

您好,关于 sklearn.Pipeline 的两个问题,带有用于时间序列的自定义转换器 [关闭]

在 sklearn 管道中转换估计器的结果