Нечітка кластеризація: алгоритм fuzzy c-means і точки між кластерами
K-means і його чітке віднесення, fuzzy c-means з належностями до всіх кластерів, фазифікатор m, коефіцієнт розбиття та індекс Се — Бені для вибору кількості кластерів — і чому викидні точки дістають високі належності.
Серія Основи ШІ Частина 36 з 52
- Мапа штучного інтелекту: що є що і як усе це пов’язано
- Коротка історія штучного інтелекту: від Тюрінга до мовних моделей
- Дані, модель, тренування, інференс: основні поняття на одному прикладі
- Як читати математичний запис: символи, індекси, суми та квантори
- Множини й відношення: конструктор, з якого складаються означення в ШІ
- Функції й відображення: чому кожна модель у ШІ — це функція
- Логіка й доведення: правила, за якими міркують у ШІ
- Графи й дерева: структура, на якій тримаються пошук і нейронні мережі
- Лінійна алгебра для машинного навчання: вектори, матриці й чому ШІ передусім множить
- Похідні, градієнт і правило ланцюжка: як модель дізнається, у якому напрямку вчитися
- Градієнтний спуск: як навчається модель
- Що таке ймовірність: від кидка кубика до аксіом Колмогорова
- Умовна ймовірність і теорема Баєса: як змінити оцінку, коли дізнаєтеся щось нове
- Випадкова величина і функція розподілу: одна функція, яка каже про розподіл усе
- Функція щільності та функція маси ймовірності: чому неперервна величина має в точці ймовірність нуль
- Математичне сподівання, дисперсія і коваріація: де лежить розподіл, наскільки він широкий і що з чим пов’язано
- Огляд розподілів ймовірностей: Бернуллі, біноміальний, Пуассона, рівномірний, нормальний і експоненційний
- Закон великих чисел і центральна гранична теорема: чому середні поводяться так передбачувано
- Статистика й оцінювання параметрів: максимальна правдоподібність, MAP і довірчі інтервали
- Теорія інформації: ентропія, перехресна ентропія і KL-дивергенція — звідки беруться функції втрат
- Пошук у просторі станів: BFS, DFS, UCS і A* з анімаціями
- Ігри та суперник: мінімакс, альфа-бета відсікання і Monte Carlo tree search
- Задоволення обмежень: бектрекінг, поширення обмежень і AC-3 на судоку та мапі чеських країв
- Логіка й системи, засновані на знаннях: пряме і зворотне виведення, резолюція та експертні системи
- Планування: STRIPS, світ кубиків, евристики з релаксації та планування в AI-агентах
- Локальний пошук та імітація відпалу: комівояжер через обласні центри Чехії
- Генетичні алгоритми: популяція, схрещування, мутація і добір на рюкзаку для походу
- Еволюційні стратегії і генетичне програмування: від правила однієї п’ятої до закону Кеплера
- Оптимізація мурашиною колонією: як феромоновий слід знаходить короткий шлях
- Оптимізація роєм частинок: інерція, власний досвід і досвід рою
- Нейроеволюція: еволюція ваг і форми нейронних мереж та алгоритм NEAT
- Нечіткі множини й функції належності: як записати «трохи тепло»
- Нечітка логіка та ймовірність: чому «трохи тепло» не означає «імовірно тепло»
- Нечітка логіка: t-норми, імплікації та правила ЯКЩО–ТО
- Нечітке керування: Мамдані та Суґено від вентилятора до маятника на візку
- Нечітка кластеризація: алгоритм fuzzy c-means і точки між кластерами
- Нейро-нечіткі системи (ANFIS): нечіткі правила, які навчаються з даних
- Марковські ланцюги: матриця переходів, стаціонарний розподіл і PageRank
- Приховані марковські моделі: алгоритм Вітербі й нечесне казино
- Байєсівські мережі: чому трава мокра і що з цього випливає для дощувача
- Фільтр Калмана: як за неточними вимірюваннями оцінити, де авто і як швидко воно їде
- Види машинного навчання: з учителем, без учителя, з частковим залученням учителя та інші
- Промпти, контекст і RAG: як дати моделі правильну інформацію
- Варіаційні автокодувальники (VAE): нові зображення з неперервного латентного простору
- Генеративні змагальні мережі (GAN): фальшувальник проти детектива
- Дифузійні моделі: як із чистого шуму постає зображення
- Марковські процеси ухвалення рішень: стани, дії, винагороди й рівняння Беллмана
- Q-навчання і DQN: як навчитися цінності дій — від таблиці до нейронної мережі
- Policy gradient і PPO: навчання безпосередньо політики
- Як працює ШІ-агент: мовна модель у циклі з інструментами
- Програмування з AI-агентами: завдання, тести й перевірка
- Оцінювання і безпека систем ШІ: як вимірювати і як стежити
Повна програма серії Готово: 52 з 83 тем
- Як працює k-means і що він замовчує про точки на межі кластерів.
- Як fuzzy c-means обчислює належності й центри і що робить фазифікатор m.
- Як вибрати кількість кластерів і де fuzzy c-means дає збій.
Що варто знати заздалегідь: Нечіткі множини й функції належності: як записати «трохи тепло», Види машинного навчання: з учителем, без учителя, з частковим залученням учителя та інші
Кластеризація шукає в даних групи, про які заздалегідь нічого не відомо: покупців зі схожою купівельною поведінкою, ділянки однієї тканини на знімку магнітно-резонансної томографії, документи на схожу тему. Класичний алгоритм k-means відносить кожну точку рівно до однієї групи. Проте справжні дані мають точки на межі — покупця, який купує трохи як студент і трохи як батько, піксель, у якому сходяться сіра й біла речовина мозку. Нечітка кластеризація дозволяє точці належати до кількох груп водночас, до кожної з них трохи.
Продовжує частини Нечіткі множини й функції належності і Види машинного навчання, де кластеризація з’явилася як типова задача навчання без учителя.
1. Чітка кластеризація: k-means
Означення — задача k-means
Для точок x1, …, xn ∈ ℝd і кількості кластерів c шукаємо центри v1, …, vc і віднесення точок до кластерів, які мінімізують
J = ∑i=1n ‖xi − vshluk(i)‖2.
Алгоритм Ллойда чергує два кроки: віднеси кожну точку до найближчого центру; перерахуй кожен центр як середнє його точок. Повторюй, поки віднесення змінюється.
Ви розставляєте в даних кілька «прапорців». Кожна точка приєднується до найближчого. Потім кожен прапорець переїжджає в середину своїх точок. Точки знову приєднуються до найближчого прапорця — і так далі, доки нічого не змінюється. Кожен крок зменшує J, тож алгоритм напевно зупиниться, хоча й не обов’язково на найкращому можливому розбитті.
Означення — евклідова відстань
Для точок x, v ∈ ℝd маємо ‖x − v‖ = √( ∑r=1d (xr − vr)2 ). На площині це звичайна довжина відрізка, наприклад від точки M1 = (4,5; 2,5) до центру кластера A (1,73; 2,31), який нижче знайде fuzzy c-means: √(2,772 + 0,192) ≈ 2,78. Кластеризація працює з квадратом ‖·‖2 — відпадає корінь, а віддалені точки штрафуються сильніше.
def kmeans(X, c):
V = c випадково вибраних точок з X # початкові центри
while True:
shluk = [argmin_j ‖x − V[j]‖² for x in X] # крок віднесення
if shluk не змінився: return V, shluk
for j in range(c): # крок центрів
V[j] = середнє точок x, для яких shluk(x) = j
Теорема — алгоритм Ллойда зупиняється
Жоден крок не збільшує J, тому алгоритм зупиняється після скінченної кількості кроків.
Доведення: Віднесення: кожен доданок ‖xi − vshluk(i)‖2 замінюється найменшим з усіх ‖xi − vj‖2, тож не збільшується. Центри: для точок S одного кластера із середнім x̄ справджується розклад
∑i∈S ‖xi − v‖2 = ∑i∈S ‖xi − x̄‖2 + |S| · ‖x̄ − v‖2
(мішаний доданок 2 ∑ (xi − x̄) · (x̄ − v) дорівнює нулю, бо ∑ (xi − x̄) = 0). Отже, сума найменша при v = x̄. Розбиттів n точок на c кластерів скінченно багато, а J за кожної зміни віднесення строго спадає (за однакової відстані лишаємо точку в її кластері), тож жодне розбиття не повториться. ∎
Теорема нічого не каже про те, чи знайдене розбиття має найменше J, — лише що алгоритм не зациклиться.
Наші дані: три групи по 40 точок — A ліворуч унизу, B праворуч і C угорі, — чотири точки на межі (M1–M4) і дві викидні точки далеко від усього (O1, O2). K-means усталився після чотирьох ітерацій:
Кластери він знайшов добре, але точки на межі мусив розподілити: M1, M3 і M4 відніс до B, M2 — до A. Точка M3 при цьому лежить майже точно між B і C — k-means про це нічого не скаже. А обидві викидні точки потрапили до кластера C, ніби належать до нього так само, як його ядро.
2. Fuzzy c-means
Означення — fuzzy c-means (Данн 1973, Бездек 1981)
Замість віднесення шукаємо матрицю належностей U = (uij), uij ∈ [0, 1], де для кожної точки ∑j uij = 1, і центри vj, які мінімізують
Jm = ∑i ∑j uijm ‖xi − vj‖2,
де m > 1 — фазифікатор. Алгоритм чергує два кроки, що випливають з умов оптимальності:
vj = ∑i uijm xi / ∑i uijm, uij = 1 / ∑k (dij / dik)2/(m−1),
де dij = ‖xi − vj‖.
Кожна точка ділить свою одиницю між усіма кластерами — більше тому, до якого вона ближче. Центр кластера — це зважене середнє всіх точок: точки, які сильно належать до кластера, тягнуть його більше, точки з інших кластерів — лише ледь-ледь. Формула належності порівнює відстані: якщо точка до одного центру вдвічі ближча, ніж до іншого, вона дістає (при m = 2) учетверо більшу належність.
Jm = ∑i=1n ∑j=1c uijm ‖xi − vj‖2, ∑j uij = 1
- Jm
- загальна «ціна» розбиття — алгоритм її мінімізує; вона мала, коли точки належать переважно до близьких до них центрів
- ∑i ∑j
- кожна точка рахується до кожного кластера — на відміну від k-means, де на точку брався лише один кластер
- uij
- належність точки i до кластера j — вага, з якою відстань входить у ціну
- m
- фазифікатор — без степеня (m = 1) вигідно було б віддати всю одиницю найближчому центру, і знову вийшов би k-means; при m > 1 ділитися вигідно: точка, однаково віддалена від двох центрів, при m = 2 і поділі навпіл заплатить лише (½2 + ½2) · d2 = ½d2 замість d2
- ‖xi − vj‖2
- квадрат відстані — скільки коштує мати точку «біля» цього центру; далекий центр обійдеться дорого
- ∑j uij = 1
- умова — без неї мінімум був би тривіальним: усі uij = 0 і нульова ціна
uij = 1 / ∑k=1c ( dij / dik )2/(m−1)
- uij
- нова належність точки i до кластера j за фіксованих центрів
- dij / dik
- відношення відстаней — у скільки разів центр j далі, ніж центр k; відношення (а не різниця) робить результат незалежним від масштабу даних
- 2/(m−1)
- наскільки різко вирішує відношення — для m = 2 це 2, тож удвічі ближчий центр дістає вчетверо більше; для m → 1 показник необмежено зростає і все дістає найближчий центр
- ∑k
- порівняння з усіма центрами, зокрема із самим j (доданок k = j дорівнює 1), — завдяки цьому належності точки дають у сумі рівно 1
Теорема — звідки беруться обидва кроки
Належності за фіксованих центрів. Для однієї точки i мінімізуємо ∑j uijm dij2 за умови ∑j uij = 1. Функція Лагранжа: L = ∑j uijm dij2 − λ (∑j uij − 1). З ∂L/∂uij = m uijm−1 dij2 − λ = 0 випливає uij = (λ/m)1/(m−1) · dij−2/(m−1). Після підстановки в умову суми невідома λ скорочується і лишається
uij = dij−2/(m−1) / ∑k dik−2/(m−1) = 1 / ∑k (dij / dik)2/(m−1).
Вийшли додатні числа, тож умову uij ≥ 0 окремо стежити не треба. (Якщо точка лежить точно в центрі, dij = 0, вона дістає до цього кластера належність 1; наша реалізація розв’язує це так, що відстань ніколи не падає нижче 10−12.)
Центри за фіксованих належностей. Jm — опукла квадратична функція від vj, і ∂Jm/∂vj = −2 ∑i uijm (xi − vj) = 0 дає vj = ∑i uijm xi / ∑i uijm.
Отже, кожен крок мінімізує Jm за фіксованої другої групи змінних і не може його збільшити — той самий аргумент, що й для k-means. Бездек та ін. (1987, виправлення початкової теореми Бездека 1980 року) показали, що послідовність має граничні точки в стаціонарних точках Jm (не обов’язково в глобальному мінімумі).
import numpy as np
def fcm(X, c, m=2.0, iteraci=100, eps=1e-5):
U = np.random.dirichlet(np.ones(c), size=len(X)) # випадкові належності, рядок = 1
for _ in range(iteraci):
W = U ** m
V = (W.T @ X) / W.sum(axis=0)[:, None] # центри як зважені середні
D = np.linalg.norm(X[:, None, :] - V[None, :, :], axis=2) + 1e-12
nove = 1 / ((D[:, :, None] / D[:, None, :]) ** (2 / (m - 1))).sum(axis=2)
if np.abs(nove - U).max() < eps:
return V, nove
U = nove
return V, U
3. Fuzzy c-means на наших даних
Колір точки тепер — суміш кольорів кластерів відповідно до належностей: чисто зелена точка належить лише до A, точка «між» зеленим і помаранчевим — частково до A і частково до B. Пунктирні лінії показують, як переміщувалися центри, — алгоритм усталився після дев’яти ітерацій:
| Точка | k-means | A | B | C |
|---|---|---|---|---|
| M1 (4,5; 2,5) | B | 0,41 | 0,45 | 0,15 |
| M2 (3,3; 4,5) | A | 0,43 | 0,18 | 0,38 |
| M3 (5,8; 5) | B | 0,12 | 0,44 | 0,45 |
| M4 (4,6; 4) | B | 0,28 | 0,40 | 0,32 |
Тепер видно, що k-means замовчав. M1 майже навпіл між A і B; M3 насправді на волосинку більше в C, ніж у B, хоча k-means відніс її до B; а M4 посередині трикутника трохи належить до всіх трьох. Точки в ядрах кластерів мають належність до свого кластера, близьку до одиниці. Центри вийшли практично такі самі, як у k-means, — fuzzy c-means не змінює, де кластери, але додає до них інформацію, наскільки впевнено до них належить кожна точка.
Приклад — належності точки M1 = (4,5; 2,5)
Центри після дев’яти ітерацій: A ≈ (1,73; 2,31), B ≈ (7,12; 2,87), C ≈ (4,51; 7,11). Для m = 2 досить обернених квадратів відстаней:
| Кластер | d2 | 1/d2 | u = (1/d2) / 0,3190 |
|---|---|---|---|
| A | 2,772 + 0,192 ≈ 7,72 | 0,1296 | 0,41 |
| B | 2,622 + 0,372 ≈ 7,03 | 0,1423 | 0,45 |
| C | 0,012 + 4,612 ≈ 21,25 | 0,0471 | 0,15 |
| сума | 0,3190 | 1,00 |
M1 майже однаково віддалена від центрів A і B (7,72 проти 7,03), тому ділиться між ними майже навпіл; C утричі далі (у квадраті), тож дістає лише решту.
4. Фазифікатор m
Означення — коефіцієнт розбиття
Коефіцієнт розбиття (partition coefficient) — це PC = (1/n) ∑i ∑j uij2. Він дорівнює 1 для чіткого розбиття і 1/c, коли кожна точка однаково належить до всіх кластерів.
Одне число, яке каже, наскільки «чітке» розбиття. Для трьох кластерів воно лежить між 1/3 (усе розмите) і 1 (кожна точка має ясний дім).
PC = (1/n) ∑i ∑j uij2
- PC
- чіткість усього розбиття, число з [1/c; 1]
- (1/n) ∑i
- середнє за точками — щоб можна було порівнювати набори даних різного розміру
- ∑j uij2
- чіткість однієї точки — квадрат «винагороджує» зосереджену належність: (1, 0, 0) дає 1, (⅓, ⅓, ⅓) лише ⅓; за фіксованої суми 1 сума квадратів найменша, коли всі частки однакові
Для m, близького до 1, fuzzy c-means наближається до k-means: коефіцієнт розбиття дорівнює 0,98, а точка M4 належить до B на 0,79. Для m = 2 коефіцієнт становить 0,84, а для m = 5 лише 0,42 — кольори зливаються, і навіть точка з ядра кластера A має до A належність лише 0,45. Для m → ∞ усі належності прямували б до 1/3. Найчастіше використовують m = 2: досить м’яко, щоб точки на межі було видно, і досить чітко, щоб кластери лишалися виразними.
Приклад — точка вдвічі ближча до одного з двох центрів
Точка має до центру 1 відстань 1, а до центру 2 відстань 2. За формулою u1 = 1 / (1 + (1/2)2/(m−1)):
- m = 1,2: показник 10, u1 = 1 / (1 + 1/1 024) ≈ 0,999 — практично чітке віднесення,
- m = 2: показник 2, u1 = 1 / (1 + 1/4) = 0,8,
- m = 5: показник 0,5, u1 = 1 / (1 + 0,707) ≈ 0,586,
- m → ∞: показник → 0, (1/2)0 = 1 і u1 → 1/2.
Загалом: для m → 1+ показник 2/(m − 1) прямує до нескінченності, відношення dij/dik < 1 прямують до нуля, а ті, що > 1, — до нескінченності, тож найближчий центр дістає 1, а решта 0 (k-means). Для m → ∞ показник прямує до нуля, усі c доданків суми прямують до 1 і uij → 1/c.
5. Скільки кластерів?
Кількість кластерів алгоритму треба задати. Коли ми її не знаємо, запускаємо його для різних c і порівнюємо якість розбиттів. Для цього придатні коефіцієнт розбиття та індекс Се — Бені (Xie–Beni).
Означення — індекс Се — Бені
XB = ∑i ∑j uijm ‖xi − vj‖2 / (n · minj ≠ k ‖vj − vk‖2) — що менший, то краще.
Чисельник вимірює, наскільки щільно точки тримаються своїх центрів; знаменник — наскільки далеко один від одного два найближчі центри. Добре розбиття має компактні кластери, далекі один від одного.
XB = ∑i ∑j uijm ‖xi − vj‖2 / ( n · minj ≠ k ‖vj − vk‖2 )
- XB
- відношення «розкид усередині кластерів / відстань між ними» — менше краще
- ∑ ∑ uijm ‖xi − vj‖2
- компактність — саме значення Jm, яке алгоритм мінімізував
- n
- кількість точок — робить із чисельника середнє на точку, щоб індекс не зростав із розміром даних
- minj ≠ k ‖vj − vk‖2
- відокремленість — вирішує найближча пара центрів; саме Jm з додаванням кластерів лише спадає, а цей доданок штрафує розбиття, яке розколює один справжній кластер на два близькі
Приклад — індекс Се — Бені для c = 3
Після завершення алгоритму J2 ≈ 166,73. Квадрати відстаней між центрами: A–B ≈ 29,4, A–C ≈ 30,8, B–C ≈ 24,79 (найближчі B і C). Для n = 126 точок:
XB = 166,73 / (126 · 24,79) = 166,73 / 3 124 ≈ 0,053.
| Кількість кластерів c | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|
| Коефіцієнт розбиття (більше краще) | 0,745 | 0,841 | 0,748 | 0,661 | 0,609 |
| Індекс Се — Бені (менше краще) | 0,228 | 0,053 | 0,298 | 0,682 | 0,529 |
Обидва показники сходяться на трьох кластерах, які ми вклали в дані. Для справжніх даних такий збіг не самоочевидний, і показники радше орієнтир, ніж вердикт.
6. Де fuzzy c-means дає збій
Погляньте на викидні точки: O1 праворуч угорі має до C належність 0,45, а до B — 0,39; O2 ліворуч угорі — навіть 0,58 до C. Проте жодному кластеру вони не належать. Винна умова ∑j uij = 1: точка мусить комусь роздати свою одиницю, навіть коли вона далеко від усіх. Належність тут означає радше «до кого найближче», ніж «наскільки добре сюди пасує».
Приклад — чому O2 = (0,2; 9,5) «належить» до C
Квадрати відстаней до центрів: A ≈ 54,07, B ≈ 91,88, C ≈ 24,29. Навіть від найближчого центру C точка, отже, віддалена на 4,9 — понад шість стандартних відхилень 0,8, з якими точки кластерів розкидані навколо центрів. Обернені значення 0,0185, 0,0109 і 0,0412 дають суму 0,0706 і належності 0,26, 0,15 і 0,58. Формула бачить лише відношення відстаней, а не їхню величину: що далі лежала б точка, то ближче відношення були б до 1, а належності — до ⅓, але до нуля вони не прямували б ніколи.
Означення — посибілістичні c-means (Крішнапурам і Келлер, 1993)
Умову суми відкидають, а до ціни додають доданок, який не допускає тривіального розв’язку u = 0:
J = ∑i ∑j uijm dij2 + ∑j ηj ∑i (1 − uij)m, звідки uij = 1 / (1 + (dij2 / ηj)1/(m−1)).
ηj — це «радіус» кластера j: точка на відстані d2 = ηj має належність ½, а при m = 2 точка з d2 = 9ηj — лише 0,1. Належність тепер залежить від відстані до одного-єдиного центру, а не від відношення до інших, — викидна точка дістає малі значення скрізь.
- Посибілістичні c-means (Крішнапурам і Келлер, 1993) скасовують умову суми — викидна точка тоді дістає малі належності до всіх кластерів.
- Форма кластерів. Евклідова відстань дає круглі кластери. Алгоритм Густафсона — Кесселя (1979) дає кожному кластеру власну матрицю відстані і знаходить навіть видовжені еліпси.
- Початкове положення. Так само, як k-means, алгоритм може зупинитися в гіршому локальному мінімумі — на практиці його запускають кілька разів з різних стартів.
7. Нечітка кластеризація на практиці
- Медичні знімки. Сегментація МРТ-знімків мозку на сіру речовину, білу речовину та спинномозкову рідину — класичне застосування: піксель на межі тканин справді містить обидві.
- Сегментація покупців. Покупець може частково належати до кількох груп, і маркетинг може це враховувати.
- Імовірнісний родич. Гаусові суміші, навчені алгоритмом EM, теж відносять точки до кластерів «м’яко» — але ймовірностями, а не належностями. Результати бувають схожі, а тлумачення відрізняється саме так, як описала частина про нечітку логіку та ймовірність.
- Ембединги. Тексти, перетворені мовною моделлю на вектори, можна кластеризувати так само; м’яке віднесення тоді покаже документи, що лежать між темами.
8. Підсумок
- K-means відносить кожну точку рівно до одного кластера і нічого не каже про точки на межі.
- Fuzzy c-means шукає належності uij із сумою 1 і центри як зважені середні; чергує два прості кроки.
- На наших даних він знайшов ті самі центри, що й k-means, і до того ж показав, що точки M1–M4 належать до двох чи трьох кластерів водночас.
- Фазифікатор m керує тим, наскільки м’яке розбиття; коефіцієнт розбиття та індекс Се — Бені допомагають вибрати кількість кластерів.
- Умова суми 1 дає викидним точкам високі належності; посибілістичні варіанти це розв’язують.
Хочете спробувати самі? Попросіть ШІ-агента запустити fuzzy c-means на кольорах пікселів вашої власної фотографії й розфарбувати її за кластерами — і погляньте, які пікселі лежать «між» кольорами.
Маєте іншу думку? Напишіть на support@coden-app.com.