k-means векторов документа после BERT

Я трансформировал через БЕРТ некоторое количество предложений(документов) и получил их векторы. Теперь мне нужно построить следующий алгоритм.

  1. Создаю центроиды и с k-means кластеризацию документы
  2. Получаю новые вектора для следующего цикла. Для этого из вектора i вычитаю среднее значение векторов его кластера и получаю новый i
  3. Генерирую новые случайные центроиды и повторяю 1,2, n раз

Учитель сказал, что по итогу должно выполняться два свойства

  1. mse между вектором и его новым вектором (после вычитания среднего кластера(шаг 2)) должен уменьшаться.
  2. Для документа сумма его средних значений кластеров к которым он был определен за n этапов должна в теории быть приблизительна равна изначальному вектору документа.

Проблема в том, что

  1. mse действительно уменьшается, но только несколько этапов, после оно снова растет

  2. никогда сумма средних кластеров не равнялась вектору документа, даже приблизительно

  3. имея 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  
    

Ответы (0 шт):