Sklearn.KMeans:如何避免内存或值错误?

7
我正在处理一个图像分类问题,正在创建一个词袋模型。为此,我提取了所有图片的SIFT描述符,并且需要使用KMeans算法来找到中心作为我的词袋。
以下是我的数据: - 图像数量:1584 - SIFT描述符数量(32个元素向量):571685 - 中心数量:15840
因此,我运行了KMeans算法来计算我的中心。
dico = pickle.load(open('./dico.bin', 'rb')) # np.shape(dico) = (571685, 32)
k = np.size(os.listdir(img_path)) * 10 # = 1584 * 10

kmeans = KMeans(n_clusters=k, n_init=1, verbose=1).fit(dico)

pickle.dump(kmeans, open('./kmeans.bin', 'wb'))
pickle.dump(kmeans.cluster_centers_, open('./dico_reduit.bin', 'wb'))

使用这段代码时,由于我的笔记本电脑内存仅为2GB,因此我遇到了内存错误,所以我决定将中心数量除以2,并随机选择一半的SIFT描述符。然而这次,我得到了一个值错误:数组太大

我该如何在不出现内存问题的情况下得到相关结果?


展示 dico 的形状。(因为我对您的帖子中的数字有些困惑;但我没有使用词袋模型的经验) - sascha
我在代码中添加了信息。理解词袋模型的工作原理是无用的,它只是为了提供上下文。 - Pierre
1
好的。因此,支配维度是样本维度(而不是特征维度)。这意味着,您可以使用一些在线kmeans算法,例如MiniBatchKMeans。每次迭代中,只有n=batch_size会在内存中读取,而不是将所有内容读入内存。 - sascha
那正是我所需要的。如果您愿意,可以添加一个答案。 - Pierre
1个回答

9

正如@sascha在评论中所说,我只需使用MiniBatchKMeans 类来避免这个问题:

dico = pickle.load(open('./dico.bin', 'rb'))

batch_size = np.size(os.listdir(img_path)) * 3
kmeans = MiniBatchKMeans(n_clusters=k, batch_size=batch_size, verbose=1).fit(dico)

pickle.dump(kmeans, open('./minibatchkmeans.bin', 'wb'))

你如何设置批量大小? - Nicolas Gervais
@NicolasGervais 使用 batch_size 参数 - Pierre
你如何做决定? - Nicolas Gervais
@NicolasGervais 这个问题在这里讨论:https://stats.stackexchange.com/questions/398757/how-to-determine-the-best-batch-size-value-for-mini-batch-k-means-algorithm 显然,没有魔法解决方案,你将不得不迭代查找最佳值。 - Pierre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接