kha*_*san 14 python sparse-matrix svd pca scikit-learn
我试图在巨大的稀疏矩阵上应用PCA,在下面的链接中它说sklearn的randomizedPCA可以处理scipy稀疏格式的稀疏矩阵. 在非常大的稀疏矩阵上应用PCA
但是,我总是得到错误.有人可以指出我做错了什么.
输入矩阵'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>
Run Code Online (Sandbox Code Playgroud)
我想做:
>>>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.
Run Code Online (Sandbox Code Playgroud)
如果我试图转换为密集矩阵,我想我已经失去了记忆.
>>> 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
Run Code Online (Sandbox Code Playgroud)
Ima*_*ngo 14
由于PCA的性质,即使输入是稀疏矩阵,输出也不是.你可以用一个简单的例子来检查它:
>>> from sklearn.decomposition import TruncatedSVD
>>> from scipy import sparse as sp
Run Code Online (Sandbox Code Playgroud)
创建一个随机稀疏矩阵,其0.01%的数据为非零.
>>> X = sp.rand(1000, 1000, density=0.0001)
Run Code Online (Sandbox Code Playgroud)
将PCA应用于它:
>>> clf = TruncatedSVD(100)
>>> Xpca = clf.fit_transform(X)
Run Code Online (Sandbox Code Playgroud)
现在,检查结果:
>>> type(X)
scipy.sparse.coo.coo_matrix
>>> type(Xpca)
numpy.ndarray
>>> print np.count_nonzero(Xpca), Xpca.size
95000, 100000
Run Code Online (Sandbox Code Playgroud)
这表明95000个条目非零,但是,
>>> np.isclose(Xpca, 0, atol=1e-15).sum(), Xpca.size
99481, 100000
Run Code Online (Sandbox Code Playgroud)
99481个元件是靠近0(<1e-15),但不 0.
简而言之,这意味着,对于PCA,即使输入是稀疏矩阵,输出也不是.因此,如果您尝试1e8从矩阵中提取100,000,000()组件,最终会得到1e8 x n_features(在您的示例中1e8 x 1617899)密集矩阵,当然,它不能保存在内存中.
我不是专家统计学家,但我相信目前没有使用scikit-learn的工作方法,因为scikit-learn的实现不是问题,只是他们稀疏PCA的数学定义(通过稀疏SVD)这使得结果密集.
可能对您有用的唯一解决方法是让您从少量组件开始,然后增加它,直到您可以保留在内存中的数据与所解释数据的百分比之间取得平衡(您可以计算如下):
>>> clf.explained_variance_ratio_.sum()
Run Code Online (Sandbox Code Playgroud)
小智 7
PCA(X) 是 SVD(X-mean(X))。即使 X 是稀疏矩阵,X-mean(X) 也始终是稠密矩阵。因此,随机 SVD(TruncatedSVD) 的效率不如稀疏矩阵的随机 SVD。但评估延迟
延迟(X-平均值(X))
可以避免将稀疏矩阵X扩展到稠密矩阵X-mean(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
| 归档时间: |
|
| 查看次数: |
14158 次 |
| 最近记录: |