我有数据形成一个1000 x 1e9形状的稀疏矩阵。我想使用K-means将1000个示例聚类为10个集群。
矩阵非常稀疏,小于1 / 1e6值。
我的笔记本电脑有16个RAM。我在scipy中尝试了稀疏矩阵。不幸的是,矩阵使聚类过程需要比我更多的内存。有人可以建议一种方法吗?
运行以下测试代码段时,我的系统崩溃了
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_
感谢任何有用的建议。
答案 0 :(得分:1)
KMeans中心不再稀疏,因此需要对稀疏情况进行仔细优化(对于通常的情况可能代价很高,因此可能不会以这种方式进行优化)。
你可以尝试ELKI(不是python而是Java),它通常要快得多,并且还有稀疏的数据类型。您也可以尝试使用单精度浮点数也会有所帮助。
但最终,结果将是值得怀疑的:k-means在统计上以最小二乘为根。它假设您的数据来自k个信号加上一些高斯误差。因为你的数据很稀疏,所以它显然没有这种高斯形状。当大多数值为0时,它不能是高斯值。
只有1000个数据点,我宁愿使用HAC。
答案 1 :(得分:0)
无论你做什么(对于你的数据;考虑到你的记忆限制): kmeans还没准备好!
这包括:
忽略潜在的理论原因(高维和非凸启发式优化)我只是在这里提到实际问题:
Worksheets("Sheet3").OLEObjects.Add filename:="C:\Users\myname\Desktop\" & fName, Link:=False, DisplayAsIcon:=False, Left:=40, Top:=40, Width:=150, Height:=10
即使您删除/关闭所有内存繁重的组件,例如:
center_shift_total = squared_norm(centers_old - centers)
(而不是init=some_sparse_ndarray
)
k-means++
代替n_init=1
10
代替precompute_distances=False
(不清楚是否有帮助)
True
代替n_jobs=1
以上将是你需要关心的问题!
答案 2 :(得分:0)
虽然KMeans
接受稀疏矩阵作为输入,但算法中使用的质心具有密集表示,并且您的特征空间非常大,甚至10个质心也不适合16GB的RAM。
我有两个想法:
sklearn.cluster.SpectralClustering
。您可以预先计算1000x1000矩阵中的成对距离,并将其传递给您的聚类算法。 (我不能对聚类方法做出具体建议,也不能根据你的应用提出合适的函数来计算距离)答案 3 :(得分:-2)
考虑使用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
定义为矩阵行的长度。