我有具有二进制特征的点:
id, feature 1, feature 2, ....
1, 0, 1, 0, 1, ...
2, 1, 1, 0, 1, ...
矩阵的大小约为20k*200k,但它是稀疏的。我使用Mahout通过kmeans算法对数据进行聚类,并有以下问题:
- kmean是二进制特征的好候选者吗
- 在保持曼哈顿距离测量的概念的同时,有什么方法可以减少尺寸吗(我需要曼哈顿,而不是Cosine或Tanimoto)
- kmean的内存使用率很高,每个Map/Reduce任务需要4GB内存(3k集群的400Mb矢量文件上的4Mb块)。考虑到Mahout中的Vector对象使用双条目,有没有办法只对点使用布尔条目,而对中心使用双条目
k-means是一个很好的候选者,如果你有一个好的距离度量。曼哈顿的距离可能很好;我喜欢对数似然。
您可以使用任何您喜欢的降维技术。我喜欢交替最小二乘法;SVD也工作得很好。对于这个大小矩阵,您可以使用Commons Math在内存中轻松地完成它,而不用使用Hadoop——这太过分了。
(另请参阅http://myrrix.com--我有一个非常快速的ALS实现,您可以在核心/在线模块中重复使用。它可以在几十MB的堆中在几秒钟内处理这个问题。)
特征矩阵中不再包含二进制0/1值。在特征空间中,余弦距离应该很好(1-余弦相似性)。Tanimoto/Jaccard不合适。
k-means有一个经常被忽视的大要求:它需要计算一个合理的均值。这比人们想象的要重要得多。
- 如果平均值不减少方差,它可能不会收敛(算术平均值对于欧几里得距离是最优的。对于曼哈顿,中值据说更好。对于非常不同的度量,我不知道)
- 平均值可能不再那么稀疏了
- 平均值也不再是二进制向量
此外,特别是对于大型数据集,您希望使用哪个k?
你真的应该研究一下其他的距离测量方法。您的数据大小并没有那么大;使用一台计算机就足够了。使用紧凑的矢量表示,它将很容易适应主内存。只是不要使用先计算n^2相似性矩阵的东西。也许可以尝试一些二元向量相似性的索引。
k-means相当容易实现,特别是如果你不做任何预先播种的话。要减少内存使用,只需为数据的最佳表示形式自己实现即可。它可以是一个位集,也可以是非零维度的排序列表。曼哈顿距离可以归结为计算向量不同的维度的数量!