【问题标题】:Spectral clustering with sklearn and a big affinity matrix使用 sklearn 和大亲和矩阵的光谱聚类
【发布时间】:2014-11-13 18:06:47
【问题描述】:

我正在尝试使用scikit-learn 提供的谱聚类方法来聚合我的数据集的行( 16000)。 在我预先计算了或多或少分配 3 GB(我最多可以达到 8 GB)的亲和矩阵(16000x16000 浮点矩阵)之后出现了我的问题,使用 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 参数。

【问题讨论】:

  • 您是否尝试过使用缩减的子集,比如 10x10、100x100、1Kx1K? Spectral 基于特征向量的计算,这是一项繁重的操作。从小数据集到大数据集可以帮助您计算出原始数据集的预期时间。
  • 我尝试过使用合成的小型数据集(200-400 行),但不是渐进式的。的确,我可以确定一个可行的维度,但我找不到在原始数据集上使用谱聚类的解决方案(也没有确切的问题)
  • 你能说哪个操作是交换的吗?可能可以使用不同的特征求解器或使用 float32。为什么在标题中说“内存过多”?您存储用于进行特征分解的矩阵的内存不到三倍。这似乎并没有大错特错。你想获得多少个集群?如果集群很少,则应该只需要很少的特征向量。
  • 顺便说一句,您是否尝试过其他聚类或降维方法?
  • @AndreasMueller 如何降维?

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


【解决方案1】:

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

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

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

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

【讨论】:

  • 据我了解,问题是“如果相异矩阵为 3gb,为什么它不适用于 8gb ram”但也许我误解了。
  • 我更新了问题。更改 eigensolver 可以缓解内存问题,但会引入数值错误,我想知道我是否做错了什么。
  • 为了节省内存,可以(原则上)即时计算矩阵对向量的作用,并在迭代方法中使用它来计算特征向量。那么一个人只需要 O(n) 内存,但需要更多的时间。
猜你喜欢
  • 2016-01-19
  • 2017-12-18
  • 2018-10-30
  • 2018-05-01
  • 2015-06-07
  • 2014-12-18
  • 2017-03-02
  • 2017-12-01
  • 2016-11-26
相关资源
最近更新 更多