Sklearn 自定义转换器:使用 FunctionTransformer 和子类化 TransformerMixin 之间的区别
Sklearn custom transformers: difference between using FunctionTransformer and subclassing TransformerMixin
为了进行正确的 CV,建议使用管道,以便可以将相同的转换应用于 CV 中的每个折叠。我可以使用 sklearn.preprocessing.FunctionTrasformer
或 subclassing sklearn.base.TransformerMixin
来定义自定义转换。推荐的方法是哪一种?为什么?
这完全取决于你,两者或多或少会达到相同的结果,只是你编写代码的方式不同。
例如,在使用 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
时,您必须定义整个 class 以及 [=44= 的 fit
和 transform
函数].
所以你必须像这样创建一个 class(示例代码取自 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
在这里,查看以下链接以获得更好的想法
FunctionTransformer
和 TransformerMixin
的子类之间的主要区别在于,对于后者,您可以通过应用 fit
方法来学习您的自定义转换器。
例如StandardScaler
在 fit
方法中学习列的均值和标准差,在 transform
方法中这些属性用于转换。这不能通过简单的 FunctionTransformer
实现,至少不能以规范的方式实现,因为您必须以某种方式通过火车组。
这种学习的可能性实际上是使用自定义转换器和管道的原因 - 如果您只是通过使用 FunctionTransformer
来应用普通函数,那么在交叉验证过程中什么也得不到。在交叉验证之前转换一次或者在交叉验证的每个步骤中转换都没有区别(只是后者会花费更多时间)。
为了进行正确的 CV,建议使用管道,以便可以将相同的转换应用于 CV 中的每个折叠。我可以使用 sklearn.preprocessing.FunctionTrasformer
或 subclassing sklearn.base.TransformerMixin
来定义自定义转换。推荐的方法是哪一种?为什么?
这完全取决于你,两者或多或少会达到相同的结果,只是你编写代码的方式不同。
例如,在使用 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
时,您必须定义整个 class 以及 [=44= 的 fit
和 transform
函数].
所以你必须像这样创建一个 class(示例代码取自 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
在这里,查看以下链接以获得更好的想法
FunctionTransformer
和 TransformerMixin
的子类之间的主要区别在于,对于后者,您可以通过应用 fit
方法来学习您的自定义转换器。
例如StandardScaler
在 fit
方法中学习列的均值和标准差,在 transform
方法中这些属性用于转换。这不能通过简单的 FunctionTransformer
实现,至少不能以规范的方式实现,因为您必须以某种方式通过火车组。
这种学习的可能性实际上是使用自定义转换器和管道的原因 - 如果您只是通过使用 FunctionTransformer
来应用普通函数,那么在交叉验证过程中什么也得不到。在交叉验证之前转换一次或者在交叉验证的每个步骤中转换都没有区别(只是后者会花费更多时间)。