Машинне навчання · Блок 3 · Тема 12

Ієрархічна кластеризація та DBSCAN

k-means питає, де стоять центри. Ці два методи питають інше: де густо — і що з чим зливається раніше. Відповіді виходять зовсім не ті.

Попередня тема закінчилась трьома картинками, на яких відповідь була очевидно неправильною. Дві довгі смуги, які k-means розрізав упоперек, — 58 % точок на своїх місцях. Коло всередині кільця — 60 %. Щільна купка поруч із розсіяною хмарою — 89 %. Людське око бачить правильну відповідь за півсекунди, а метод її не бачить узагалі.

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

01 / Дві відповідіДві відповіді на одну невдачу

Обидві проблеми мають розвʼязок, і розвʼязки ці зовсім різні.

DBSCAN викидає з опису поняття центра. Замість «де середина групи» він питає «де точки стоять густо» — і нарощує кластер від сусіда до сусіда, куди б той не тягнувся. Смуга, кільце, підкова: якщо ланцюжок сусідів веде туди, кластер піде туди. Заразом він уміє те, чого k-means не вміє принципово, — сказати про окрему точку «це не кластер, це шум».

Ієрархічна кластеризація відповідає на другу проблему. Вона не видає одне розбиття. Вона будує дерево: спочатку кожен обʼєкт сам по собі, далі найближча пара зливається, далі наступна — аж поки все не стане однією групою. Кількість груп обираєш ти, але після побудови, дивлячись на дерево, а не наосліп до неї.

Працюємо на тих самих даних, що й у минулій темі. Наскрізний приклад — дошка оголошень про вживані телефони з теми 08: 1 100 оголошень із відомою ціною, дві ознаки — логарифм ціни й рік випуску, обидві приведені до z-оцінок. Плюс три синтетичні набори, на яких k-means провалився: витягнуті смуги, вкладені кільця, різна щільність. Ті самі точки, що й у темі 11, — щоб порівняння було чесним.

Масштаб і тут обовʼязковий. DBSCAN міряє відстані радіусом, ієрархічна — відстанями між групами. Обидва методи мовчки віддадуть усю владу тій колонці, у якої випадково найбільші числа. Правило з розділу 7 попередньої теми діє без винятків.

02 / ЩільністьКластер — це там, де густо

Уся ідея DBSCAN (density-based spatial clustering of applications with noise — кластеризація за щільністю з урахуванням шуму) тримається на одному спостереженні: усередині кластера точки стоять близько одна до одної, а між кластерами — порожньо. Не «кругло», не «навколо центра» — просто густо.

Щоб перетворити це на алгоритм, потрібні два числа, і задаєш їх ти.

Перші граблі, і вони тихі. У scikit-learn min_samples рахує разом із самою точкою. Тобто min_samples=3 означає «сама точка плюс щонайменше двоє сусідів», а не троє сусідів. Помилка на одиницю тут не викине винятку — вона просто змістить межу щільності.

Далі кожна точка отримує одну з трьох ролей, і ці три слова — весь словник методу.

рольумоващо це означає
Ядерна (core)у радіусі eps навколо неї — щонайменше min_samples точоквона стоїть у густому місці й має право нарощувати кластер далі
Гранична (border)сусідів замало, але вона сама лежить у радіусі якоїсь ядерноївона в кластері, але з неї кластер далі не росте — це край
Шум (noise)ні те, ні тежодного кластера; алгоритм чесно каже «ця точка ні з ким»

Візьмімо ті самі десять оголошень, на яких у минулій темі крутились ітерації k-means, і роздамо їм ролі. Радіус eps = 1.2 (нагадаю: одиниця тут — одне стандартне відхилення), min_samples = 3.

Схема 1 · Три ролі точки

Десять оголошень із розділу 3 попередньої теми. Навколо кожної точки — коло радіуса 1.2; підраховуємо, скільки точок у нього потрапило разом із нею самою.

оголошенняz (ціна, рік)точок у радіусі 1.2ролькластер
A1−0.5, 1.13ядерна1
A2−1.0, −1.12гранична2
A3−2.5, −1.52гранична2
A40.1, 1.54ядерна1
A50.6, 1.56ядерна1
A61.1, 0.74ядерна1
A71.0, 1.55ядерна1
A81.7, 1.54ядерна1
A90.4, −1.51шум
A10−2.0, −0.63ядерна2
Сім ядерних, дві граничні, один шум. A2 і A3 самі по собі стоять рідко — у їхніх колах лише по дві точки. Але обидві потрапили в коло ядерної A10 (відстані 1.12 і 1.03), тому їх приймають у другий кластер як край. У A9 в радіусі немає взагалі нікого: найближче до нього A2 на відстані 1.46. Це той самий Gamma X Ultra 2017 року, у якого в темі 11 силует був 0.205 — k-means мусив кудись його віднести, а DBSCAN просто каже «ні з ким».

