用它包装的函数保存一个sklearn`FunctionTransformer`

时间:2019-01-02 20:30:52

标签: python scikit-learn pickle joblib

我正在将sklearn的{​​{1}}和Pipeline用于自定义功能

FunctionTransformer

这是我的代码:

from sklearn.externals import joblib
from sklearn.preprocessing import FunctionTransformer
from sklearn.pipeline import Pipeline

我收到此错误:

  

AttributeError:模块'__ main__'没有属性'f'

如何解决?

请注意,此问题也在def f(x): return x*2 pipe = Pipeline([("times_2", FunctionTransformer(f))]) joblib.dump(pipe, "pipe.joblib") del pipe del f pipe = joblib.load("pipe.joblib") # Causes an exception

中发生

1 个答案:

答案 0 :(得分:5)

我能够使用marshal模块(除了pickle来破解解决方案,并覆盖{{1}所使用的魔术方法getstatesetstate }。

pickle

现在,如果我们使用import marshal from types import FunctionType from sklearn.base import BaseEstimator, TransformerMixin class MyFunctionTransformer(BaseEstimator, TransformerMixin): def __init__(self, f): self.func = f def __call__(self, X): return self.func(X) def __getstate__(self): self.func_name = self.func.__name__ self.func_code = marshal.dumps(self.func.__code__) del self.func return self.__dict__ def __setstate__(self, d): d["func"] = FunctionType(marshal.loads(d["func_code"]), globals(), d["func_name"]) del d["func_name"] del d["func_code"] self.__dict__ = d def fit(self, X, y=None): return self def transform(self, X): return self.func(X) 而不是MyFunctionTransformer,则代码将按预期工作:

FunctionTransformer

此方法的工作方式是从泡菜中删除函数from sklearn.externals import joblib from sklearn.pipeline import Pipeline @MyFunctionTransformer def my_transform(x): return x*2 pipe = Pipeline([("times_2", my_transform)]) joblib.dump(pipe, "pipe.joblib") del pipe del my_transform pipe = joblib.load("pipe.joblib") ,而f的代码和名称。

dill看起来也像封送处理的不错选择