如何在Python中使用低内存对非常大的稀疏数据集进行集群?
我的数据形成了一个1000 x 1e9形状的稀疏矩阵。我想使用K-means将1000个示例分为10个集群 矩阵非常稀疏,小于1/1e6值 我的笔记本电脑有16个内存。我在scipy中尝试了稀疏矩阵。不幸的是,矩阵使得聚类过程需要比我多得多的内存。有人能提出一个方法吗 我的系统在运行以下测试代码段时崩溃如何在Python中使用低内存对非常大的稀疏数据集进行集群?,python,cluster-analysis,Python,Cluster Analysis,我的数据形成了一个1000 x 1e9形状的稀疏矩阵。我想使用K-means将1000个示例分为10个集群 矩阵非常稀疏,小于1/1e6值 我的笔记本电脑有16个内存。我在scipy中尝试了稀疏矩阵。不幸的是,矩阵使得聚类过程需要比我多得多的内存。有人能提出一个方法吗 我的系统在运行以下测试代码段时崩溃 import numpy as np from scipy.sparse import csr_matrix from sklearn.cluster import KMeans row =
import numpy as np
from scipy.sparse import csr_matrix
from sklearn.cluster import KMeans
row = np.array([0, 0, 1, 2, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 8])
col = np.array([0, 2, 2, 0, 1, 2] * 3)
data = np.array([1, 2, 3, 4, 5, 6] * 3)
X = csr_matrix((data, (row, col)), shape=(9, 1e9))
resC = KMeans(n_clusters=3).fit(X)
resC.labels_
任何有帮助的建议都将不胜感激。考虑使用
dict
,因为它只存储分配的值。我想一个很好的方法是创建一个SparseMatrix
对象,如下所示:
class SparseMatrix(dict):
def __init__(self, mapping=[]):
dict.__init__(self, {i:mapping[i] for i in range(len(mapping))})
#overriding this method makes never-accessed indexes return 0.0
def __getitem__(self, i):
try:
return dict.__getitem__(self, i)
except KeyError:
return 0.0
>>> my_matrix = SparseMatrix([1,2,3])
>>> my_matrix[0]
1
>>> my_matrix[5]
0.0
编辑:
对于多维情况,您可能需要覆盖以下两种项目管理方法:
def __getitem__(self, ij):
i,j = ij
dict.__setitem__(i*self.n + j)
def __getitem__(self, ij):
try:
i,j = ij
return dict.__getitem__(self, i*self.n + j)
except KeyError:
return 0.0
>>> my_matrix[0,0] = 10
>>> my_matrix[1,2]
0.0
>>> my_matrix[0,0]
10
还假设您将self.n
定义为矩阵行的长度。无论您做什么(对于您的数据;考虑到您的内存限制):kmeans还没有准备好强>
这包括:
- 在线KMeans/小批量KMeans;正如在另一份答复中提出的那样
- 它只会帮助处理许多样本(并且会受到后面提到的相同效果的影响)李>
- 不同语言中的各种KMeans实现(这是一个算法问题;不受实现的约束)
- 您的质心可能会变得不稀疏!(在中提到;此链接还提到了备选方案!)
- 这意味着:使用的稀疏数据结构将变得非常不稀疏,最终会耗尽您的内存李>
- (我更改了sklearn的代码,以观察上面的链接已经提到的内容)
- 相关sklearn代码:
center\u shift\u total=squared\u norm(centers\u old-centers)
- 相关sklearn代码:
(而不是init=一些稀疏数组
)k-means++
而不是n_init=1
10
而不是precompute\u distance=False
(如果有帮助,则不清楚)True
而不是n_jobs=1
-1
以上将是您需要关注的问题 尽管
KMeans
接受稀疏矩阵作为输入,但算法中使用的质心具有密集表示,而且您的特征空间非常大,即使10个质心也无法容纳16GB的RAM
我有两个想法:
sklearn.cluster.spectrcalClustering
。您可以在1000x1000矩阵中预先计算成对距离,并将其传递给集群算法。(我无法具体推荐聚类方法或合适的函数来计算距离,因为这取决于您的应用程序)KMeans中心将不再是稀疏的,因此这需要对稀疏情况进行仔细的优化(通常情况下这可能会很昂贵,因此可能不会以这种方式进行优化) 您可以尝试ELKI(不是python而是Java),它通常速度更快,而且数据类型稀疏。您也可以尝试使用单精度浮点也会有所帮助 但最终,结果将是值得怀疑的:k-均值在统计学上是以最小二乘法为基础的。它假设您的数据来自k个信号加上一些高斯误差。因为你的数据是稀疏的,它显然没有这种高斯形状。当大多数值为0时,它不能是高斯分布
只有1000个数据点,我宁愿使用HAC。他已经在使用基于scipy的设置,其中有许多高质量的稀疏矩阵数据结构可用,并由sklearn的kmeans支持。所以这个答案在我看来没有多大帮助。谢谢你的回答和解释。你认为还有其他聚类方法适合我吗?如果k-means在我的情况下不好,我想用另一个。谢谢myrtlecat。由于不同的示例可能获得不同的特性值,第二种解决方案应该是一种变通方法。