k-means векторов документа после BERT
Я трансформировал через БЕРТ некоторое количество предложений(документов) и получил их векторы. Теперь мне нужно построить следующий алгоритм.
- Создаю центроиды и с k-means кластеризацию документы
- Получаю новые вектора для следующего цикла. Для этого из вектора i вычитаю среднее значение векторов его кластера и получаю новый i
- Генерирую новые случайные центроиды и повторяю 1,2, n раз
Учитель сказал, что по итогу должно выполняться два свойства
- mse между вектором и его новым вектором (после вычитания среднего кластера(шаг 2)) должен уменьшаться.
- Для документа сумма его средних значений кластеров к которым он был определен за n этапов должна в теории быть приблизительна равна изначальному вектору документа.
Проблема в том, что
mse действительно уменьшается, но только несколько этапов, после оно снова растет
никогда сумма средних кластеров не равнялась вектору документа, даже приблизительно
имея 256 кластеров на 4000 документов через несколько этапов количество кластеров почти всегда становится 2 и не изменяется, а на первом этапа без точки могут сидеть до 150 центроидов
//Создаю центроиды 256 x 768 первый этап //edistrix - вектор документов после BERT for i in range(0, 4000): min_dist = 100000 for j in range (0,256): dist = np.linalg.norm(edistrix[i] - start_centroids[j]) if rass < min_dist: min_dist = dist centr[i] = j // centr - номер ближайшего центроида к вектору i cluster_p[int(centr[i])]+=1 // количество точек кластера cluster_sum[int(centr[i])] += edistrix[i] // сумма векторов кластера near_cluster_etapa[0] = centr // ближайший центроид, но для каждого этапа //other stages for n in range(0, 7): // количество этапов for i in range(0, 256): // считаем среднее кластеров if cluster_p[i] != 0: centr_centroidov[n][i] = np.divide(cluster_sum[i], cluster_p[i]) for i in range(0, 4000): Dif = edistrix[i] - centr_centroidov[n][int(near_cluster_etapa[n][i])] //разница между вектором и средним его кластера sred[i][n] = ((edistrix[i] - Dif)**2).mean(axis=None) // mse между вектором и его разницей edistrix[i] = Dif // вектор i для следующего этапа как его разница all_doc_koord[i][n+1] = edistrix[i] //generate new centroids //reset to zero the number of points and the sum of the cluster vectors and nearest centroid of the vector (cluster_p, cluster_sum, centr) //again k-means for i in range(0,4000): min_dist = 100000 for j in range (0,256): dist = np.linalg.norm(edistrix[i][0] - start_centroids[j]) if dist < min_dist: min_dist = dist centr[i] = j cluster_p[int(centr[i])]+=1 cluster_sum[int(centr[i])] += edistrix[i][0] near_cluster_etapa[n+1] = centr //проверяю свойства /1 for i in range(0, 7): print('{0:.10f}'.format(sred[0][i]) ) // for i documents print all mse /2 summ = 0 for i in range (0,7): summ += centr_centroidov [i][int(near_cluster_etapa[i][0])] //folding the average of the cluster from stages for 0 (first) document summ