Python 基于sklearn和大亲和矩阵的谱聚类

Python 基于sklearn和大亲和矩阵的谱聚类,python,scikit-learn,cluster-analysis,eigenvector,spectral,Python,Scikit Learn,Cluster Analysis,Eigenvector,Spectral,我正在尝试使用提供的光谱聚类方法来聚合我的数据集的行(只有行16000行)。 我的问题出现在我使用argpack解算器预计算亲和矩阵(16000x116000浮点矩阵)后,该矩阵分配了大约3g字节(最多可达8gb),该矩阵上调用的方法,需要更多的内存,cpu在尝试交换内存中的内容时损失了太多时间,以至于计算速度减慢到了极限。 我还尝试在方法之前调用垃圾收集器,但没有成功: import gc gc.collect() 我怎样才能得到正在发生的事情的确切计划? 这是一个已知的问题吗?python

我正在尝试使用提供的光谱聚类方法来聚合我的数据集的行(只有16000行)。 我的问题出现在我使用argpack解算器预计算亲和矩阵(16000x116000浮点矩阵)后,该矩阵分配了大约3g字节(最多可达8gb),该矩阵上调用的方法,需要更多的内存,cpu在尝试交换内存中的内容时损失了太多时间,以至于计算速度减慢到了极限。 我还尝试在方法之前调用垃圾收集器,但没有成功:

import gc
gc.collect()
我怎样才能得到正在发生的事情的确切计划? 这是一个已知的问题吗?python中是否有其他现成的方法来执行光谱聚类

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

更新 关于lobpcg解算器,我错了,一开始它似乎使用了我所有的内存,但随后它稳定在5Gb左右,过程继续,但另一个问题出现了。 似乎计算会导致一些数值不准确,最终会产生NAN或类似的错误(当亲和矩阵稍微改变时,出现的错误会发生变化,请参见下文):

我的亲和性度量是一个高斯核
exp(-(X_1-X_2)^2/2*σ^2))
,当尝试不同的σ值时,结果会有很大差异。我可以理解,当某些条目接近于零时,可能会出现一些不准确的情况,但当我使用较大的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\u slice
是一个numpy数组,其行是我的实例,
self.\u sigma
存储高斯sigma参数。

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

这个矩阵的大小是O(n^2),因此几乎所有的实现都需要O(n^2)内存

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


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

您是否尝试过使用减少的子集,比如10x10、100x100、1Kx1K?频谱分析是基于特征向量的计算,这是一项繁重的操作。从一个小数据集到一个大数据集可以帮助您计算出原始数据集的预期时间。我尝试过使用合成小数据集(200-400行),但不是以渐进的方式。的确,我可以确定一个可行的维度,但我找不到在原始数据集上使用光谱聚类的解决方案(也找不到到底出了什么问题)。你能说哪个操作是交换吗?可以使用不同的特征解算器或使用float32。你为什么在标题中说“记忆太多”?你只有不到三倍的内存来存储矩阵进行特征分解。这似乎并不是大错特错。你想得到多少个集群?如果只有很少的簇,那么只需要很少的特征向量。顺便说一句,你有没有尝试过其他的簇或降维方法?@AndreasMueller降维在这里有什么帮助?正如我所理解的,问题是“如果相异矩阵是3gb,为什么8gb ram不能工作?”但也许我误解了。我更新了问题。更改本征解算器可以缓解内存问题,但会引入数值错误,我想知道我是否做错了什么。为了节省内存,可以(原则上)动态计算矩阵对向量的作用,并在迭代方法中使用它来计算本征向量。那么一个人只需要O(n)内存,但需要更多的时间。
 pairwise_dists = \
      scipy.spatial.distance.squareform(
           scipy.spatial.distance.pdist(data_slice,'sqeuclidean'))
 similarity_matrix = scipy.exp(-pairwise_dists /(2 * self._sigma ** 2))