当前位置: 首页 > 面试题库 >

大数据增量PCA

高宏峻
2023-03-14
问题内容

我只是尝试使用sklearn.decomposition中的IncrementalPCA,但它像以前的PCA和RandomizedPCA一样引发了MemoryError。我的问题是,我要加载的矩阵太大,无法放入RAM。现在,它以形状〜(1000000,1000)的数据集形式存储在hdf5数据库中,因此我有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

感谢帮助


问题答案:

您的程序可能无法尝试将整个数据集加载到RAM中。每个float32 32×1,000,000×1000 32位为3.7 GiB。在只有4 GiB
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以下。



 类似资料:
  • Sql Delta表和Database ricks Delta表有区别吗?看起来SQL我们在概念的基础上使用这个名字。存储Base表差异的表是Delta。对于数据库是一样的吗?

  • 如何使用数据砖增量从其他表中更新表中的多个记录。 我想达到这样的目标: 它失败并出现错误:不匹配的输入“发件人”期望

  • hive怎么进行增量更新呢?看到很多人是先分区例如根据create_time分区。每天根据create_time 新增数据。但是如果我的数据是会经常变动的呢?例如去年的数据,今年修改了。我应该如何更新这条数据进去。假设我现在数据是上亿的,应该怎么处理。 假设数据初始数据: 1 2024-08-10 15:18:00.000 wang 2 2024-08-10 15:18:00.000 xxx 3

  • 我创建了一个向MySql数据库插入数百万个值的程序。我读到过有关批插入的文章,它将优化我的程序并使其更快,但当我尝试这样做时,它以同样的方式工作。我没有将每个值插入数据库,而是每次将500个值保存在一个列表中,然后将它们插入一个大循环中,如下所示: 然后我删除列表中的所有值,并再次开始收集500个值。它不应该工作得更好吗? 我的插入代码是: 我有一些问题: 1。为什么当我批量插入时它不能更快地工作

  • 本文向大家介绍mysql批量删除大量数据,包括了mysql批量删除大量数据的使用技巧和注意事项,需要的朋友参考一下 mysql批量删除大量数据 假设有一个表(syslogs)有1000万条记录,需要在业务不停止的情况下删除其中statusid=1的所有记录,差不多有600万条, 直接执行 DELETE FROM syslogs WHERE statusid=1 会发现删除失败,因为lock wai

  • 我使用Firebase实时数据库作为后端。我希望每个请求最多增加1个。例如: 这不管用。 在前端,我发送“数据1”。我应该如何创建“.validate”规则?