使用 Python 3 在 scikit-learn 上进行大数据序列化
Posted
技术标签:
【中文标题】使用 Python 3 在 scikit-learn 上进行大数据序列化【英文标题】:Large data serialization on scikit-learn with Python 3 【发布时间】:2014-10-07 17:53:14 【问题描述】:我有一台配备 16 Gb RAM 的 MacBook (Mac OS X 10.9)。 通过 Anaconda 安装的两个 Python:2.7.8 和 3.4.1。两者都配备了最新的 scikit-learn 0.15.1。 在尝试运行该简单代码时(只是测试序列化大型矩阵的可能性):
import numpy as np
test_data = np.random.rand(10000, 60000)
print(test_data.nbytes / 2**30)
from sklearn.externals import joblib
joblib.dump(test_data, '/Users/va/Desktop/test_data.joblib')
Python 2.7.8 运行良好,但 Python 3.4.1 出现以下错误:
Failed to save <class 'numpy.ndarray'> to .npy file:
Traceback (most recent call last):
File "/Users/va/anaconda/python.app/Contents/lib/python3.4/site-
packages/sklearn/externals/joblib/numpy_pickle.py", line 240, in save
obj, filename = self._write_array(obj, filename)
File "/Users/va/anaconda/python.app/Contents/lib/python3.4/site-
packages/sklearn/externals/joblib/numpy_pickle.py", line 203, in _write_array
self.np.save(filename, array)
File "/Users/va/anaconda/python.app/Contents/lib/python3.4/site-
packages/numpy/lib/npyio.py", line 453, in save
format.write_array(fid, arr)
File "/Users/va/anaconda/python.app/Contents/lib/python3.4/site-
packages/numpy/lib/format.py", line 410, in write_array
fp.write(array.tostring('C'))
OSError: [Errno 22] Invalid argument
Traceback (most recent call last):
File "<ipython-input-3-90ed09e5c6d4>", line 1, in <module>
joblib.dump(test_data, '/Users/va/Desktop/test_data.joblib')
File "/Users/va/anaconda/python.app/Contents/lib/python3.4/site-
packages/sklearn/externals/joblib/numpy_pickle.py", line 368, in dump
pickler.dump(value)
File "/Users/va/anaconda/python.app/Contents/lib/python3.4/pickle.py", line 412, in dump
self.framer.end_framing()
File "/Users/va/anaconda/python.app/Contents/lib/python3.4/pickle.py", line 196, in end_framing
self.commit_frame(force=True)
File "/Users/va/anaconda/python.app/Contents/lib/python3.4/pickle.py", line 208, in commit_frame
write(data)
OSError: [Errno 22] Invalid argument
看来问题在于要存储的数据量。例如,Python 3 处理 np.random.rand(10000, 20000),它是 1.5 Gb,非常好。
以防万一,泡菜也不好用:
import pickle
with open('/Users/va/Desktop/test_data.pkl', 'wb') as f:
pickle.dump(test_data, f, protocol=pickle.HIGHEST_PROTOCOL)
前往:
Traceback (most recent call last):
File "<ipython-input-6-3f73f3011539>", line 3, in <module>
pickle.dump(test_data, f, protocol=pickle.HIGHEST_PROTOCOL)
OSError: [Errno 22] Invalid argument
在 Windows 7 上,Python 3.4 与 joblib
和 pickle
都可以正常工作。
有什么建议可以在 Mac 上使用 Python 3 解决这个问题吗?
【问题讨论】:
你安装的是 32 位还是 64 位 Python? 另外,你的底层文件系统类型是什么? FAT32、ext2,还有别的吗? 是的,64 位 Python。文件系统是HFS Plus。再一次,同样的代码在 2.7 上运行良好,所以它不能是文件系统。 这是 Python 中的一个错误。有一个开放的错误bugs.python.org/issue24658。他们创建了一个正在审查中的补丁(很长一段时间......) 【参考方案1】:我在 OS X 10.10 和 Python 3.4.3 上也使用pickle
时发生这种情况
相反,我开始使用 https://github.com/zopefoundation/zodbpickle,它慢了大约 2-3 倍,但绝对适用于 sklearn
分类器
【讨论】:
另一种解决方法是使用python open('/tmp/null','w+b').write(bytearray(2**32)
。注意 open() 中的参数“w+b”。为某些 OS X 工作(但不适合我)以上是关于使用 Python 3 在 scikit-learn 上进行大数据序列化的主要内容,如果未能解决你的问题,请参考以下文章
使用 SVM 作为图像分类器的精度/F 分数是不是可以达到 10%?
编码标准:是不是应该总是在每个方法或函数的末尾写“return”? [复制]
使用 python 3.8+(默认协议=5)时,pickle.load 在 python 3.7 中的(协议=4)对象上失败