使用sklearn和大亲和力矩阵进行光谱聚类

时间:2014-09-19 07:51:55

标签: python scikit-learn cluster-analysis eigenvector spectral

我正在尝试使用scikit-learn提供的谱聚类方法来聚合我的数据集的行( 16000)。 我的问题出现在我预先计算了亲和度矩阵(一个16000x16000浮点矩阵)之后,它或多或少地分配3千兆字节(我最多可以达到8 GB),使用argpack解算器调用该矩阵的方法需要更多的内存并且cpu在尝试将内存和内存交换时失去了太多时间,以至于计算速度变慢了。 我还尝试在方法之前调用垃圾收集器,但没有成功:

import gc
gc.collect()

如何获得正在进行的精确计划? 这是一个已知的问题?在python中是否有任何替代方案可以开箱即用地进行谱聚类?

如果需要,我可以发布一个最小的工作示例。

更新 关于lobpcg求解器,我错了,起初它似乎使用了我所有的记忆,但随后它稳定在5Gb附近并且过程继续,但另一个问题上升。 似乎计算导致一些数值不准确,最终产生Nans或像这样的错误(当亲和度矩阵稍微变化时,出现的错误会发生变化,见下文):

File "/usr/local/lib/python3.4/dist-packages/sklearn/cluster/spectral.py", line 255, in spectral_clustering
eigen_tol=eigen_tol, drop_first=False)
File "/usr/local/lib/python3.4/dist-packages/sklearn/manifold/spectral_embedding_.py", line 303, in spectral_embedding
largest=False, maxiter=2000)
File "/usr/local/lib/python3.4/dist-packages/scipy/sparse/linalg/eigen/lobpcg/lobpcg.py", line 449, in lobpcg
assert np.allclose(gramA.T, gramA)
AssertionError

我的亲和力度量标准是高斯内核exp(-((X_1 - x_2)^2/2*sigma^2)),并且在为sigma尝试不同的值时,结果会有很大差异。我可以理解,当某些条目接近零时会出现一些不准确的情况,但是当我使用sigma(= 5.0)的大值时,情况并非如此,而是将它们更接近1.0。

现在我假设我错过了一些观点,或者我在这个过程中做错了什么,所以我以新的目标更新了这个问题。

作为参考,这就是我计算亲和度矩阵的方法:

 pairwise_dists = \
      scipy.spatial.distance.squareform(
           scipy.spatial.distance.pdist(data_slice,'sqeuclidean'))
 similarity_matrix = scipy.exp(-pairwise_dists /(2 * self._sigma ** 2))

其中data_slice是一个numpy数组,其行是我的实例,self._sigma存储高斯sigma参数。

1 个答案:

答案 0 :(得分:1)

光谱聚类计算相异矩阵的特征向量。

此矩阵的大小为O(n ^ 2),因此任何实现几乎都需要O(n ^ 2)内存。

16000x16000x4(假设浮动存储,没有开销) 大约1 GB。它可能需要一个工作副本(诸如scipy.exp之类的方法可能会生成矩阵的副本;并且可能具有双精度)和一些开销,这就是为什么你最终使用3 GB ......

该算法不适用于大数据,就像任何其他需要O(n ^ 2)内存的算法一样。选择不同的算法;也许可以使用索引结构加速。或者减少数据集大小,例如通过采样。