Joblib 和 pickle 的不同用例是什么?

背景: 我刚刚开始使用 scikit-learn,并在页面底部阅读了有关 临场发挥,对阵腌黄瓜的内容。

使用 joblib 替换 pickle (joblib.dump & joblib.load)可能更有趣,它对大数据更有效,但只能对磁盘进行 pickle,而不能对字符串进行 pickle

我看了这个关于泡菜的问答, Python 中 pickle 的常见用例,想知道这里的社区是否可以分享 joblib 和 pickle 之间的区别?什么时候应该使用一个而不是另一个?

66080 次浏览
  • 在大型 numpy 数组 上,joblib 通常要快得多,因为它对 numpy 数据结构的数组缓冲区有特殊的处理。要查找有关实现的详细信息,可以查看 源代码。它还可以在使用 zlib 或 lz4进行 pickle 时动态压缩该数据。
  • Joblib 还可以在加载一个未压缩的 joblib-pickled numpy 数组时映射 数据缓冲区,从而使进程之间共享内存成为可能。
  • 如果没有 pickle 大型 numpy 数组,那么普通 pickle 的速度会快得多,特别是对于大型的小型 python 对象集合 (例如 str 对象的大型 dict) ,因为标准库的 pickle 模块是用 C 语言实现的,而 joblib 是纯 Python。
  • 由于 PEP 574(Pickle protocol 5)已经合并到 Python 3.8中,因此使用标准库来 Pickle 大型数组现在更加有效(从内存和 CPU 的角度来看)。在此上下文中,大数组意味着4GB 或更大。
  • Joblib 在 Python 3.8中加载具有嵌套 numpy 数组的对象时仍然很有用在内存映射模式下使用 mmap_mode="r"

我遇到了同样的问题,所以我尝试了这个(使用 Python 2.7) ,因为我需要加载一个大的 pickle 文件

#comapare pickle loaders
from time import time
import pickle
import os
try:
import cPickle
except:
print "Cannot import cPickle"
import joblib


t1 = time()
lis = []
d = pickle.load(open("classi.pickle","r"))
print "time for loading file size with pickle", os.path.getsize("classi.pickle"),"KB =>", time()-t1


t1 = time()
cPickle.load(open("classi.pickle","r"))
print "time for loading file size with cpickle", os.path.getsize("classi.pickle"),"KB =>", time()-t1


t1 = time()
joblib.load("classi.pickle")
print "time for loading file size joblib", os.path.getsize("classi.pickle"),"KB =>", time()-t1

输出为

time for loading file size with pickle 1154320653 KB => 6.75876188278
time for loading file size with cpickle 1154320653 KB => 52.6876490116
time for loading file size joblib 1154320653 KB => 6.27503800392

根据这个 joblib 比这3个模块中的 cPickle 和 Pickle 模块工作得更好,谢谢

感谢 Gunjan 给我们这个脚本! 我为了 Python 3的结果修改了它

#comapare pickle loaders
from time import time
import pickle
import os
import _pickle as cPickle
from sklearn.externals import joblib


file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'database.clf')
t1 = time()
lis = []
d = pickle.load(open(file,"rb"))
print("time for loading file size with pickle", os.path.getsize(file),"KB =>", time()-t1)


t1 = time()
cPickle.load(open(file,"rb"))
print("time for loading file size with cpickle", os.path.getsize(file),"KB =>", time()-t1)


t1 = time()
joblib.load(file)
print("time for loading file size joblib", os.path.getsize(file),"KB =>", time()-t1)


time for loading file size with pickle 79708 KB => 0.16768312454223633
time for loading file size with cpickle 79708 KB => 0.0002372264862060547
time for loading file size joblib 79708 KB => 0.0006849765777587891

只是个小小的提示。 泡菜更适合于适当的 scikit-learn 估计器/训练有素的模型。在机器学习应用中,训练好的模型主要用于保存和加载以进行预测。