什么是推荐的将自定义sklearn管道持久化(pickle)的方式?

7
我已经建立了一个sklearn管道,将一个标准支持向量回归组件与一些自定义变压器组合起来创建特征。然后将该管道放入一个对象中进行训练,然后使用pickle (这似乎是推荐的方式) 进行序列化。反序列化对象用于进行预测。

为了分发,使用pyinstaller将其转换为可执行文件。

当我从单元测试中调用反序列化的回归对象时,它可以正常工作。

但是,当我尝试使用PyInstaller二进制文件进行预测时,会得到一个长的堆栈跟踪,以此结束:

module = loader.load_module(fullname)   File "messagestream.pxd", line 5, in init scipy.optimize._trlib._trlib ImportError: No module named 'scipy._lib.messagestream'

这感觉像是一种腌制错误,可能是由于腌制与pyinstaller的交互作用引起的。我该如何重构我的代码,以便在取消腌制后,我的自定义管道可以像标准的sklearn回归器一样轻松且稳健地运行?


你是否正在使用Joblib对你的模型进行序列化? - Espoir Murhabazi
不,我正在使用pickle进行序列化,尽管我也尝试过joblib和dill,但都没有成功。 - Roko Mijic
有人遇到了同样的问题:https://dev59.com/CVYN5IYBdhLWcg3wsZ5R - Roko Mijic
2个回答

9

好的,在一些搜索后,似乎情况并不是由于pickling引起的,而只是一个pyinstaller“hidden imports”的问题,但由于某种原因当进行pickling时才会出现(不要问我为什么)。

以下解决了我当前的问题:编辑.spec文件,添加以下带有Scipy的隐藏导入:

 hiddenimports=['scipy._lib.messagestream']

我还需要一些与其他库相关的其他隐藏导入。
 hiddenimports=['sklearn.neighbors.typedefs',
                'scipy._lib.messagestream',
                'pandas._libs.tslibs.timedeltas'   ]

谢谢你的技巧。我在2017年5月没有遇到这个问题。这是新版本中的一个错误吗? - Stéphane
也适用于py2exe。 - munieq11
我在哪里可以找到.spec文件?我已经在.whl和环境中查找,但都没有找到。 - Daan Luttik

3

如果有人想通过CLI参数而不是像Roko的答案中所示的那样通过.spec文件来完成这个操作,以下是语法:

pyinstaller --hidden-import scipy._lib.messagestream --onefile your_python_file_here.py

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接