03 / АлгоритмЯк розростається кластер

Ролі роздано — далі алгоритм майже тривіальний. Він обходить точки одну за одною:

1. беремо чергову ще не розглянуту точку 2. якщо вона не ядерна — поки що позначаємо як шум і йдемо далі 3. якщо ядерна — відкриваємо новий кластер і кладемо в чергу її сусідів 4. дістаємо точку з черги, приписуємо до цього кластера; якщо вона теж ядерна — дописуємо в чергу і її сусідів 5. черга спорожніла — кластер закінчився, повертаємось до кроку 1

Прокрутімо це на наших десяти. Перша точка — A1, вона ядерна, відкриваємо кластер 1 і кладемо в чергу її сусідів A4 і A5. A4 ядерна — дописуємо її сусідів A1, A5, A7. A5 ядерна — дописує A6, A7, A8. Черга крутиться, поки не вичерпається, і кластер 1 виходить такий: A1, A4, A5, A6, A7, A8. Далі беремо A2 — не ядерна, позначаємо шумом тимчасово. A3 — те саме. A9 — теж не ядерна. Аж ось A10: ядерна, відкриваємо кластер 2, у чергу йдуть A2 і A3 — обидві не ядерні, тому нікого далі не тягнуть, і кластер 2 = A10, A2, A3. A9 так і лишається шумом.

Зверни увагу на два наслідки, які видно вже на десяти точках.

Перший: кластер може мати будь-яку форму. Він росте ланцюжком, від сусіда до сусіда, і жодного «центра» ніхто не рахує. Довга змія завтовшки в два кроки — законний кластер DBSCAN і неможливий кластер k-means.

Другий, дрібніший і неприємний: гранична точка може дістатись різним кластерам. Якби A2 лежала в колах двох різних ядерних точок із різних кластерів, її забрав би той, до кого черга дійшла першою, — тобто результат залежав би від порядку рядків у таблиці. Ядерних точок це не стосується: вони розподіляються однозначно. На практиці граничних точок мало, але якщо два запуски на перетасованих даних дали трохи різні мітки — причина зазвичай саме тут.

04 / ПараметриДва повзунки, дві катастрофи

Тепер найважливіше про DBSCAN: усе тримається на двох числах. Кількість кластерів він і справді не питає — але eps і min_samples задають її неявно, і крайні значення дають дві протилежні катастрофи.

Візьмімо ті самі дві витягнуті смуги, які завалили k-means, і додамо до них пʼятнадцять розкиданих поодиноких оголошень — щоб було на що подивитись у графі «шум». Разом 145 точок: 130 у двох смугах і 15 самих по собі.

Інтерактив 1 · 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 — і саме тому в усіх прикладах цієї теми стоїть пʼятірка. Порада груба, але вона хоч якось привʼязує число до даних.

05 / Вибір epsЗвідки брати eps

З eps складніше, бо це відстань, і «правильної» відстані ніхто не знає. Стандартний прийом такий:

1. для кожної точки знайти відстань до її k-го найближчого сусіда (k беруть рівним min_samples − 1) 2. відсортувати всі ці відстані за зростанням 3. намалювати криву й шукати на ній «коліно» — місце, де вона з пологої різко йде вгору

Сенс простий. Поки крива йде полого, ми рухаємось по точках, які сидять у густих місцях: до четвертого сусіда їм рукою подати. Коли крива задирається вгору — почались точки, у яких сусідів поблизу немає. Висота коліна і є та відстань, яка ще вважається «близько».

Схема 2 · Відстань до четвертого сусіда, відсортована

Ліворуч — наші 145 точок зі смугами. Праворуч — 1 100 справжніх оголошень із дошки.

Ліворуч коліно є, праворуч його немає. На синтетичних смугах крива тримається нижче 0.5 для 129 точок і різко злітає на останніх шістнадцяти — це наші підкинуті одинаки плюс кілька крайніх точок смуг. Беремо eps з коліна — 0.45–0.50 — і отримуємо ідеальний розподіл. На дошці оголошень крива піднімається плавно: у половини оголошень четвертий сусід ближче ніж за 0.04, у 95 % — ближче ніж за 0.23, а далі відстань росте без жодного зламу. Це такий самий нечіткий критерій, як лікоть у k-means: він окреслює розумний діапазон і не називає числа.

