посоветуйте как сделать кластеризацию (одномерного) списка целых чисел без заданого количества кластеров и вычислить коэффициент кластеризации
имеется список целых чисел (например от 0 do 32)
- нужно разделить на кластеры. количество кластеров неизвестно. максимум 4.
- вычислить коэффициент кластеризации (я назвал его xi)
Вообще-то это нужно для определения похожести наборов картинок из которых получаются числа(число пятен, углы наклона, длинны линий...)
Например:
- если в одном наборе количество пятен [2,3,3,3,5,5] а в другом [12,12,12,13,14,14] - то видно, что в первом мало пятен, а во втором много
- если в одном наборе количество пятен [10,12,12,14,14,15] а в другом [16,17,19,20,20,22] - то количество пятен не очень отличается, хотя во втором наборе больше...
хотелось бы разделить числа, максимум на 4 кластера, и вычислить коэффициент, который бы характеризовал кучность кластера, расстояние между кластерами...
я нарисовал гистограммы и примерно задал кэффициент кластеризации (по своему разумению)
Ответы (1 шт):
Автор решения: CrazyElf
→ Ссылка
Кластеризуйте на разное число кластеров, вычисляйте silhouette_score. Где максимум его - то число кластеров и оптимальное. Примерно такой может быть код:
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
import seaborn as sns
for data in [list(range(6,10))*5 + list(range(22,26))*5, list(range(2,6))*5 + list(range(12,16))*5 + list(range(22,30))*5]:
clusters = list(range(2, 5))
scores = []
clusters_centers = []
for k in clusters:
kmeans = KMeans(n_clusters=k).fit(list(zip(data)))
preds = kmeans.predict(list(zip(data)))
clusters_centers.append(kmeans.cluster_centers_)
scores.append(silhouette_score(list(zip(data)), preds))
s, k = max(zip(scores, clusters))
plt.figure();
sns.displot(data, bins=32);
for x in clusters_centers[clusters.index(k)]:
plt.plot([x[0],x[0]], [0,5], c='r', linestyle='--')
plt.figure();
sns.lineplot(clusters, scores);
plt.xlabel("Число кластеров");
plt.ylabel('silhouette_score');
plt.xticks(clusters);
plt.title(f'Максимальная мера {s:.3f} при {k} кластерах');
plt.plot(k, s, 'r*')








