我想在一个neuraxle管道中使用分类器,例如sklearn.linear_model.SGDClassifier
,并使用partial_fit
以在线方式进行训练。我已经将分类器包装在SKLearnWrapper
中,并设置了use_partial_fit=True
,如下所示:
from neuraxle.pipeline import Pipelinefrom neuraxle.steps.sklearn import SKLearnWrapperfrom sklearn.linear_model import SGDClassifierp = Pipeline([ SKLearnWrapper(SGDClassifier(), use_partial_fit=True) ])X = [[1.], [2.], [3.]]y = ['class1', 'class2', 'class1']p.fit(X, y)
然而,要以在线方式训练分类器,需要向partial_fit
函数提供一个额外的参数classes
,该参数包含数据中可能出现的类别,例如classes=['class1', 'class2']
,至少在首次调用时需要提供。因此,上述代码会导致错误:
ValueError: classes must be passed on the first call to partial_fit.
同样的问题也出现在其他fit_params
参数上,例如sample_weight
。在标准的sklearn管道中,可以通过<step name>__<parameter name>语法将fit_params
传递给各个步骤,例如对于sample_weight
参数:
from sklearn.linear_model import SGDClassifierfrom sklearn.pipeline import Pipelineq = Pipeline([ ('clf', SGDClassifier())])q.fit(X, y, clf__sample_weight=[0.25, 0.5, 0.25])
当然,标准的sklearn管道不允许对分类器调用partial_fit
,这就是为什么我最初想使用neuraxle管道的原因。
在neuraxle管道中,有没有办法向步骤的fit
或partial_fit
函数传递额外的参数呢?
回答:
我建议您编辑SKLearnWrapper,通过重新定义partial_fit
方法来添加参数,并添加您想要的缺失参数。
您还可以在分叉的SKLearnWrapper中添加一个方法,如下所示。可以通过稍后从管道外部调用的apply
方法来更改类别参数。
ConfigurablePartialSGDClassifier(SKLearnWrapper) def __init__(self): super().__init__(SGDClassifier(), use_partial_fit=True) def update_classes(self, classes: List[str]): self.classes = classes def _sklearn_fit_without_expected_outputs(self, data_inputs): self.wrapped_sklearn_predictor.partial_fit(data_inputs, classes=self.classes)
然后您可以这样做:
p = Pipeline([ ('clf', ConfigurablePartialSGDClassifier())])X1 = [[1.], [2.], [3.]]X2 = [[4.], [5.], [6.]]Y1 = [0, 1, 1]Y2 = [1, 1, 0]classes = ['class1', 'class2', 'class1']p.apply("update_classes", classes)p.fit(X1, Y1)p.fit(X2, Y2)
请注意,p
也可以这样简单定义以获得相同的行为:
p = ConfigurablePartialSGDClassifier()
关键是,调用apply
方法可以穿过管道,如果步骤中包含此类方法,则会应用于所有嵌套步骤。