06 / ШумШум — це відповідь

Тепер про властивість, якої немає в жодного методу з попередньої теми. DBSCAN не зобовʼязаний віднести кожну точку до кластера. У scikit-learn такі точки дістають мітку −1.

Звучить як вада — «алгоритм не впорався». Насправді це чесність. Коли k-means приписує дике оголошення до найближчого сегмента, він не додає знання, а ховає його: у групі «дешеві старі» тепер сидить телефон за 130 грн, який не схожий узагалі ні на що.

Подивись, що з цього виходить на справжніх даних. Запускаємо DBSCAN на всіх 1 100 оголошеннях дошки з eps = 0.3 і min_samples = 5. Результат такий: 12 кластерів і 26 оголошень у шумі. І ось найцікавіше число всієї теми: із цих 26 оголошень 25 позначені в таблиці як шахрайські. Алгоритм цієї колонки не бачив.

що вважаємо підозрілимточністьповнотаF1
шум DBSCAN (26 оголошень)0.9620.1800.303
найдешевший кластер k-means (тема 11)0.2060.5250.296
випадковий тик, 355 оголошень0.1260.3230.182

Читається це так. Шум DBSCAN майже не помиляється: з 26 піднятих тривог хибна одна. Але й ловить він мало — 25 шахраїв зі 139, тобто 18 %. Це ціни-приманки на кшталт 130 і 190 грн і завищені 45 320 та 83 500 грн: те, що стоїть на самому краю. Звичайного шахрая з ціною «трохи нижче ринку» жодна щільність не виловить, бо він лежить у гущі.

Це і є місток до передостанньої теми блоку. Задача «знайди дивне, не маючи жодного прикладу дивного» зветься пошуком аномалій, і шум DBSCAN — її найпростіший інструмент. Там будуть методи, які роблять це прицільно й уміють ранжувати підозрілість, а не лише ставити мітку −1.
А тепер чесно про ті 12 кластерів. Це не 12 сегментів ринку. Рік випуску — ціле число, і в z-оцінках сусідні роки стоять на відстані 0.43. Поки eps менший за 0.43, вертикальних звʼязків між роками просто немає, і дошка розпадається на горизонтальні смуги «всі оголошення 2019-го», «всі оголошення 2020-го». Варто підняти eps до 0.5 — і 1 089 оголошень зливаються в один суцільний кластер. Ніякої проміжної відповіді на цих даних немає: або смуги за роками, або одна хмара. Це не поламаний DBSCAN — це чесна відповідь про дошку: щільнісно відокремлених груп на ній немає.

07 / ВадаОдна щільність на всіх

Головна вада DBSCAN схована в тому самому місці, що й перевага: eps у нього один на весь простір. Метод припускає, що всі справжні кластери мають приблизно однакову густину. Коли це не так, вибирати доводиться між двома поразками. Обидва способи виразно кращі за жеребкування, але жоден не наближається до того, що дає розмітка: далі в курсі, коли дійдемо до моделей із учителем, та сама задача розвʼязується вчетверо точніше.

Це рівно той третій випадок із минулої теми — щільна купка й розсіяна хмара поруч, де k-means дав 89 %. З параметрами, які ідеально спрацювали на смугах і кільцях (eps = 0.6, min_samples = 5), DBSCAN дає на ньому 70 %: щільну купку знаходить бездоганно, а розсіяну хмару рве на уламки й 30 її точок зі 150 оголошує шумом.

Можна підібрати eps під розсіяну хмару — 0.85. Тоді кластерів рівно два, шуму лише 9 точок, а на своїх місцях 88 %. Це найкраще, що DBSCAN взагалі може видати на цих даних, — і воно все одно трохи гірше за k-means. Причому дійти до цього числа можна, тільки підглядаючи у правильну відповідь, якої в реальній задачі немає.

Розширення, яке це лагодить. HDBSCAN (hierarchical DBSCAN) не бере eps взагалі. Він проганяє DBSCAN подумки одразу для всіх радіусів, будує з цього дерево — так, те саме дерево, що й у другій половині цієї теми, — і залишає ті кластери, які тримаються найдовше. Через це він здатен знаходити групи різної щільності однією моделлю. Чарівної палички з нього теж не виходить — на невеликих вибірках він помиляється не менше, і перевіряти його доводиться так само руками. Ціна — складніша реалізація й окремий пакет (hdbscan, а у свіжих версіях scikit-learnHDBSCAN). Ідею варто знати; коли eps ніяк не підбирається, це перше, що слід спробувати.

