基于大数据的增量PCA



我刚刚尝试使用来自sklearn.decomposition的IncrementalPCA,但它抛出了一个MemoryError,就像PCA和RandomizedPCA之前一样。我的问题是,我试图加载的矩阵太大,无法装入RAM。现在它被存储在hdf5数据库中,作为形状~(1000000,1000)的数据集,所以我有1.000.000.000个float32值。我认为IncrementalPCA批量加载数据,但显然它试图加载整个数据集,这没有帮助。如何使用这个库?是hdf5格式的问题?

from sklearn.decomposition import IncrementalPCA
import h5py
db = h5py.File("db.h5","r")
data = db["data"]
IncrementalPCA(n_components=10, batch_size=1).fit(data)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/software/anaconda/2.3.0/lib/python2.7/site-packages/sklearn/decomposition/incremental_pca.py", line 165, in fit
    X = check_array(X, dtype=np.float)
  File "/software/anaconda/2.3.0/lib/python2.7/site-packages/sklearn/utils/validation.py", line 337, in check_array
    array = np.atleast_2d(array)
  File "/software/anaconda/2.3.0/lib/python2.7/site-packages/numpy/core/shape_base.py", line 99, in atleast_2d
    ary = asanyarray(ary)
  File "/software/anaconda/2.3.0/lib/python2.7/site-packages/numpy/core/numeric.py", line 514, in asanyarray
    return array(a, dtype, copy=False, order=order, subok=True)
  File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper (-------src-dir-------/h5py/_objects.c:2458)
  File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper (-------src-dir-------/h5py/_objects.c:2415)
  File "/software/anaconda/2.3.0/lib/python2.7/site-packages/h5py/_hl/dataset.py", line 640, in __array__
    arr = numpy.empty(self.shape, dtype=self.dtype if dtype is None else dtype)
MemoryError

Thanks for help

您的程序可能在尝试将整个数据集加载到RAM时失败。32位/float32 × 1,000,000 × 1000等于3.7 GiB。这在只有4gb RAM的机器上可能是个问题。要检查这是否真的是问题所在,请尝试单独创建一个这样大小的数组:

>>> import numpy as np
>>> np.zeros((1000000, 1000), dtype=np.float32)

如果你看到一个MemoryError,你要么需要更多的RAM,要么你需要一次处理一个数据块。

对于h5py数据集,我们应该避免将整个数据集传递给我们的方法,而是传递数据集的切片。一次一个

因为我没有你的数据,让我从创建一个相同大小的随机数据集开始:

import h5py
import numpy as np
h5 = h5py.File('rand-1Mx1K.h5', 'w')
h5.create_dataset('data', shape=(1000000,1000), dtype=np.float32)
for i in range(1000):
    h5['data'][i*1000:(i+1)*1000] = np.random.rand(1000, 1000)
h5.close()

它创建一个漂亮的3.8 GiB文件。

现在,如果我们在Linux中,我们可以限制程序可用的内存数量:

$ bash
$ ulimit -m $((1024*1024*2))
$ ulimit -m
2097152

现在,如果我们试着运行你的代码,我们会得到MemoryError。(按Ctrl-D退出新的bash会话,稍后重置限制)

让我们试着解决这个问题。我们将创建一个IncrementalPCA对象,并多次调用它的.partial_fit()方法,每次都提供数据集的不同切片。

import h5py
import numpy as np
from sklearn.decomposition import IncrementalPCA
h5 = h5py.File('rand-1Mx1K.h5', 'r')
data = h5['data'] # it's ok, the dataset is not fetched to memory yet
n = data.shape[0] # how many rows we have in the dataset
chunk_size = 1000 # how many rows we feed to IPCA at a time, the divisor of n
ipca = IncrementalPCA(n_components=10, batch_size=16)
for i in range(0, n//chunk_size):
    ipca.partial_fit(data[i*chunk_size : (i+1)*chunk_size])

这似乎是为我工作,如果我看看什么top报告,内存分配保持在200M以下。

可以使用NumPy的memmap类,它允许操作a存储在磁盘二进制文件中的大数组,就好像它完全在内存中一样;类只在需要时在内存中加载所需的数据。由于incrementalPCA在任何给定时间都使用批处理,因此内存使用仍然处于控制之下。下面是一个示例代码

from sklearn.decomposition import IncrementalPCA
import numpy as np
X_mm = np.memmap(filename, dtype="float32", mode="readonly", shape=(m, n))
batch_size = m // n_batches
inc_pca = IncrementalPCA(n_components=10, batch_size=batch_size)
inc_pca.fit(X_mm)

相关内容

  • 没有找到相关文章

最新更新