Кластеризація без нагляду з невідомою кількістю кластерів


79

У мене великий набір векторів у 3 вимірах. Мені потрібно згрупувати їх на основі евклідової відстані таким чином, щоб усі вектори в будь-якому конкретному скупченні мали евклідову відстань між собою менше, ніж поріг "Т".

Я не знаю, скільки кластерів існує. Зрештою, можуть існувати окремі вектори, які не є частиною будь-якого кластера, оскільки його евклідова відстань не менше "Т" з будь-яким із векторів у просторі.

Які існуючі алгоритми / підхід слід використовувати тут?


5
Обов’язково подивіться DBSCANна Вікіпедію.
Вийшов - Аноні-Мус

@ Anony-Mousse Будь-яка ідея, як я можу отримати представників кластерів від DBSCAN?
Divij Sehgal

Кластери DBSCAN можуть мати довільну форму. Що б тоді було хорошим «представником»?
Вийшов - Аноні-Мус

Відповіді:


79

Ви можете використовувати ієрархічну кластеризацію . Це досить базовий підхід, тому існує безліч реалізацій. Він, наприклад, включений до Python's scipy .

Дивіться, наприклад, такий сценарій:

import matplotlib.pyplot as plt
import numpy
import scipy.cluster.hierarchy as hcluster

# generate 3 clusters of each around 100 points and one orphan point
N=100
data = numpy.random.randn(3*N,2)
data[:N] += 5
data[-N:] += 10
data[-1:] -= 20

# clustering
thresh = 1.5
clusters = hcluster.fclusterdata(data, thresh, criterion="distance")

# plotting
plt.scatter(*numpy.transpose(data), c=clusters)
plt.axis("equal")
title = "threshold: %f, number of clusters: %d" % (thresh, len(set(clusters)))
plt.title(title)
plt.show()

Що дає результат, подібний до наступного зображення. скупчення

Поріг, вказаний як параметр, є значенням відстані, на основі якого приймається рішення, чи точки / кластери будуть об'єднані в інший кластер. Також можна вказати метрику відстані, яка використовується.

Зверніть увагу, що існують різні методи для обчислення подібності всередині / між кластерами, наприклад відстань між найближчими точками, відстань між найвіддаленішими точками, відстань до центрів кластера тощо. Деякі з цих методів також підтримуються модулем ієрархічної кластеризації scipys ( одинарний / повний / середній ... зв’язок ). Відповідно до Вашого допису, я думаю, Ви хотіли б використовувати повний зв'язок .

Зверніть увагу, що цей підхід також дозволяє малими (одноточковими) кластерами, якщо вони не відповідають критерію подібності інших кластерів, тобто пороговій відстані.


Існують інші алгоритми, які будуть працювати ефективніше, що стане актуальним у ситуаціях з великою кількістю точок даних. Як припускають інші відповіді / коментарі, ви можете також поглянути на алгоритм DBSCAN:


Для гарного огляду цих та інших алгоритмів кластеризації також загляньте на цю демонстраційну сторінку (бібліотеки scikit-learn від Python):

Зображення скопійовано з цього місця:

http://scikit-learn.org/stable/auto_examples/cluster/plot_cluster_comparison.html

Як бачите, кожен алгоритм робить деякі припущення щодо кількості та форми кластерів, які потрібно враховувати. Будь то неявні припущення, нав'язані алгоритмом, або явні припущення, задані параметризацією.


Але такий спосіб кластеризації не дозволяє існувати сиротам-векторам, чи не так? Згідно з умовами, про які я писав тут, якщо існує вектор, який не має евклідової відстані менше "Т" з будь-яким іншим вектором у просторі, то його слід залишити в спокої. Сподіваюся, це зрозуміло - вибачте, якщо це не було висловлено раніше.
Лондонський хлопець,

1
@AbhishekShivkumar - див. Мою редакцію. Звичайно, можуть бути одноточкові кластери.
moooeeeep

як тоді хтось знаходить центри скупчень?
Euler_Salter

@Euler_Salter Ви сортуєте за кластерами, групуєте за кластерами, потім обчислюєте середні / середні координати по точках для кожного кластера.
moooeeeep

