如何在 Python 2 中加载 Python 3 Pickled SKlearn 模型

How to load Python 3 Pickled SKlearn Model in Python 2

我有一个 Python 3.6 脚本,可以训练 SKLearn 模型,然后使用以下代码保存模型:

with open('filepath', 'wb') as f:
    pickle.dump(trained_model, f, protocol=2)

当我尝试在 python 3.6 中加载 pickle 时,一切正常:

>>with open('filepath', 'rb') as f:
>>    model = pickle.load(f)
>>
>>model

RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
        max_depth=None, max_features='auto', max_leaf_nodes=None,
        min_impurity_decrease=0.0, min_impurity_split=None,
        min_samples_leaf=1, min_samples_split=2,
        min_weight_fraction_leaf=0.0, n_estimators=80, n_jobs=1,
        oob_score=False, random_state=None, verbose=0,
        warm_start=False)

当我在 Python 2.7 中 运行 同样的 pickle.load 命令时,出现以下错误:

>>with open('filepath', 'rb') as f:
>>    model = pickle.load(f)

ValueError: non-string names in Numpy dtype unpickling

查看文档和类似案例,将协议设置为 2 应该 使 pickle 文件兼容。是什么导致了这个问题,我该如何解决?

您可以使用 pickle._load() instead of .load() to force using a pure-Python implementation 并获得更有用的回溯。

如果错误部分在 numpy 的代码中,您仍然只能使用 C 调试器或手动跟踪源代码...
...或者使用 numpy pickle format spec 在被送入 numpy 的拆酸例程的部分上并尝试猜测它有什么问题!

  • pickletools.dis() 为您做到!它打印 pickle 数据的反汇编,包括偏移量。 尽管您可能仍然需要规范来找出违规的性质。

也就是说,3.4. Model persistence — scikit-learn 0.19.1 documentation 确实警告在另一个版本 and/or 架构中加载模型数据不受支持,并建议改为保存源 material。