Я пытаюсь реализовать кластеризацию kmeans в Java, и она не возвращает правильные результаты.
У меня есть 3 папки, каждая из которых содержит 8 связанных документов (всего 24 документа), и я пытаюсь использовать KMeans для их кластеризации.Я предварительно обрабатываю данные, а затем строю матрицу частот слова и использую ее для построения матрицы tf-idf.Я чувствую себя довольно хорошо с моей матрицей, потому что, когда я прошу ее выложить самые распространенные слова (т.е. ключевые слова для папки), я получаю хорошие результаты.
Однако, когда я добавляю матрицу в мои KMeans с k = 3, я никогда не получаю правильный результат (а иногда получаю 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;
}
Что мне не хватает?
Любая помощь будет принята с благодарностью.