08 / ДеревоДерево замість розбиття

Другий метод теми починається з іншого питання. Не «де густо», а «що з чим схоже найбільше».

Уся ідея. Спочатку кожне оголошення — окремий кластер, їх рівно стільки, скільки рядків. Знаходимо дві найближчі групи й зливаємо їх в одну. Знову знаходимо найближчі та зливаємо. І так n − 1 разів, поки все не стане однією групою. Записуємо, хто з ким і на якій відстані злився, — це і є результат.

Такий напрямок — від окремих точок догори — зветься агломеративним (agglomerative, від «нагромаджувати»). Буває й зворотний, дивізивний: почати з однієї групи й ділити її. На практиці майже завжди беруть агломеративний, бо він простіший і передбачуваний.

Результат — не набір міток, а дендрограма (dendrogram, «деревна діаграма»). Читається вона так:

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

Інтерактив 2 · Дендрограма з рухомим зрізом

Двадцять вісім оголошень із дошки, злиття за середньою відстанню. Тягни повзунок — і дивись, скільки груп дає зріз і як вони лягають на площину.

груп
найбільша
одинаків
наст. злиття
Осі. На дендрограмі знизу — 28 оголошень, по вертикалі — відстань злиття в z-оцінках. На правій картинці — ті самі оголошення: по горизонталі ціна (логарифмічна шкала), по вертикалі рік випуску. Найвище злиття тут на висоті 2.81 — остання, вимушена перемичка: воно зʼєднує девʼять свіжих оголошень 2023–2024 років з усіма іншими девʼятнадцятьма. Опустись до 1.30 — і дерево дає пʼять груп: свіжі діляться на дешевші й дорогі, старі — на три цінові смуги. Довга вертикаль без перемичок означає групу, яка довго ні з ким не зливалась, тобто добре відокремлену.

09 / LinkageЧим міряти відстань між групами

В описі методу є одне слово, повз яке легко проскочити: «знаходимо дві найближчі групи». А що таке відстань між групами? Між двома точками вона очевидна. Між купкою з семи точок і купкою з дванадцяти — ні.

Відповідей чотири, вони звуться звʼязком (linkage), і вибір між ними міняє результат сильніше, ніж будь-що інше в методі.

звʼязоквідстань між групами — це…що з цього виходить
Одиночний (single)відстань між двома найближчими точками групгрупи ростуть ланцюжками; знаходить змії й кільця, але злипається через один випадковий місток
Повний (complete)відстань між двома найдальшими точкамигрупи виходять компактні, приблизно кулясті; довгу смугу розріже
Середній (average)середнє з усіх попарних відстаней між групамикомпроміс між першими двома, найчастіше — розумна поведінка за замовчуванням
Ворда (ward)наскільки зросте сума квадратів відстаней усередині груп, якщо їх злитимінімізує рівно те, що й інерція k-means; кулясті групи схожого розміру

Найважливіший із цих чотирьох рядків — перший, і зветься це ланцюжковим ефектом. Одиночному звʼязку досить, щоб дві групи зʼєднала одна ланцюжкова доріжка з точок: далі він проковтне обидві. Це рівно те, що робить кластер DBSCAN довільної форми, — і рівно те, через що одиночний звʼязок розсипається на реальних даних. Ось наша дошка, ієрархічна кластеризація, три групи:

одиночний 1 094 · 5 · 1 ← один велетень і дві порошинки середній 1 089 · 8 · 3 ← те саме повний 656 · 433 · 11 Ворда 439 · 360 · 301 ← єдине розбиття, з яким можна працювати

А тепер те саме на синтетиці, де правильна відповідь відома, — і виявиться, що переможець міняється місцями з невдахою.

Схема 3 · Чотири звʼязки, два набори даних

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

Дзеркальний результат. На смугах одиночний звʼязок дає ідеальні 65 і 65 точок — рівно дві смуги, 100 %. Решта три ріжуть картинку впоперек, як k-means. На різній щільності все навпаки: одиночний і середній відкушують від хмари лише по дві точки, повний — шість, і всі троє лишають велетня на 144–148, тобто не дають нічого (64.7 %, 67.3 %, 64.7 %), а Ворд знаходить обидві групи майже точно — 96 %. Один і той самий звʼязок виграє в одному наборі й програє в іншому, і вибирати доводиться до того, як побачиш відповідь.

10 / ЦінаСкільки це коштує

