使用 joblib 加载腌制 scikit-learn 模型时出现 KeyError

Posted

技术标签:

【中文标题】使用 joblib 加载腌制 scikit-learn 模型时出现 KeyError【英文标题】:KeyError when loading pickled scikit-learn model using joblib 【发布时间】:2018-08-03 12:44:34 【问题描述】:

我有一个对象,其中包含两个scikit-learn 模型,一个IsolationForest 和一个RandomForestClassifier,我想对其进行腌制,然后将其解封并用于生成预测。除了这两个模型之外,该对象还包含几个 StandardScalers 和几个 Python 列表。

使用joblib 腌制这个对象是没有问题的,但是当我稍后尝试取消腌制它时,我得到以下异常:

Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "/home/(...)/python3.5/site-packages/joblib/numpy_pickle.py", line 578, in load
   obj = _unpickle(fobj, filename, mmap_mode)
 File "/home/(...)/python3.5/site-packages/joblib/numpy_pickle.py", line 508, in _unpickle
   obj = unpickler.load()
 File "/usr/lib/python3.5/pickle.py", line 1039, in load
   dispatch[key[0]](self)
KeyError: 0

同一个应用程序对对象进行pickle和unpickles,因此scikit-learnjoblib和其他库的版本是相同的。考虑到模糊的错误,我不确定从哪里开始调试。有什么想法或建议吗?

【问题讨论】:

您的电脑上是否安装了最新版本的 scikit? 你能生成最少的可重复代码吗? 【参考方案1】:

对此的解决方案相当平庸:在不知情的情况下,我使用sklearn.externals.joblib 中的joblib 版本进行酸洗,但使用更新版本的joblib 来解开对象。当我对这两个任务使用较新版本的 joblib 时,问题得到了解决。

【讨论】:

你好@haroba 我面临同样的问题你能告诉我你必须使用哪个版本吗?我正在使用 joblib-0.13.0 版本 平庸,但有用;)【参考方案2】:

我碰巧使用from sklearn.externals import joblib 导出模型并尝试使用import joblib 加载。

【讨论】:

【参考方案3】:

我的很有趣。我正在使用git-lfs,因此文件已被更改,joblib 无法打开它们。所以我需要运行git lfs pull 来获取实际文件。因此,如果您使用的是兼容的 joblib 版本,请确保您的文件不会以某种方式更改!

【讨论】:

【参考方案4】:

对我来说,使用相同版本的 joblib 进行转储和加载,但我将文件保存在 python 3.7.4 下并尝试使用引发相同 KeyError 的 python 3.7.6 加载。

【讨论】:

【参考方案5】:

就我而言,我试图加载 XGB。我发现XGB与其他sklearn模型不兼容,所以我做了以下:

from xgboost import *
import joblib

def get_model(model_path):
    if 'xgb' in model_path:
        xgb_model = XGBClassifier()
        xgb_model.load_model(model_path)
        model = xgb_model
    else: 
        model = get_obj(model_path)
    return model 

xbg = get_model('Models/xgb_v1.pkl') # an xgb

tree = model = get_model('Models/dt_v1.pkl') # a decition tree

【讨论】:

以上是关于使用 joblib 加载腌制 scikit-learn 模型时出现 KeyError的主要内容,如果未能解决你的问题,请参考以下文章

在 joblib `Parallel` 上下文中腌制 `matlab` 对象时出错

正在加载的管道仅返回列名

在使用 joblib 加载模型之前检查 sklearn 版本

使用 joblib.dump 保存和加载经过训练的 GradientBoostingClassifier

python使用joblib模块保存和加载机器学模型

从源码理解pickle和joblib加载dict的性能不同