2

我有一个使用 sklearn joblib 加载持久模型并执行预测的 python 脚本。当我在我的用户名下运行脚本时,脚本运行良好,当其他用户尝试运行相同的脚本时,他们收到错误“ImportError:没有名为 numpy_pickle 的模块”

我还将脚本复制到另一个用户主目录并从那里运行它仍然是同样的错误,我也从 python shell 运行它并且没有任何改变。这是我在 Python shell 中运行的内容:

from sklearn.externals import joblib
joblib.load("model_filename.pkl")

上面的第二行在我的用户名下工作,并在所有其他用户下给出以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/pymodules/python2.7/joblib/numpy_pickle.py", line 424, in load
    obj = unpickler.load()
  File "/usr/lib/python2.7/pickle.py", line 858, in load
    dispatch[key](self)
  File "/usr/lib/python2.7/pickle.py", line 1090, in load_global
    klass = self.find_class(module, name)
  File "/usr/lib/python2.7/pickle.py", line 1124, in find_class
    __import__(module)
ImportError: No module named numpy_pickle

这一切都在运行一台带有 Ubuntu 14.04.1 LTS 的服务器。

任何想法为什么会发生这种情况?

谢谢

4

3 回答 3

3

正如 Croad Langshan 所建议的,请确保您没有joblib 版本冲突/不匹配- 我遇到了完全相同的问题。二进制文件是使用sklearn.externals.joblib创建的,但是我使用的是从官方 debian 存储库安装的独立 joblib,这与股票 debian sklearn 相结合导致了一个不可选择的二进制存储。

因此,请检查您是否将python-joblib作为独立包安装,如果有 - 删除它,删除 sklearn 并从源代码重新安装 sklearn

$ sudo apt-get remove python-joblib
$ sudo apt-get remove python-sklearn

从源代码安装 sklearn

$ git clone https://github.com/scikit-learn/scikit-learn.git
$ sudo python setup.py install

*注意 - 可能发生冲突反转的情况(使用独立作业库创建的原始二进制文件)

*解决模块版本冲突/不匹配的更精细的解决方案是使用 virtualenv,但在我的情况下,我没有动力保留独立的 joblib

于 2015-03-27T18:28:27.487 回答
1

load 函数pickle在“幕后”使用 Python 标准库模块。该模块提供了一种将任意 python 对象转储到文件的方法。再次“Unpickling”该文件以将 python 对象从文件加载回内存需要 Python 文件,这些文件定义了定义对象类的模块(函数也是如此)。包含这些模块的目录需要打开sys.path(例如通过在环境变量中列出PYTHONPATH)。

也许有问题的泡菜引用了模块中的代码numpy_pickle(而不是joblib.numpy_pickle),也许那不是打开的sys.path(即使它joblib本身是)。尝试(在导入之前)运行import cgitb; cgitb.enable()以查看module最后一个堆栈帧中的值。

于 2015-03-01T19:54:26.583 回答
1

我有同样的问题。我与一个用户腌制了一个模型,但无法与第二个用户解除腌制。上面的答案并没有真正帮助我。我相信这与保存在腌制文件中的局部变量和第二个用户的路径有关。

该模块试图加载为:

__import__('joblib.numpy_pickle')

这导致

ImportError: No module named joblib.numpy_pickle

但如果你跑

__import__('sklearn.externals.joblib.numpy_pickle')

它可以找到它并返回

<module 'sklearn' from '/python2.6/site-packages/sklearn/__init__.pyc'>

所以我假设第二个用户正在尝试加载文件,并且文件中有一些设置告诉它在 joblib.numpy_pickle 中查找,同时忽略之前导入的 sklearn.externals。我不知道如何解决这个问题,所以我只是用第二个用户再次训练模型并保存它。现在第二个用户可以读取它创建的文件。

于 2015-08-11T13:50:58.773 回答