Попередня тема закінчилась трьома картинками, на яких відповідь була очевидно неправильною. Дві довгі смуги, які k-means розрізав упоперек, — 58 % точок на своїх місцях. Коло всередині кільця — 60 %. Щільна купка поруч із розсіяною хмарою — 89 %. Людське око бачить правильну відповідь за півсекунди, а метод її не бачить узагалі.
Причина не в налаштуваннях. Вона в самій будові k-means: кожна точка йде до найближчого центра, тому межа між кластерами — завжди пряма, а кластер — завжди приблизно кругла грудка. Плюс друга незручність: кількість груп k доводиться назвати наперед, до того як ти щось про дані дізнався.
Дві відповідіДві відповіді на одну невдачу
Обидві проблеми мають розвʼязок, і розвʼязки ці зовсім різні.
DBSCAN викидає з опису поняття центра. Замість «де середина групи» він питає «де точки стоять густо» — і нарощує кластер від сусіда до сусіда, куди б той не тягнувся. Смуга, кільце, підкова: якщо ланцюжок сусідів веде туди, кластер піде туди. Заразом він уміє те, чого k-means не вміє принципово, — сказати про окрему точку «це не кластер, це шум».
Ієрархічна кластеризація відповідає на другу проблему. Вона не видає одне розбиття. Вона будує дерево: спочатку кожен обʼєкт сам по собі, далі найближча пара зливається, далі наступна — аж поки все не стане однією групою. Кількість груп обираєш ти, але після побудови, дивлячись на дерево, а не наосліп до неї.
Тут легко зробити хибний висновок: мовляв, це два способи полагодити те саме, і треба вибрати кращий. Це не так. Вони лагодять різні поломки й відповідають на різні питання — тому й не заміняють один одного.
| метод | питання, на яке він відповідає | що на виході |
|---|---|---|
| k-means | де стоять k центрів? | рівно k груп, кожна точка обовʼязково в якійсь |
| DBSCAN | де точки стоять густо? | групи довільної форми — скільки вийде — плюс окрема мітка «шум» |
| Ієрархічна | що з чим зливається раніше? | дерево злиттів; будь-яке розбиття дістається з нього зрізом |
Звідси й правило вибору, до якого ми повернемось у розділі 12 вже з числами на руках. Ієрархічну беруть, коли не знаєш, скільки груп шукати: вона показує всі варіанти одразу, і кількість обираєш по дереву, а не наосліп. DBSCAN беруть, коли не знаєш, якої вони форми — або коли окремі дивні обʼєкти цікавлять тебе не менше за самі групи. Питання «скільки?» і питання «якої форми?» незалежні одне від одного, тож буває, що в задачі потрібні обидва методи: дерево — щоб прикинути кількість, щільність — щоб знайти форму й викиди.
І одразу про ціну, щоб вона не стала сюрпризом наприкінці. Ієрархічна кластеризація тримає в памʼяті всі попарні відстані, тому вона метод для тисяч рядків, а не для мільйонів; DBSCAN такої межі не має. Точні числа — у розділі 10.
Працюємо на тих самих даних, що й у минулій темі. Наскрізний приклад — дошка оголошень про вживані телефони з теми 08: 1 100 оголошень із відомою ціною, дві ознаки — логарифм ціни й рік випуску, обидві приведені до z-оцінок. Плюс три синтетичні набори, на яких k-means провалився: витягнуті смуги, вкладені кільця, різна щільність. Ті самі точки, що й у темі 26, — щоб порівняння було чесним.
ЩільністьКластер — це там, де густо
Уся ідея DBSCAN (density-based spatial clustering of applications with noise — кластеризація за щільністю з урахуванням шуму) тримається на одному спостереженні: усередині кластера точки стоять близько одна до одної, а між кластерами — порожньо. Не «кругло», не «навколо центра» — просто густо.
Щоб перетворити це на алгоритм, потрібні два числа, і задаєш їх ти.
eps(радіус околу) — наскільки близько має стояти точка, щоб вважатись сусідкою. Це відстань у тих самих одиницях, у яких лежать ознаки: у нас — у z-оцінках.min_samples(мінімум сусідів) — скільки точок має бути в цьому радіусі, щоб місце вважалось густим.
scikit-learn
min_samples рахує разом із самою точкою. Тобто
min_samples=3 означає «сама точка плюс щонайменше двоє сусідів», а не троє
сусідів. Помилка на одиницю тут не викине винятку — вона просто змістить межу
щільності.Далі кожна точка отримує одну з трьох ролей, і ці три слова — весь словник методу.
| роль | умова | що це означає |
|---|---|---|
| Ядерна (core) | у радіусі eps навколо неї — щонайменше min_samples точок | вона стоїть у густому місці й має право нарощувати кластер далі |
| Гранична (border) | сусідів замало, але вона сама лежить у радіусі якоїсь ядерної | вона в кластері, але з неї кластер далі не росте — це край |
| Шум (noise) | ні те, ні те | жодного кластера; алгоритм чесно каже «ця точка ні з ким» |
Візьмімо ті самі десять оголошень, на яких у минулій темі крутились ітерації k-means, і
роздамо їм ролі. Радіус eps = 1.2 (нагадаю: одиниця тут — одне стандартне
відхилення), min_samples = 3.
Три ролі точки
Десять оголошень із розділу 3 попередньої теми. Навколо кожної точки — коло радіуса 1.2; підраховуємо, скільки точок у нього потрапило разом із нею самою.
| оголошення | z (ціна, рік) | точок у радіусі 1.2 | роль | кластер |
|---|---|---|---|---|
| A1 | −0.5, 1.1 | 3 | ядерна | 1 |
| A2 | −1.0, −1.1 | 2 | гранична | 2 |
| A3 | −2.5, −1.5 | 2 | гранична | 2 |
| A4 | 0.1, 1.5 | 4 | ядерна | 1 |
| A5 | 0.6, 1.5 | 6 | ядерна | 1 |
| A6 | 1.1, 0.7 | 4 | ядерна | 1 |
| A7 | 1.0, 1.5 | 5 | ядерна | 1 |
| A8 | 1.7, 1.5 | 4 | ядерна | 1 |
| A9 | 0.4, −1.5 | 1 | — | шум |
| A10 | −2.0, −0.6 | 3 | ядерна | 2 |
Gamma X Ultra 2017 року, у якого в темі 26 силует був 0.205 — k-means
мусив кудись його віднести, а DBSCAN просто каже «ні з ким».АлгоритмЯк розростається кластер
Ролі роздано — далі алгоритм майже тривіальний. Він обходить точки одну за одною:
Прокрутімо це на наших десяти. Перша точка — A1, вона ядерна, відкриваємо кластер 1 і кладемо в чергу її сусідів A4 і A5. Дістаємо A4 — вона ядерна, тож її сусіди теж ідуть у чергу: A5 і A7 (сама A1 там уже була). Дістаємо A5 — ядерна, дописує A6, A7, A8. Черга крутиться, поки не вичерпається, і кластер 1 виходить такий: A1, A4, A5, A6, A7, A8. Далі беремо A2 — не ядерна, позначаємо шумом тимчасово. A3 — те саме. A9 — теж не ядерна. Аж ось A10: ядерна, відкриваємо кластер 2, у чергу йдуть A2 і A3 — обидві не ядерні, тому нікого далі не тягнуть, і кластер 2 = A10, A2, A3. A9 так і лишається шумом.
Як росте кластер
Ті самі десять оголошень, eps = 1.2,
min_samples = 3. Тягни повзунок і дивись на чергу: саме вона й веде
кластер від сусіда до сусіда.
Зверни увагу на два наслідки, які видно вже на десяти точках.
Перший: кластер може мати будь-яку форму. Він росте ланцюжком, від сусіда до сусіда, і жодного «центра» ніхто не рахує. Довга змія завтовшки в два кроки — законний кластер DBSCAN і неможливий кластер k-means.
Другий, дрібніший і неприємний: гранична точка може дістатись різним кластерам. Якби A2 лежала в колах двох різних ядерних точок із різних кластерів, її забрав би той, до кого черга дійшла першою, — тобто результат залежав би від порядку рядків у таблиці. Ядерних точок це не стосується: вони розподіляються однозначно. На практиці граничних точок мало, але якщо два запуски на перетасованих даних дали трохи різні мітки — причина зазвичай саме тут.
ПараметриДва повзунки, дві катастрофи
Тепер найважливіше про DBSCAN: усе тримається на двох числах. Кількість
кластерів він і справді не питає — але eps і min_samples задають
її неявно, і крайні значення дають дві протилежні катастрофи.
Візьмімо ті самі дві витягнуті смуги, які завалили k-means, і додамо до них пʼятнадцять розкиданих поодиноких оголошень — щоб було на що подивитись у графі «шум». Разом 145 точок: 130 у двох смугах і 15 самих по собі.
eps і min_samples
Тягни обидва повзунки. Заповнені кружечки — ядерні точки, порожні — граничні, сірі хрестики — шум. Колір = кластер.
eps = 0.45 і min_samples = 5
DBSCAN знаходить рівно дві смуги й оголошує шумом рівно ті 15 точок, які ми туди й
підкинули. Зменш радіус до 0.15 при min_samples = 10 — і густих місць не
лишиться взагалі: усі 145 точок стануть шумом. Збільш до 1.30 — і смуги
зіллються в один суцільний кластер. Між цими краями є вузька смужка правильних
відповідей, і ширина цієї смужки — головна практична проблема методу.Обидва параметри тягнуть в один бік, але по-різному. eps вирішує, які
точки взагалі бачать одна одну; min_samples — наскільки густо має бути, щоб
місце вважалось кластером. Більший min_samples при тому самому радіусі
означає більше шуму й менше кластерів.
Типова порада для min_samples: бери щонайменше подвоєну кількість
ознак. У нас ознак дві, отже 4–5 — і саме тому в усіх прикладах цієї теми стоїть
пʼятірка. Порада груба, але вона хоч якось привʼязує число до даних, і за нею стоїть
проста думка: що більше вимірів, то легше кільком точкам випадково опинитись поруч, тож
поріг «густо» доводиться піднімати.
І ще один наслідок, який зазвичай не називають, а він корисний. Будь-який кластер
DBSCAN містить щонайменше min_samples точок, і це видно з
означення: щоб кластер узагалі відкрився, потрібна ядерна точка, а в її колі за
означенням уже стоїть min_samples точок — і всі вони одразу дістають її
мітку. Тобто min_samples — це заразом і мінімальний розмір групи, яку метод
згоден визнати групою. Якщо в задачі відомо, що менш ніж вісім оголошень сегментом не
вважаються, це вже готове значення параметра.
Вибір epsЗвідки брати eps
Це головне практичне питання всього методу: без відповіді на нього DBSCAN не
запустиш. З min_samples ще можна жити за грубою порадою, а eps
— відстань, і «правильної» відстані ніхто наперед не знає: вона залежить від даних, від
масштабування, від кількості ознак. Порада «підбери на око» тут не відповідь, тож нижче
два робочі способи — і спосіб перевірити результат, не підглядаючи у правильну
відповідь, якої в реальній задачі немає.
Спосіб перший — графік k-ї відстані. Він дає перше наближення з самих даних:
Яке брати k? Те, що вже стоїть у min_samples, мінус один — і ось чому.
Точка стає ядерною, коли в її колі опиняється min_samples точок разом із
нею самою (розділ 2). Отже сусідів має набратись min_samples −
1, і найдальший із них — це min_samples − 1-й найближчий сусід. Відстань до
нього і є той радіус, за якого ця точка щойно стає ядерною. У нас
min_samples = 5, тому k = 4, і на графіку скрізь стоїть «четвертий
сусід».
Рахується це пʼятьма рядками:
Сенс кривої простий. Поки вона йде полого, ми рухаємось по точках, які сидять у густих місцях: до четвертого сусіда їм рукою подати. Коли крива задирається вгору — почались точки, у яких сусідів поблизу немає. Висота коліна і є та відстань, яка ще вважається «близько».
Відстань до четвертого сусіда, відсортована
Ліворуч — наші 145 точок зі смугами. Праворуч — 1 100 справжніх оголошень із дошки.
eps з
коліна — 0.45–0.50 — і отримуємо ідеальний розподіл. На дошці оголошень крива
піднімається плавно: у половини оголошень четвертий сусід ближче ніж за 0.04, у
95 % — ближче ніж за 0.23, а далі відстань росте без жодного зламу. Це такий самий нечіткий критерій, як лікоть у
k-means: він окреслює розумний діапазон і не називає числа.Спосіб другий — те, що робити, коли коліна немає. А немає його частіше, ніж є:
на правій половині схеми крива піднімається без жодного зламу. Тоді працює інший,
чесніший прийом: прогнати eps по сітці й подивитись, де відповідь
перестає стрибати. Ось та сама розгортка на наших 145 точках із двома смугами,
min_samples = 5:
| eps | кластерів | у шумі | частка шуму |
|---|---|---|---|
| 0.20 | 12 | 46 | 31.7 % |
| 0.30 | 9 | 27 | 18.6 % |
| 0.40 | 5 | 15 | 10.3 % |
| 0.45 | 2 | 15 | 10.3 % |
| 0.50 | 2 | 15 | 10.3 % |
| 0.55 | 2 | 15 | 10.3 % |
| 0.60 | 2 | 11 | 7.6 % |
| 0.70 | 1 | 10 | 6.9 % |
| 1.00 | 1 | 7 | 4.8 % |
Дивитись треба на полицю — проміжок, де відповідь не міняється. Тут вона одна й помітна: від 0.45 до 0.55 виходить рівно два кластери й рівно 15 шумових точок, тобто три різні радіуси дають ту саму відповідь. Це й є ознака, що поділ справжній, а не намальований радіусом: справжня структура витримує зсув параметра, вигадана — ні. При 0.60 кластерів усе ще два, але в шум уже потрапило 11 точок замість 15 — чотири одинаки прилипли до смуг, тобто край полиці почався. А коліно на схемі показало 0.45–0.50: два незалежні способи привели в те саме місце, і це найкраще підтвердження, яке взагалі можна отримати без розмітки.
Далі три числа, за якими відповідь перевіряють на здоровий глузд:
- частка шуму. Рівно нуль означає, що
epsзавеликий і метод уже нікого не відкидає; більш ніж половина — що замалий. Робочий діапазон зазвичай кілька відсотків, і його варто назвати собі наперед, виходячи із задачі: скільки дивних обʼєктів ти очікуєш у цих даних; - розмір найбільшого кластера. Якщо в ньому 99 % рядків — сталося злипання. Це найчастіша тиха поразка: метод ніби відпрацював, кластери ніби є, а поділу немає;
- ширина полиці. Якщо відповідь міняється на кожному кроці сітки й полиці немає взагалі — це теж результат, і читається він так: щільнісно відокремлених груп у цих даних немає. Саме такий випадок чекає нас у наступному розділі на справжній дошці оголошень.
eps, знайдений на z-оцінках, безглуздо переносити на ті самі дані в гривнях
і роках, і саме тому масштабування тут не порада, а умова.ШумШум — це відповідь
Тепер про властивість, якої немає в жодного методу з попередньої теми. DBSCAN
не зобовʼязаний віднести кожну точку до кластера. У
scikit-learn такі точки дістають мітку −1.
Звучить як вада — «алгоритм не впорався». Насправді це чесність. Коли k-means приписує дике оголошення до найближчого сегмента, він не додає знання, а ховає його: у групі «дешеві старі» тепер сидить телефон за 130 грн, який не схожий узагалі ні на що.
Подивись, що з цього виходить на справжніх даних. Запускаємо DBSCAN на всіх 1 100
оголошеннях дошки з eps = 0.3 і min_samples = 5. Результат
такий: 12 кластерів і 26 оголошень у шумі. І ось найцікавіше число всієї
теми: із цих 26 оголошень 25 позначені в таблиці як шахрайські. Алгоритм
цієї колонки не бачив.
| що вважаємо підозрілим | точність | повнота | F1 |
|---|---|---|---|
| шум DBSCAN (26 оголошень) | 0.962 | 0.180 | 0.303 |
| найдешевший кластер k-means (тема 26) | 0.206 | 0.525 | 0.296 |
| випадковий тик, 355 оголошень | 0.126 | 0.323 | 0.182 |
Читається це так. Шум DBSCAN майже не помиляється: з 26 піднятих тривог хибна одна. Але й ловить він мало — 25 шахраїв зі 139, тобто 18 %. Це ціни-приманки на кшталт 130 і 190 грн і завищені 45 320 та 83 500 грн: те, що стоїть на самому краю. Звичайного шахрая з ціною «трохи нижче ринку» жодна щільність не виловить, бо він лежить у гущі.
−1.eps менший за 0.43, вертикальних звʼязків між роками просто немає, і дошка
розпадається на горизонтальні смуги «всі оголошення 2019-го», «всі оголошення 2020-го».
Варто підняти eps до 0.5 — і 1 089 оголошень зливаються в один суцільний
кластер. Ніякої проміжної відповіді на цих даних немає: або смуги за роками, або одна
хмара. Це не поламаний DBSCAN — це чесна відповідь про дошку: щільнісно
відокремлених груп на ній немає.ВадаОдна щільність на всіх
Головна вада DBSCAN схована в тому самому місці, що й перевага: eps у
нього один на весь простір. Метод припускає, що всі справжні кластери
мають приблизно однакову густину. Коли це не так, вибирати доводиться між двома
поразками — і обидві варто побачити.
Це рівно той третій випадок із минулої теми — щільна купка й розсіяна хмара поруч, де
k-means дав 89 %. З параметрами, які ідеально спрацювали на смугах і кільцях
(eps = 0.6, min_samples = 5), DBSCAN дає на ньому
70 %: щільну купку знаходить цілком — усі 95 її точок в одному
кластері, разом із пʼятьма найближчими точками хмари, — а саму хмару рве на уламки й
30 точок зі 150 оголошує шумом.
Можна підібрати eps під розсіяну хмару — 0.85. Тоді кластерів рівно два,
шуму лише 9 точок, а на своїх місцях 88 %. Це найкраще, що DBSCAN
взагалі може видати на цих даних, — і воно все одно трохи гірше за k-means. Причому
дійти до цього числа можна, тільки підглядаючи у правильну відповідь, якої в реальній
задачі немає.
Один радіус на дві щільності
Ті самі 150 оголошень: 95 у щільній купці ліворуч, 55 у розсіяній
хмарі праворуч. Однакові дані, однаковий min_samples = 5, різний
eps.
eps = 0.6: навколо точки в серці купки в таке коло
потрапляє 89 точок, а навколо точки в серці хмари — 4, тобто хмара для алгоритму
просто порожнеча. Праворуч
eps = 0.85 хмару нарешті видно, але й купка розповзлась: у більшій групі
вже 104 точки замість 95. Проміжного радіуса, за якого обидві групи знайдено точно, на
цих даних не існує — і саме це, а не помилка в налаштуваннях, називають головною вадою
DBSCAN.Причину видно двома числами. Медіанна відстань до четвертого сусіда в щільній купці —
0.102, у розсіяній хмарі — 0.773: густина відрізняється
всемеро з половиною. Тому коло одного й того самого радіуса 0.6 накриває навколо половини
точок купки понад вісімдесят сусідів, а навколо половини точок хмари —
не більш як три, разом із нею самою. При min_samples = 5
перша ядерна із запасом, друга — шум. Один радіус фізично не може означати «густо» і тут,
і там: те, що для купки просторо, для хмари вже космос.
Як помітити це на своїх даних, де правильної відповіді немає. Ознака така: один
кластер забрав майже все, решта — крихти, і при цьому шуму багато. Тут при
eps = 0.6 вийшли групи 100, 10, 5 і 5 та ще 30 точок у шумі — це не «чотири
сегменти», а одна знайдена група й уламки другої. Друга ознака — з
розділу 5: якщо полиці немає, тобто відповідь стрибає з «усе розсипалось»
одразу в «усе злиплось», оминаючи проміжний стан, — щільності в даних різні, і DBSCAN на
них не інструмент. Саме так поводилась дошка оголошень: або смуги за роками, або одна
хмара.
eps взагалі. Він проганяє DBSCAN подумки
одразу для всіх радіусів, будує з цього дерево — так, те саме дерево, що й у другій
половині цієї теми, — і залишає ті кластери, які тримаються найдовше. Через це він
здатен знаходити групи різної щільності однією моделлю. Чарівної палички з нього
теж не виходить. На тому самому наборі «різна щільність» зі 150 точок, на якому
спіткнувся DBSCAN, HDBSCAN дає збіг зі справжніми групами 0.78 за скоригованим
індексом Ренда — проти 0.90 у DBSCAN із найвдалішим eps. І параметр
у нього свій: при min_cluster_size 10 виходить 0.78, при 15 —
уже нуль, бо метод оголошує шумом усе. Тобто eps не зник, а
перетворився на іншу ручку, яку так само доводиться крутити руками. Ціна — складніша реалізація й окремий
пакет (hdbscan, а у свіжих версіях scikit-learn —
HDBSCAN). Ідею варто знати; коли eps ніяк не підбирається, це
перше, що слід спробувати.ДеревоДерево замість розбиття
Другий метод теми починається з іншого питання. Не «де густо», а «що з чим схоже найбільше».
Такий напрямок — від окремих точок догори — зветься агломеративним (agglomerative, від «нагромаджувати»). Буває й зворотний, дивізивний: почати з однієї групи й ділити її. На практиці майже завжди беруть агломеративний, бо він простіший і передбачуваний.
Результат — не набір міток, а дендрограма (dendrogram, «деревна діаграма»). Читається вона так:
- кожен листок унизу — одне оголошення;
- кожна перемичка — злиття двох груп;
- висота перемички — відстань між групами в момент злиття. Низька перемичка означає «злилися схожі», висока — «злилися вимушено, бо більше нікого не лишилось».
А тепер найкорисніше. Проведи горизонтальну лінію на будь-якій висоті — і кожна вертикаль, яку вона перетне, стане окремою групою. Одне дерево, і скільки завгодно розбиттів. Кількість груп обирається після побудови, і обирається очима.
Дендрограма з рухомим зрізом
Двадцять вісім оголошень із дошки, злиття за середньою відстанню. Тягни повзунок — і дивись, скільки груп дає зріз і як вони лягають на площину.
LinkageЧим міряти відстань між групами
В описі методу є одне слово, повз яке легко проскочити: «знаходимо дві найближчі групи». А що таке відстань між групами? Між двома точками вона очевидна. Між купкою з семи точок і купкою з дванадцяти — ні.
Відповідей чотири, вони звуться звʼязком (linkage), і вибір між ними міняє результат сильніше, ніж будь-що інше в методі.
| звʼязок | відстань між групами — це… | що з цього виходить |
|---|---|---|
| Одиночний (single) | відстань між двома найближчими точками груп | групи ростуть ланцюжками; знаходить змії й кільця, але злипається через один випадковий місток |
| Повний (complete) | відстань між двома найдальшими точками | групи виходять компактні, приблизно кулясті; довгу смугу розріже |
| Середній (average) | середнє з усіх попарних відстаней між групами | компроміс між першими двома, найчастіше — розумна поведінка за замовчуванням |
| Ворда (ward) | наскільки зросте сума квадратів відстаней усередині груп, якщо їх злити | мінімізує рівно те, що й інерція k-means; кулясті групи схожого розміру |
Таблиця називає поведінку, але не пояснює, звідки вона береться. А береться вона цілком із того, яку саме пару чисел звʼязок дивиться.
Чому одиночний тягнеться ланцюжком. Він міряє відстань між групами однією парою точок — найближчою, і решта про групи його не обходить: ані розмір, ані форма, ані те, як далеко решта точок. Тому дві купки, між якими лежить доріжка з проміжних точок, зливаються покроково, ланка за ланкою, і кожен крок однаково дешевий. Девʼяти чисел на прямій досить, щоб це побачити:
Порахуй руками. Усередині купок сусіди стоять на відстані 1, уздовж доріжки — на відстані 2, і перехід від купки до доріжки — теж 2. Для одиночного звʼязку всі ці злиття однаково дешеві, тому він проходить усю пряму рівним кроком і жодного розриву не бачить. Попроси в нього дві групи — і він не зможе їх дати: усі чотири останні злиття стоять на тій самій висоті 2, тож зріз трохи нижче дає пʼять груп, а зріз трохи вище — одразу одну. Розбиття на дві в цьому дереві просто не існує. Це і є ланцюжковий ефект — одна доріжка з випадкових точок склеює те, що око розділяє миттєво. Він же й дає одиночному звʼязку його силу: рівно так само він проходить уздовж витягнутої смуги чи кільця, куди інші три не підуть.
Чому Ворд збирає кулі. Він міряє не відстань, а шкоду: наскільки зросте розкид усередині груп, якщо їх злити. Формула одна:
Словами: ціна злиття — це квадрат відстані між центрами двох груп, помножений на множник, який росте разом із їхніми розмірами. Тепер кожен символ окремо. nA і nB — скільки точок у першій і в другій групі. d — відстань між їхніми центрами; центр групи — це просто середнє її точок по кожній ознаці. d2 — та сама відстань, помножена сама на себе. Δ — велика грецька літера «дельта», якою в математиці позначають приріст; тут це приріст суми квадратів відстаней від точок до центра своєї групи. На кожному кроці Ворд зливає ту пару, у якої Δ найменша.
Порахуймо на шести числах. Нехай група P — це 6 точок із центром у (0, 0), група Q — 6 точок із центром у (3, 0), а між ними одна самотня точка R у (1.5, 0), рівно посередині:
Злити дві великі групи в чотирнадцять разів дорожче, ніж прийняти в одну з них самотню точку, — хоча центри розсунуті всього вдвічі далі. Звідси обидві звички Ворда. Квадрат відстані між центрами робить далекі злиття непомірно дорогими, тому групи виходять компактними, а не витягнутими. А множник із розмірів робить дорогим злиття двох великих груп, тому вони ростуть рівномірно й виходять схожого розміру. Та сама властивість — і головне обмеження: якщо справжні групи різного розміру або не кулясті, Ворд однаково намалює кулі схожого розміру.
Найважливіший із цих чотирьох рядків — усе-таки перший: одиночному звʼязку досить, щоб дві групи зʼєднала одна ланцюжкова доріжка, і далі він проковтне обидві. На синтетичних смугах це перевага, на реальних даних — катастрофа. Ось наша дошка, ієрархічна кластеризація, три групи:
А тепер те саме на синтетиці, де правильна відповідь відома, — і виявиться, що переможець міняється місцями з невдахою.
Чотири звʼязки, два набори даних
Угорі — дві витягнуті смуги без підкинутих одинаків, рівно 130 точок по 65 у кожній смузі; унизу — щільна купка (95) і розсіяна хмара (55). Обидва рази ріжемо дерево на дві групи.
ЦінаСкільки це коштує
За зручність «одразу вся ієрархія» доводиться платити, і платня росте квадратично.
Щоб знайти найближчу пару, треба знати всі попарні відстані — а їх для n обʼєктів рівно
n·(n − 1)/2, тобто приблизно n²/2. Кожна відстань — дробове число, яке numpy
зберігає у восьми байтах (тип float64). Далі просто
множення:
І це нижня оцінка, бо в ній лише сама матриця. Заміряно на одній машині:
AgglomerativeClustering зі звʼязком Ворда на 20 000 точках забрав
3 055 МБ, тоді як гола матриця відстаней для 20 000 точок важить
1 526 МБ. Тобто реальний апетит удвічі більший за формулу — бібліотека
тримає ще одну копію, поки зливає групи.
З часом та сама історія. Наївний пошук найближчої пари на кожному з n − 1 кроків дає n³ операцій; сучасні реалізації (алгоритм ланцюжка найближчих сусідів, яким рахують Ворда, повний і середній звʼязок) знімають один множник і працюють за n². Квадрат нікуди не дівається: матрицю все одно треба хоч раз прочитати цілком.
| рядків | ієрархічна (Ворд) | DBSCAN | різниця |
|---|---|---|---|
| 2 000 | 0.08 с | 0.009 с | ×9 |
| 4 000 | 0.43 с | 0.020 с | ×21 |
| 8 000 | 1.65 с | 0.050 с | ×33 |
| 16 000 | 7.79 с | 0.132 с | ×59 |
Читати цю таблицю треба не по секундах, а по тому, як вони ростуть. Подвоєння даних коштує ієрархічній учетверо-упʼятеро більше часу — це і є квадрат. DBSCAN на тому самому подвоєнні дорожчає лише приблизно у два з половиною рази. Тому розрив у правому стовпці росте разом із таблицею, і на десятках тисяч рядків вибору вже фактично немає.
Чому DBSCAN дешевший. Наївно він теж квадратичний: для кожної точки перебрати всі
інші. Але йому не потрібні всі відстані — лише сусіди в радіусі eps,
а це вміє просторовий індекс: структура, яка заздалегідь ділить простір
на комірки й дозволяє питати «хто лежить у цьому колі», не обходячи весь набір.
scikit-learn будує таке дерево (KD-дерево або ball-дерево) сам, і на двох-трьох
ознаках один запит коштує приблизно log n замість n, а весь прогін — n·log n. Тому DBSCAN
на мільйоні рядків реальний, а дендрограма на мільйоні — ні.
Що робити, коли рядків забагато для дерева. Ієрархічну майже завжди рятує
підвибірка: візьми випадкові кілька тисяч рядків, побудуй по них дендрограму й прочитай із
неї кількість груп — та відповідь, заради якої метод здебільшого й беруть. Далі
цю кількість віддаєш k-means, який спокійно пройде по всіх даних. Другий шлях —
AgglomerativeClustering з аргументом connectivity: якщо
заздалегідь сказати, які пари взагалі мають право злитись (скажімо, лише сусіди по графу
k найближчих), матриця стає розрідженою і памʼять перестає бути квадратичною. Ціна — той
самий ланцюжковий ризик, бо зʼєднання вздовж графа якраз і є ланцюжок.
І ще одна практична дрібниця, яку варто знати наперед. Ієрархічна кластеризація
не вміє приписати новий обʼєкт до вже готових груп: щоб додати один
рядок, треба перебудувати дерево. У k-means для цього досить порівняти відстані до
центрів. DBSCAN теж не має такого механізму — у scikit-learn у нього немає
навіть методу predict.
РазомТри форми, три методи
Час скласти все докупи. Ось три набори даних, на яких провалився k-means, і три методи на кожному з них. Девʼять станів — перебери всі й подивись, хто де виграє.
Девʼять відповідей
Перемикай форму й метод. Числа під картинкою пораховані на тих самих точках, що й у попередній темі.
eps = 0.6 і min_samples = 5: одні
параметри на всі три набори, як і було б у житті, поки не почнеш підбирати.
Ієрархічна — звʼязок Ворда (він стоїть за замовчуванням у
AgglomerativeClustering), дерево розрізане на дві групи. У вердикті
для порівняння названо, що дав би на цьому ж наборі одиночний звʼязок.Підсумок у трьох рядках, і жоден із них не про перемогу:
- Витягнуті смуги й кільця. DBSCAN — 100 % і 100 %, одиночний звʼязок — те саме. k-means і Ворд — 56–66 %, тобто нічого. Форма довільна вимагає методу, який дивиться на сусідів, а не на центри.
- Різна щільність. Ворд 96 %, k-means 89 %, DBSCAN 70 %, одиночний звʼязок 65 %. Порядок перевернувся повністю: те, що вигравало щойно, тепер програє найгірше.
- Жодна конфігурація не виграє скрізь. Ані одна пара
(
eps,min_samples), ані один звʼязок. Це не недогляд авторів методів — це властивість задачі, у якій немає правильної відповіді.
З цих девʼяти станів витягується правило, яке працює й поза цією сторінкою: метод не буває «кращим» чи «гіршим» — він робить припущення й виграє там, де припущення справдилось. k-means припускає кулі схожого розміру — і на кулях виграє. DBSCAN припускає однакову щільність усередині всіх груп — і виграє формою там, де щільність рівна. Ворд припускає те саме, що й k-means, тому й помиляється там само. Виходить, питання «який метод брати» насправді звучить як «що я готовий припустити про ці дані» — і відповідає на нього не метод, а той, хто на дані дивиться.
Практичний наслідок: якщо два методи на одних даних дали схожі групи, це сильний сигнал, що групи справжні. Якщо розійшлись — жоден із них не «правий», просто дані не задовольняють щонайменше одне з двох припущень, і треба зрозуміти, яке саме.
ВибірЩо обирати й що далі
Ось три методи в одній таблиці — не «який кращий», а що кожен припускає й на чому ламається.
| k-means | DBSCAN | Ієрархічна | |
|---|---|---|---|
| Що припускає про дані | кулясті групи схожого розміру | однакова щільність усередині всіх груп | нічого — усе вирішує обраний звʼязок |
| Що треба задати | k | eps, min_samples | звʼязок; кількість груп — після побудови |
| Форми кластерів | лише опуклі, межі прямі | будь-які | одиночний — будь-які, Ворда — кулясті |
| Що робить із дивними точками | приписує до найближчого центра | окрема мітка «шум» | лишає крихітними групами на великій висоті |
| Скільки рядків витримує | мільйони | мільйони (з індексом) | десятки тисяч |
| Новий обʼєкт без перерахунку | так | ні | ні |
| Головна пастка | випадковий старт, потреба знати k | підбір eps, різна щільність | вибір звʼязку міняє все |
А якщо стисло, то відповідь на питання «що брати» вміщується у три рядки:
- не знаєш, скільки груп → ієрархічна: дерево показує всі варіанти одразу, а зріз обираєш по широкій сходинці — проміжку висот без злиттів;
- не знаєш, якої вони форми, або цікавлять самі викиди → DBSCAN: він єдиний із трьох уміє сказати «ця точка ні з ким»;
- знаєш і те, і те, а рядків мільйони → k-means: він єдиний із трьох дешевий і єдиний, що вміє приписати новий обʼєкт без перерахунку всього.
Практичний порядок дій, який працює в більшості випадків: почни з
ієрархічної на підвибірці в кілька тисяч рядків, подивись на дендрограму — вона
покаже, скільки груп узагалі варто шукати. Далі, якщо групи схожі на грудки, візьми
k-means на всіх даних із цим k. Якщо на дендрограмі видно щось витягнуте або якщо
цікавлять саме дивні обʼєкти — бери DBSCAN і підбирай eps за коліном.
Лишилось одне питання, яке ми весь час обходили: усі картинки цієї теми двовимірні, бо намалювати можна лише два виміри. А оголошення описується сімома числами, клієнт банку — сотнею. Дивитись на кластери в семи вимірах ніхто не вміє, і тут стає в пригоді метод головних компонент із теми 11: він стискає багато ознак у дві так, щоб на них можна було подивитись і побачити те, що справді є в даних. Для DBSCAN у нього є й друга користь, суто технічна: просторовий індекс, без якого метод квадратичний, працює лише на невеликій кількості ознак (розділ 10).
А наступна тема бере мітку
−1 із цього уроку й робить із неї окрему задачу. Шум DBSCAN піймав на дошці
25 шахраїв зі 139 і майже не помилився — але це все, на що він здатен: поставити мітку
«так» або «ні». Пошук аномалій — про методи, які ранжують підозрілість числом, працюють,
коли дивних обʼєктів одиниці на тисячу, і не вимагають, щоб решта даних узагалі
розпадалась на кластери.