За зручність «одразу вся ієрархія» доводиться платити, і платня росте квадратично. Щоб знайти найближчу пару, треба знати всі попарні відстані — а їх для n обʼєктів приблизно n²/2.

1 000 оголошень 500 тисяч відстаней 4 МБ памʼяті 10 000 оголошень 50 мільйонів 400 МБ 100 000 оголошень 5 мільярдів 40 ГБ ← кінець

Тобто ієрархічна кластеризація — метод для тисяч рядків, не для мільйонів. На сотнях тисяч вона просто не запуститься на звичайній машині. У DBSCAN та сама квадратична біда в наївній реалізації, але її лагодить просторовий індекс: scikit-learn шукає сусідів у радіусі через KD-дерево й на низьких розмірностях працює приблизно за n·log n. Тому DBSCAN на мільйоні рядків — реально, а дендрограма на мільйоні — ні.

І ще одна практична дрібниця, яку варто знати наперед. Ієрархічна кластеризація не вміє приписати новий обʼєкт до вже готових груп: щоб додати один рядок, треба перебудувати дерево. У k-means для цього досить порівняти відстані до центрів. DBSCAN теж не має такого механізму — у scikit-learn у нього немає навіть методу predict.

11 / РазомТри форми, три методи

Час скласти все докупи. Ось три набори даних, на яких провалився k-means, і три методи на кожному з них. Девʼять станів — перебери всі й подивись, хто де виграє.

Інтерактив 3 · Девʼять відповідей

Перемикай форму й метод. Числа під картинкою пораховані на тих самих точках, що й у попередній темі.

форма даних
метод
на своїх місцях
кластерів
шум
розміри
Умови однакові для всіх. k-means — при k = 2, з найкращого з кількох стартів. DBSCAN — з eps = 0.6 і min_samples = 5: одні параметри на всі три набори, як і було б у житті, поки не почнеш підбирати. Ієрархічна — звʼязок Ворда (він стоїть за замовчуванням у AgglomerativeClustering), дерево розрізане на дві групи. У вердикті для порівняння названо, що дав би на цьому ж наборі одиночний звʼязок.

Підсумок у трьох рядках, і жоден із них не про перемогу:

12 / ВибірЩо обирати й що далі

Ось три методи в одній таблиці — не «який кращий», а що кожен припускає й на чому ламається.

k-meansDBSCANІєрархічна
Що припускає про данікулясті групи схожого розміруоднакова щільність усередині всіх групнічого — усе вирішує обраний звʼязок
Що треба задатиkeps, min_samplesзвʼязок; кількість груп — після побудови
Форми кластерівлише опуклі, межі прямібудь-якіодиночний — будь-які, Ворда — кулясті
Що робить із дивними точкамиприписує до найближчого центраокрема мітка «шум»лишає крихітними групами на великій висоті
Скільки рядків витримуємільйонимільйони (з індексом)десятки тисяч
Новий обʼєкт без перерахункутакніні
Головна пасткавипадковий старт, потреба знати kпідбір eps, різна щільністьвибір звʼязку міняє все

Практичний порядок дій, який працює в більшості випадків: почни з ієрархічної на підвибірці в кілька тисяч рядків, подивись на дендрограму — вона покаже, скільки груп узагалі варто шукати. Далі, якщо групи схожі на грудки, візьми k-means на всіх даних із цим k. Якщо на дендрограмі видно щось витягнуте або якщо цікавлять саме дивні обʼєкти — бери DBSCAN і підбирай eps за коліном.

Лишилось одне питання, яке ми весь час обходили: усі картинки цієї теми двовимірні, бо намалювати можна лише два виміри. А оголошення описується сімома числами, клієнт банку — сотнею. Дивитись на кластери в семи вимірах ніхто не вміє — і саме тому наступна тема про метод головних компонент: як стиснути багато ознак у дві так, щоб на них можна було подивитись і побачити те, що справді є в даних. А після неї — пошук аномалій, куди веде мітка −1 із цієї теми.

Далі в практиці. У practice.ipynb ми напишемо DBSCAN із нуля й звіримо мітки з бібліотечним; проженемо всі три методи на трьох формах і складемо таблицю з ARI; підберемо eps за графіком k-ї відстані; порівняємо чотири звʼязки на одних даних; побудуємо дендрограму через scipy.cluster.hierarchy; і наприкінці прикладемо всі три методи до справжньої дошки оголошень і чесно звіримо результат із колонкою шахрайське.

Далі в темі

Теорію прочитано. Тепер закріпи її на практиці.