首页 文章

使用sklearn在大型稀疏矩阵上执行PCA

提问于
浏览
9

我试图在庞大的稀疏矩阵上应用PCA,在下面的链接中它表示sklearn的randomizedPCA可以处理scipy稀疏格式的稀疏矩阵 . Apply PCA on very large sparse matrix

但是,我总是得到错误 . 有人可以指出我做错了什么 .

输入矩阵'X_train'包含float64中的数字:

>>>type(X_train)
<class 'scipy.sparse.csr.csr_matrix'>
>>>X_train.shape
(2365436, 1617899)
>>>X_train.ndim 
2
>>>X_train[0]     
<1x1617899 sparse matrix of type '<type 'numpy.float64'>'
    with 81 stored elements in Compressed Sparse Row format>

我想做:

>>>from sklearn.decomposition import RandomizedPCA
>>>pca = RandomizedPCA()
>>>pca.fit(X_train)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/RT11/.pyenv/versions/2.7.9/lib/python2.7/site-packages/sklearn/decomposition/pca.py", line 567, in fit
    self._fit(check_array(X))
  File "/home/RT11/.pyenv/versions/2.7.9/lib/python2.7/site-packages/sklearn/utils/validation.py", line 334, in check_array
    copy, force_all_finite)
  File "/home/RT11/.pyenv/versions/2.7.9/lib/python2.7/site-packages/sklearn/utils/validation.py", line 239, in _ensure_sparse_format
    raise TypeError('A sparse matrix was passed, but dense '
TypeError: A sparse matrix was passed, but dense data is required. Use X.toarray() to convert to a dense numpy array.

如果我试图转换为密集矩阵,我想我已经失去了记忆 .

>>> pca.fit(X_train.toarray())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/RT11/.pyenv/versions/2.7.9/lib/python2.7/site-packages/scipy/sparse/compressed.py", line 949, in toarray
    return self.tocoo(copy=False).toarray(order=order, out=out)
  File "/home/RT11/.pyenv/versions/2.7.9/lib/python2.7/site-packages/scipy/sparse/coo.py", line 274, in toarray
    B = self._process_toarray_args(order, out)
  File "/home/RT11/.pyenv/versions/2.7.9/lib/python2.7/site-packages/scipy/sparse/base.py", line 800, in _process_toarray_args
    return np.zeros(self.shape, dtype=self.dtype, order=order)
MemoryError

2 回答

  • 1

    由于PCA的性质,即使输入是稀疏矩阵,输出也不是 . 你可以用一个简单的例子来检查它:

    >>> from sklearn.decomposition import TruncatedSVD
    >>> from scipy import sparse as sp
    

    创建一个随机稀疏矩阵,其0.01%的数据为非零 .

    >>> X = sp.rand(1000, 1000, density=0.0001)
    

    将PCA应用于它:

    >>> clf = TruncatedSVD(100)
    >>> Xpca = clf.fit_transform(X)
    

    现在,检查结果:

    >>> type(X)
    scipy.sparse.coo.coo_matrix
    >>> type(Xpca)
    numpy.ndarray
    >>> print np.count_nonzero(Xpca), Xpca.size
    95000, 100000
    

    这表明95000个条目不为零,但是,

    >>> np.isclose(Xpca, 0, atol=1e-15).sum(), Xpca.size
    99481, 100000
    

    99481个元素 are 接近 0<1e-15 ),但 not 0 .

    简而言之,这意味着,对于PCA,即使输入是稀疏矩阵,输出也不是 . 因此,如果您尝试从矩阵中提取100,000,000( 1e8 )个组件,最终会得到 1e8 x n_features (在您的示例中为 1e8 x 1617899 )密集矩阵,当然,它不能保留在内存中 .

    我不是专家统计学家,但我相信目前没有使用scikit-learn的工作方式,因为scikit-learn的实现不是问题,只是他们稀疏PCA的数学定义(通过稀疏SVD)这使得结果密集 .

    可能对您有用的唯一解决方法是让您从少量组件开始,然后增加它,直到您可以保留在内存中的数据与所解释数据的百分比之间取得 balancer (您可以计算如下):

    >>> clf.explained_variance_ratio_.sum()
    
  • 11

    PCA(X)是SVD(X-均值(X)) . 即使X是稀疏矩阵,X均值(X)也总是密集矩阵 . 因此,随机化SVD(TruncatedSVD)不像稀疏矩阵的随机SVD那样有效 . 但是,延迟评估

    延迟(X-平均值(X))

    可以避免将稀疏矩阵X扩展到密集矩阵X-均值(X) . 延迟评估使用随机化SVD实现稀疏矩阵的有效PCA .

    这个机制在我的包中实现:
    https://github.com/niitsuma/delayedsparse/

    您可以使用此机制查看PCA的代码:https://github.com/niitsuma/delayedsparse/blob/master/delayedsparse/pca.py

    与现有方法的性能比较表明,这种机制大大减少了所需的内存大小:https://github.com/niitsuma/delayedsparse/blob/master/demo-pca.sh

    有关此技术的更多详细说明,请参阅我的专利:https://patentscope2.wipo.int/search/ja/detail.jsf?docId=JP225380312

相关问题