我试图在Java中实现kmeans集群,但未返回正确的结果。
我有3个文件夹,每个文件夹包含8个相关文档(总共24个文档),并且正在尝试使用KMeans对其进行聚类。我对数据进行预处理,然后构建一个词频矩阵,并使用它来构建tf-idf矩阵。我对矩阵感觉很好,因为当我要求它吐出最常用的单词(即文件夹的关键字)时,我会得到很好的结果。
但是,当我将矩阵放入k = 3的KMeans中时,我永远得不到正确的结果(有时会得到2个簇)。
我的主要功能是:
public void kmeans() {
// randomly fill centroids
randomlyFillCentroids();
double threshhold = 0.001;
int iteration = 0;
double[][] iterCentroids = centroids;
do {
// set centroids to previous results
centroids = iterCentroids;
// assignLabels each point to the closest centroid
assignLabels();
// updateCentroids
iterCentroids = updateCentroids();
iteration++;
} while (!stopCondition(iteration, threshhold, iterCentroids));
}
然后,我在以下位置分配标签:
private void assignLabels() {
for (int i = 0; i < numDocuments; i++) {
double minDistance = Double.POSITIVE_INFINITY;
int minJ = 0;
for (int j = 0; j < k; j++) {
double distance = distance(data[i], centroids[j]);
if (distance < minDistance) {
minDistance = distance;
minJ = j;
}
}
label[i] = minJ;
}
}
距离是余弦距离。
然后我更新质心:
private double[][] updateCentroids() {
double[][] tempCentroids = new double[k][numWords]; // 3 x 64
int[] tally = new int[k];
// initialize to zero
for (int i = 0; i < k; i++) {
tally[i] = 0;
for (int j = 0; j < numWords; j++) {
tempCentroids[i][j] = 0.0;
}
}
// do the sums
for (int i = 0; i < numDocuments; i++) {
int value = label[i]; // get the document's label (0, 1, 2)
for (int j = 0; j < numWords; j++) {
tempCentroids[value][j] += data[i][j];
}
tally[value]++;
}
// get the average
for (int i = 0; i < k; i++) {
for (int j = 0; j < numWords; j++) {
tempCentroids[i][j] /= tally[i];
}
}
return tempCentroids;
}
我想念什么?
任何人和所有帮助将不胜感激。