21

Відповідь moooeeeep рекомендував використовувати ієрархічну кластеризацію. Я хотів детальніше розповісти, як вибрати поріг кластеризації.

Одним із способів є обчислення кластеризації на основі різних порогових значень t1 , t2 , t3 , ..., а потім обчислення метрики для "якості" кластеризації. Передумовою є те, що якість кластеризації з оптимальною кількістю кластерів матиме максимальне значення метрики якості.

Прикладом якісної метрики, яку я використовував у минулому, є Калінскі-Харабаш. Коротко: ви обчислюєте середню відстань між кластерами і ділите їх на відстані всередині кластера. Оптимальне призначення кластеризації матиме кластери, які найбільше відокремлені один від одного, і кластери, які є "найтіснішими".

До речі, вам не потрібно використовувати ієрархічну кластеризацію. Ви також можете використовувати щось на зразок k -означає, попередньо обчислити його для кожного k , а потім вибрати k, що має найвищий бал Калінського-Харабаша.

Повідомте мене, якщо вам потрібні додаткові посилання, і я перегляну свій жорсткий диск, щоб знайти кілька статей.


1
так, я оцінив би кілька статей про ієрархічне проти оцінки Калінського-Харабаша! спасибі
зміна

11

Перевірте алгоритм DBSCAN . Це кластери на основі локальної щільності векторів, тобто вони не повинні знаходитись на відстані більше, ніж ε , і можуть автоматично визначати кількість кластерів. Він також вважає, що викиди, тобто точки з недостатньою кількістю ε- сусідів, не є частиною кластера. Сторінка Вікіпедії посилається на кілька реалізацій.


0

Використовуйте OPTICS , який добре працює з великими наборами даних.

ОПТИКА: Точки впорядкування для ідентифікації кластерної структури, тісно пов’язаної з DBSCAN, знаходить основний зразок високої щільності та розширює з них кластери 1 . На відміну від DBSCAN, зберігає ієрархію кластера для змінного радіуса сусідства. Краще підходить для використання на великих наборах даних, ніж поточна склеарна реалізація DBSCAN

from sklearn.cluster import OPTICS
db = OPTICS(eps=3, min_samples=30).fit(X)

Точна настройка eps, min_samples відповідно до ваших вимог.


0

Можливо, у вас немає рішення: це той випадок, коли відстань між будь-якими двома різними точками вхідних даних завжди більша за Т. Якщо ви хочете обчислити кількість кластерів лише з вхідних даних, ви можете подивитися на MCG, ієрархічну кластеризацію метод із критерієм автоматичної зупинки: дивіться безкоштовну семінарську роботу за посиланням https://hal.archives-ouvertes.fr/hal-02124947/document (містить бібліографічні посилання).


0

Я хочу додати відповідь moooeeeep за допомогою ієрархічної кластеризації. Це рішення працює для мене, хоча підбирати порогове значення цілком "випадково". Звернувшись до іншого джерела та тесту на себе, я покращив метод і поріг можна було легко вибрати за допомогою дендрограми:

from scipy.cluster import hierarchy
from scipy.spatial.distance import pdist
import matplotlib.pyplot as plt

ori_array = ["Your_list_here"]
ward_array = hierarchy.ward(pdist(ori_array))
dendrogram = hierarchy.dendrogram(hierarchy.linkage(ori_array, method  = "ward"))
plt.title('Dendrogram')
plt.xlabel('Customers')
plt.ylabel('Euclidean distances')
plt.show()

Ви побачите такий сюжет, натисніть тут . Тоді, накресливши горизонтальну лінію, скажімо, на відстані = 1, кількість сполучників буде вашим бажанням кількості кластерів. Тому тут я вибираю поріг = 1 для 4 кластерів.

threshold = 1
clusters_list = hierarchy.fcluster(ward_array, threshold, criterion="distance")
print("Clustering list: {}".format(clusters_list))

Тепер кожному значенню в cluster_list буде присвоєний ідентифікатор кластера відповідної точки в ori_array.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.