为了进行正确的交叉验证(CV),建议使用管道(pipelines),这样可以对CV中的每个折叠应用相同的变换。我可以通过使用sklearn.preprocessing.FunctionTrasformer
或子类化sklearn.base.TransformerMixin
来定义自定义变换。哪一种方法是推荐的?为什么?
回答:
这完全取决于你,两者大体上能达到同样的结果,只是代码编写方式不同。
例如,使用sklearn.preprocessing.FunctionTransformer
时,你可以简单地定义你想要使用的函数并直接调用它,就像这样(官方文档中的代码)
def all_but_first_column(X): return X[:, 1:]def drop_first_component(X, y): """ 创建一个包含PCA和列选择器的管道,并使用它来转换数据集。 """ 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
另一方面,使用子类化sklearn.base.TransformerMixin
时,你需要定义整个类以及类的fit
和transform
函数。因此,你需要创建一个这样的类(示例代码来自这篇博客文章)
class FunctionFeaturizer(TransformerMixin): def __init__(self, *featurizers): self.featurizers = featurizers def fit(self, X, y=None): return self def transform(self, X): #执行变换并返回 return transformed_data
如你所见,相对于FunctionTransformer,TransformerMixin
在变换函数方面提供了更多的灵活性。你可以应用多个变换,或根据值进行部分变换等。例如,对于前50个值你想取对数,而对于接下来的50个值你想取反对数,依此类推。你可以轻松地定义你的变换方法来选择性地处理数据。
如果你只是想直接使用一个函数,就使用sklearn.preprocessing.FunctionTrasformer
;否则,如果你想进行更多修改或说复杂的变换,我建议子类化sklearn.base.TransformerMixin
。
在这里,看看以下链接可以获得更好的理解