from nltk.metrics import distance
import scipy.spatial as spatial
import numpy as np
from scipy.cluster.vq import kmeans
# sample vocabulary list
words = ['test', 'text', 'best', 'fast', 'context', 'boost', 'faster', 'border']
# similarity matrix
word_vectors = np.array([
[
distance.edit_distance(w, _w)
for _w in words
]
for w in words
], dtype=np.float)
centroids, _ = kmeans(word_vectors, k_or_guess=3)
word_clusters = np.argmin([
[spatial.distance.euclidean(wv, cv) for cv in centroids]
for wv in word_vectors
], 1)
for k in range(centroids.shape[0]):
print('k =', k)
print([word for i, word in enumerate(words) if word_clusters[i] == k])
Результат:
k = 0
['faster', 'border']
k = 1
['test', 'text', 'best', 'fast', 'boost']
k = 2
['context']
Примечания:
- Оригинальный словарь работает как список функций.Список мер расстояния до других слов работает как вектор признаков для любой фразы или слова.
- Каждый кластер выполнен в таком функциональном пространстве.Следовательно, расстояние между двумя словами больше не является их расстоянием Левенштейна, а их расстоянием в таком пространстве.Вот почему мы используем другие меры, такие как
spatial.distance.euclidean
. - Kmean создает центроиды в этом пространстве признаков, каждое слово рассматривается как член кластера, если центроид кластера находится ближе всего к слову (извсе остальные центроиды).
np.argmin([...], 1)
находит такое присваивание для каждого слова. - Другие алгоритмы кластеризации также могут быть проверены в пространстве слов-признаков.(Список некоторых алгоритмов кластеризации в scikit-learn: https://scikit -learn.org / stable / modules / clustering.html )