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

Кластеризація k-means

Двадцять пʼять тем ми звіряли прогноз із правильною відповіддю. Тепер правильної відповіді немає — і з цього починається зовсім інша половина машинного навчання.

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

Це не поламана задача — це інша задача, і вона зветься навчанням без учителя (unsupervised learning). Замість «передбач відповідь» тут питають: яка структура є в цих даних сама по собі. Найпростіша форма такого питання — кластеризація (clustering): розкласти обʼєкти на групи так, щоб усередині групи вони були схожі між собою, а між групами — різні.

Працюватимемо на тій самій дошці оголошень про вживані телефони, що і в темі 08. Але задача інша. Там ми знали, які оголошення шахрайські, і шукали в даних сліди цієї відповіді. Тепер питання таке: які сегменти ринку існують на цій дошці об'єктивно, за самою будовою даних, якщо ніхто нам нічого не розмічав?

01 / ПостановкаЗадача без правильної відповіді

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

Зникає метрика в тому сенсі, до якого ти звик. F1, RMSE, ROC-AUC — усі вони рахують те саме: наскільки прогноз близький до правильної відповіді. Немає відповіді — немає й числа. Метрики для кластеризації існують (одну з них, силует, ми розберемо в розділі 6), але вони міряють форму розбиття: наскільки групи щільні й наскільки далеко одна від одної. Це не те саме, що «правильно».

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

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

Це не причіпка, а робочий факт. Якщо хтось показує кластеризацію зі словами «алгоритм знайшов чотири типи клієнтів», правильне питання — не «яка точність», а «чому чотири й що ти з цим зробиш». Кластеризація не відкриває істину; вона пропонує спосіб дивитись на дані.

Тоді навіщо вона взагалі? Через чотири речі, і кожна з них траплятиметься тобі частіше, ніж здається.

навіщощо саме роблятьприклад на нашій дошці
Сегментаціярозкласти обʼєкти на групи, з якими далі працюють по-різномудешеві старі телефони, свіжі дорогі, міцна середина — для кожного сегмента своя порада продавцеві
Стисненнязамінити обʼєкт номером його групи або координатами центразамість двох чисел на оголошення — один номер сегмента; так стискають кольори в зображеннях і сигнали в звуці
Розвідкапобачити будову даних до того, як ставити гіпотезичи є на дошці окрема група «майже нових дорогих» — чи це просто хвіст однієї великої хмари
Підготовкарозбити велику задачу на кілька менших або заповнити пропуски по групіпропущену ціну заповнити медіаною свого сегмента, а не всієї таблиці (тема 09)

Спільне в усіх чотирьох одне: результат оцінюють за тим, чи став кориснішим наступний крок, а не за збігом із розміткою.

Наші дані на цю тему такі. Беремо з дошки 1 100 оголошень, у яких є ціна (у решти вона пропущена, а кластеризація на відстанях без числа працювати не вміє), і рівно дві ознаки: ціну й рік випуску. Двох досить, щоб усе бачити на площині; у практиці додамо третю й подивимось, що зміниться.

Ціну беремо не в гривнях, а як логарифм ціни. Причина стара й знайома з теми 10: різниця між 1 000 і 2 000 грн для покупця така сама, як між 10 000 і 20 000, а в гривнях це 1 000 проти 10 000. Логарифм робить ці дві відстані однаковими. Далі обидві ознаки приводимо до спільної шкали — z-оцінки: віднімаємо середнє, ділимо на стандартне відхилення. Чому це не порада, а обовʼязок, розберемо в розділі 7, і там буде видно, у що виливається пропуск цього кроку.

02 / ІдеяІдея k-середніх

Метод k-середніх (k-means) описується одним абзацом, і це майже вся теорія.

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

Розберемо три слова, бо кожне щось приховує.

«Найближчий» — за звичайною евклідовою відстанню (euclidean distance). Це та сама відстань, яку на аркуші паперу дає теорема Піфагора. Дві ознаки — два катети: різниця по ціні й різниця по році. Відстань між точками — гіпотенуза: піднеси кожну різницю до квадрата, склади й візьми корінь. Скажімо, від точки (0.4; −0.3) до точки (1.0; 0.5) різниці дорівнюють 0.6 і 0.8, квадрати — 0.36 і 0.64, сума — 1.00, корінь — 1.00. Ознак більше двох — правило не міняється: квадрат різниці по кожній, усе додати, взяти корінь.

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

«Середина групи» — це середнє арифметичне координат усіх її точок, окремо по кожній ознаці. Звідси й назва: k середніх. Ця точка зветься центроїдом (centroid) і зазвичай не збігається з жодним реальним оголошенням — це вигадана «типова» точка групи.

«k» — кількість груп, і її задаєш ти. Алгоритм її не шукає й не може знайти: скільки попросиш, стільки й нарисує. Це найважливіше обмеження методу, і розділ 6 цілком про нього.

Формально алгоритм (його звуть алгоритмом Ллойда) — це чотири рядки:

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

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

03 / РукамиТри ітерації руками

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

Обидві ознаки вже переведені в z-оцінки й округлені до одного знака, щоб арифметика лишалась читабельною. Нагадаю, як читати z: нуль — це середнє по всій дошці, −1 — на одне стандартне відхилення нижче, +1.5 — на півтора вище. Для ціни «нуль» — це приблизно 4 075 грн, для року — 2020-й.

A1 Alfa A5 2023 2 460 грн z = (−0.5, 1.1) A2 Alfa A7 2018 1 530 грн z = (−1.0, −1.1) A3 Alfa A5 2017 370 грн z = (−2.5, −1.5) A4 Alfa A5 2024 4 400 грн z = ( 0.1, 1.5) A5 Alfa A7 2024 7 320 грн z = ( 0.6, 1.5) A6 Alfa A5 2022 11 050 грн z = ( 1.1, 0.7) A7 Beta 12 2024 10 210 грн z = ( 1.0, 1.5) A8 Gamma X 2024 19 480 грн z = ( 1.7, 1.5) A9 Gamma X Ultra 2017 5 830 грн z = ( 0.4, −1.5) A10 Alfa A5 2019 620 грн z = (−2.0, −0.6)

Стартові центри поставимо в два реальні оголошення — A3 і A9. Вибір поганий: обидва з 2017 року, тобто обидва центри стоять на самому дні картинки. Це навмисно — так добре видно, як вони звідти виповзають.

Таблиця 1 · Три ітерації, усі числа

Для кожного оголошення — квадрат відстані до першого й до другого центра. Менший із двох виділено: саме туди точка й іде.

ітерація 1 ітерація 2 ітерація 3
оголошенняz d² до K1d² до K2 d² до K1d² до K2 d² до K1d² до K2
A1−0.5, 1.110.767.57K27.691.06K26.471.31K2
A2−1.0, −1.12.412.12K21.575.09K10.706.65K1
A3−2.5, −1.50.008.41K10.2713.18K10.6315.55K1
A40.1, 1.515.769.09K212.030.83K210.330.64K2
A50.6, 1.518.619.04K214.630.75K212.510.36K2
A61.1, 0.717.805.33K214.290.46K211.730.26K2
A71.0, 1.521.259.36K217.071.05K214.620.50K2
A81.7, 1.526.6410.69K222.112.35K219.071.51K2
A90.4, −1.58.410.00K27.234.62K25.185.81K1
A10−2.0, −0.61.066.57K10.277.44K10.259.16K1
центр K1−2.500, −1.500−2.250, −1.050−1.833, −1.067
центр K20.400, −1.5000.425, 0.6500.629, 0.900
інерція54.2613.2211.33
Як читати. Три нижні рядки — це центри, з якими рахувалась ця ітерація, і сума квадратів відстаней до свого центра при них. Після ітерації 3 центри стають (−1.275, −1.175) і (0.667, 1.300), сума падає до 9.07, а на четвертій ітерації жодна точка не змінює групу — алгоритм зупиняється.

Простеж очима три речі.

Перша: центри виповзають з дна. K1 пройшов шлях (−2.5, −1.5) → (−2.25, −1.05) → (−1.833, −1.067) → (−1.275, −1.175), K2 — (0.4, −1.5) → (0.425, 0.65) → (0.629, 0.9) → (0.667, 1.3). Ніхто їх не тягнув: кожен просто щоразу ставав середнім своїх точок.

Друга: приналежність міняється, і не один раз. На першій ітерації A2 пішло до K2, на другій повернулось до K1. A9 три ітерації трималось за K2 і перебігло до K1 аж на третій — там різниця була мізерна, 5.18 проти 5.81. Оголошення на межі перекидаються туди-сюди довше за всіх, і ми ще повернемось до A9 в розділі 6.

Третя: сума квадратів падає весь час — 54.26, 13.22, 11.33, 9.07. Вона й є те, що метод мінімізує, і зараз розберемось чому саме вона.

А тепер те саме, але на всіх 1 100 оголошеннях і з трьома центрами. Тисяча сто точок руками не порахуєш, зате видно те, чого не видно в таблиці, — як межі між групами переповзають картинкою.

Інтерактив 1 · Ітерації наочно

Тисяча сто оголошень, три центри, поставлені в три випадкові оголошення. Тисни «крок» і дивись, як точки перефарбовуються, центри переїжджають, а інерція спадає.

наступний півкрок
що будерозподілити точки
ітерація0
інерція
зміна
перебігло
Осі. Горизонтальна — ціна оголошення, шкала логарифмічна (тому підписи 300 ₴, 1 000 ₴, 3 000 ₴ стоять на однаковій відстані). Вертикальна — рік випуску; років усього вісім, тому точки лягають вісьмома рядами. Тло залито областями центрів: у кожній точці екрана показано, який центр там найближчий. Саме ці області й переїжджають разом із центрами — і після півкроку «пересунути центри» частина точок опиняється у чужій за кольором області. Їх наступний півкрок і перефарбує.

04 / ІнерціяЩо саме мінімізується

Ми жодного разу не сказали алгоритму, чого домагатись. А він домагається — і цілком конкретної величини. Вона зветься інерцією (inertia), і це сума квадратів відстаней від кожної точки до центра її власного кластера:

J = Σусі точки ‖ xi − c(кластер точки i) ‖²

Словами: візьми кожне оголошення, зміряй відстань до центра його групи, піднеси до квадрата, склади все. Символ xi — координати i-го оголошення, c — координати центра тієї групи, у яку воно потрапило, подвійні риски — довжина вектора між ними, тобто відстань. Що менша інерція, то щільніше точки тиснуться до своїх центрів.

Чому саме квадрат, а не сама відстань? Дві причини. Перша практична: квадрат позбавляє кореня, і все стає простішим. Друга змістовна: середнє арифметичне — рівно та точка, яка мінімізує суму квадратів відстаней. Не сума відстаней, а сума їхніх квадратів. Тобто крок «постав центр у середнє» — не інтуїція, а точний розвʼязок задачі мінімізації. Ось він у два рядки, для однієї ознаки:

крок 1 · що мінімізуємо

Шукаємо точку c, для якої сума квадратів відстаней до заданих чисел x1…xn найменша.

f(c) = (x1 − c)² + (x2 − c)² + … + (xn − c)²
крок 2 · де мінімум

Це парабола, вітками вгору: мінімум там, де похідна дорівнює нулю.

f ′(c) = −2(x1 − c) − … − 2(xn − c) = 0
крок 3 · відповідь

Ділимо на −2 і розкриваємо: сума всіх x мінус n·c дорівнює нулю. Отже:

c = (x1 + … + xn) ÷ n

Тобто середнє арифметичне. Для двох ознак те саме рахується окремо по кожній — вони в цій сумі не переплітаються.

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

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

І тут головна пастка. Ми довели, що інерція не зростає. Ми не довели, що вона доходить до найменшого можливого значення. Алгоритм зупиняється у першій же точці, де жоден із двох кроків уже нічого не міняє, — а таких точок багато, і вони різні. Це локальний мінімум: краще за сусідів, але не обовʼязково краще за всіх. Знайти справжній глобальний мінімум для k-means — задача, яку в загальному випадку ніхто швидко розвʼязувати не вміє.

Ще одна властивість інерції, про яку варто памʼятати заздалегідь: вона завжди спадає, коли ростить k. Більше центрів — коротші відстані. При k, рівному кількості точок, кожна точка стає власним центром і інерція дорівнює нулю. Тому питання «яке k дає найменшу інерцію» безглузде, і в розділі 6 доведеться шукати інший підхід.

05 / СтартРізний старт — різна відповідь

Локальний мінімум — не теоретичне застереження. Це те, з чим ти зіткнешся на першому ж запуску, і виглядає воно так: та сама функція, ті самі дані, два запуски — дві різні відповіді.

Ось чотири запуски k-means на наших 1 100 оголошеннях, k = 3. Різниця між ними тільки в тому, у які три оголошення поставлено початкові центри.

Інтерактив 2 · Чотири старти, чотири відповіді

Перемикай стартову розкладку. Порожні кружечки — де центри стояли спочатку, ромби — куди приїхали. Дивись на інерцію внизу праворуч.

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

Найкращий із чотирьох стартів дає інерцію 803.43, найгірший — 880.78. Це на 9.6 % більше, і різниця не косметична: у поганому розбитті одна група збирає дешеві телефони всіх років підряд, а «свіжі» й «старі» розлазяться по двох інших групах. Сегменти виходять інші, і бізнес-висновок із них теж інший.

Проти цього є два прийоми, і в scikit-learn обидва увімкнені за замовчуванням — саме тому новачок про проблему може так і не дізнатись.

k-means++ — розумний старт

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

1. перший центр — випадкове оголошення 2. для кожного оголошення рахуємо d² — квадрат відстані до найближчого вже обраного центра 3. наступний центр тягнемо випадково, але з імовірністю, пропорційною цьому d² 4. повторюємо, поки центрів не стане k

Тобто далекі від усіх обраних центрів точки мають найбільший шанс стати наступним центром. Випадковість лишається, але тепер вона зміщена в бік розкиданих стартів. У scikit-learn це параметр init="k-means++", і він стоїть за замовчуванням.

n_init — просто спробувати кілька разів

Другий прийом прямолінійніший: запустити алгоритм кілька разів із різних стартів і лишити той результат, у якого інерція найменша. Це параметр n_init. Порівнювати запуски між собою можна саме тому, що інерцію рахують без жодних міток.

Скільки ставити. У сучасних версіях за замовчуванням стоїть n_init="auto", і з k-means++ це один запуск. Поставити n_init=10 коштує майже нічого й помітно зменшує ризик випадково зупинитись у поганому мінімумі. І обовʼязково фіксуй random_state: без нього два запуски того самого коду дадуть різні кластери, і ти згаєш годину, шукаючи неіснуючу помилку у власних даних.

06 / Скільки групСкільки брати кластерів

Найчастіше питання про k-means і найчесніша відповідь на нього: універсального способу немає. Є два інструменти, які звужують вибір, і жоден із них не звужує його до однієї цифри.

Метод ліктя

Побудуємо інерцію для k від 1 до 10. Вона спадає завжди — це ми вже знаємо. Але спадає нерівномірно: спочатку кожен новий кластер приносить величезну користь, а потім уже майже ніякої. Точка, де крива з обриву переходить у пологий схил, і зветься ліктем.

Ось падіння інерції на наших даних, крок за кроком:

k = 1 → 2 інерція 2200.0 → 1069.7 впала на 1130.3 k = 2 → 3 інерція 1069.7 → 803.4 впала на 266.2 k = 3 → 4 інерція 803.4 → 573.9 впала на 229.6 k = 4 → 5 інерція 573.9 → 480.6 впала на 93.2 k = 5 → 6 інерція 480.6 → 392.2 впала на 88.4 k = 6 → 7 інерція 392.2 → 347.8 впала на 44.4

Де тут лікоть? Найбільший обвал — на другому кластері, але це нікому не цікаво: розбиття на дві групи буває корисним завжди. Далі два кроки поспіль дають схожу користь (266 і 230), а потім користь одразу падає більш ніж удвічі (93). Тобто лікоть десь на четвірці — але «десь», бо між 3, 4 і 5 крива згинається плавно, і три різні люди покажуть пальцем у три різні точки.

Це не вада наших даних. Різкий лікоть буває тоді, коли в даних справді є кілька відокремлених грудок — а в реальних таблицях вони частіше зливаються в одну хмару зі згущеннями. Метод ліктя чесно показує саме це.

Силует

Другий інструмент дивиться не на суму відстаней, а на кожну точку окремо й питає: чи вона взагалі в тій групі, у якій має бути? Величина зветься силуетом (silhouette). Для точки i беруть дві середні:

s = (b − a) ÷ max(a, b)

Ділення на більше з двох тримає результат у межах від −1 до +1, і читається він так:

Порахуймо силует руками для оголошення A9 — того самого Gamma X Ultra 2017 року за 5 830 грн, яке дві ітерації вагалось між групами. У фінальному розбитті десятки воно опинилось у групі «старі й дешеві» разом із A2, A3 і A10.

Схема 1 · Силует однієї точки

Десять оголошень із розділу 3, фінальне розбиття. Бірюзові відрізки — відстані до своїх, рожеві — до чужих.

Дві середні — і одна різниця. Відстані до своїх: 1.456, 2.900, 2.563 → a = 2.306. Відстані до шести чужих: 2.751, 3.015, 3.007, 2.309, 3.059, 3.270 → b = 2.902. Отже s = (2.902 − 2.306) ÷ 2.902 = 0.205. Для порівняння, у A5 (Alfa A7 2024 року) a = 0.823, b = 3.429 і s = 0.760. Середній силует по всіх десяти — 0.581.

0.205 — майже нуль, і це чесно описує становище A9: телефон дорогий, як у «свіжих», а рік як у «старих». Алгоритм мусив кудись його віднести й відніс, але впевненості в цьому рішенні немає ніякої.

Щоб оцінити ціле розбиття, силует усереднюють по всіх точках, і найкращим вважають те k, при якому середнє найбільше. Так радять усі підручники. Подивись, що з цієї поради виходить на реальних даних.

Інтерактив 3 · Вибір k

Тягни повзунок. Ліворуч — саме розбиття, знизу — крива інерції (лікоть) і крива силуету. Вони показують на різні числа.

інерція803.4
силует0.384
падіння266.2
найм. група264
Найбільший середній силует — при k = 2 (0.444). Лікоть на кривій інерції читається радше як k = 4. Обидва числа пораховані чесно, і вони не збігаються. Побачити на кривій силуету другий горбик при k = 7 (0.401) теж корисно: це майже завжди не «сім справжніх сегментів», а один крихітний щільний кластер, який підняв середнє.

Отже, лікоть каже 4, силует каже 2, і жоден із них не бреше. Так буває частіше, ніж навпаки — і з цього треба зробити правильний висновок, а не шукати третю метрику як арбітра.

Останнє слово за задачею, а не за метрикою. Ці два числа окреслюють розумний діапазон: десь від 2 до 5, а не 30. Усередині діапазону вибирає людина, і критерій у неї інший — з чим я зможу працювати. Нам для дошки оголошень потрібні сегменти, які можна назвати словами й показати менеджерові, тому далі беремо k = 3. Це рішення, і воно записане як рішення, а не видане за відкриття.

Ось що дають ці три сегменти при k = 3 (нагадаю: центр — вигадана «типова» точка групи, а не конкретне оголошення):

сегментоголошеньцентряк це читається
Дешеві старі3551 478 грн · 2018.9телефони, які дослужують останній рік; ціна нижча за дві тисячі
Міцна середина2645 795 грн · 2018.6той самий вік, але дорожчі моделі — колишній верхній сегмент, що подешевшав
Свіжі дорогі4817 098 грн · 2022.7усе, що молодше за 2021 рік, від бюджетних до найдорожчих

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

07 / МасштабМасштаб ознак обовʼязковий

Ми двічі мимохідь сказали «приводимо ознаки до z-оцінок». Настав час показати, що буває, якщо цього не зробити, — бо це найпоширеніша й найтихіша помилка в кластеризації.

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

ціна стандартне відхилення 8 685 грн рік стандартне відхилення 2.31 року

Різниця у 3 765 разів. У формулі відстані обидві різниці підносяться до квадрата й додаються — отже, доданок від ціни у мільйони разів більший за доданок від року. Ознака «рік» присутня у формулі й не впливає ні на що.

Схема 2 · Одні й ті самі дані, два масштаби

Ліворуч — k-means на сирих гривнях і роках. Праворуч — на тих самих даних, приведених до z-оцінок. Колір = кластер.

Ліворуч рік не впливає ні на що. Кожен із трьох кластерів містить оголошення всіх років з 2017-го по 2024-й, а межі між ними — вертикальні лінії по ціні: до 11 390 ₴, далі до 45 320 ₴, далі решта. Причому цінові смуги виходять безглузді: у першій сидять 956 оголошень із 1 100, в останній — 8. Праворуч — те саме після масштабування. Збіг двох розбиттів між собою — на рівні випадкового (індекс Ренда −0.004).

Зверни увагу на ліву картинку уважніше. Річ не тільки в тому, що рік проігноровано. Сама ціна поділена так, що користі з цього нуль: 956 оголошень в одній купі, 8 — в окремому кластері. Причина в тому, що кілька дуже дорогих оголошень (колекційні Gamma X і одруки із зайвим нулем, знайдені ще в темі 08) відтягли на себе цілий центр.

Правило без винятків. Будь-який метод, який рахує відстані — k-means, ієрархічна кластеризація і DBSCAN із наступної теми, а далі в курсі й моделі з учителем, що спираються на відстань, — вимагає приведення ознак до спільної шкали. Не «бажано», а вимагає: без цього результат визначає та колонка, у якої випадково виявились найбільші числа. І зверни увагу, що тут, на відміну від теми 09, немає ризику витоку через масштабування на всіх даних — тесту немає, ділити нічого. Це один із небагатьох випадків, коли fit_transform на всій таблиці — правильно.

Логарифм ціни при цьому не заміна масштабуванню, а окремий крок: він зменшує хвіст, щоб кілька оголошень по 80–95 тисяч не перетягнули на себе центр, а z-оцінка потім зрівнює шкали. Потрібні обидва.

08 / МежіЧого k-means не вміє

У самій будові методу заховане припущення, яке ніде не написане, але діє завжди. Кожна точка йде до найближчого центра — отже, межа між двома кластерами завжди пряма (у трьох вимірах — площина). Кластер, який отримує k-means, — це опукла область навколо свого центра, приблизно кругла.

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

Схема 3 · Три випадки, де відповідь очевидно неправильна

У кожному наборі людина бачить групи одразу. Кольори — те, що знайшов k-means при k = 2.

Що сталось у кожному випадку. Витягнуті: дві довгі смуги лежать одна над одною, а k-means розрізав їх упоперек — зі 130 точок на своїх місцях лише 58 %. Вкладені кола: внутрішнє коло й кільце навколо нього; центри обох груп збігаються, тому будь-яка пряма межа помиляється — 60 %. Різна щільність: щільна купка ліворуч і розсіяна хмара праворуч; межа проходить надто далеко праворуч і 16 точок розсіяної групи з 55 відходять до щільної — 89 %.

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

Є ще три речі, про які варто знати заздалегідь.

09 / ПеревіркаЧи означають кластери щось

Тепер найчесніша частина теми. У нашій таблиці все-таки є колонка шахрайське — та сама розмітка, з якою ми розбирали дошку ще в темі 08. Алгоритм її не бачив: він працював лише з ціною й роком. Подивімось, чи має знайдене розбиття хоч якийсь стосунок до неї. По дошці загалом шахрайських оголошень 12.6 % — 139 із 1 100.

сегментусьогочеснихшахрайськихчастка
Дешеві старі3552827320.6 %
Міцна середина264246186.8 %
Свіжі дорогі4814334810.0 %

Сигнал є — і він слабкий. У найдешевшому сегменті шахрайських утричі більше, ніж у «міцній середині». Але жоден із трьох кластерів не є «кластером шахраїв»: навіть у найгіршому з них чотири оголошення з пʼяти чесні.

Спокуса тут очевидна: оголосити перший сегмент детектором шахрайства. Порахуймо, що з цього вийде, тими самими метриками, що й у темі 05. Якщо вважати «дешеві старі» прогнозом «шахрайське»:

наш «детектор» precision 0.206 recall 0.525 F1 0.296 навмання, 355 рядків precision 0.126 recall 0.323 F1 0.182

Другий рядок — це орієнтир, без якого перший нічого не означає. Уяви, що ми не кластеризували нічого, а просто ткнули пальцем у 355 оголошень навмання — стільки ж, скільки в найдешевшому сегменті. Шахрайських серед них виявиться приблизно стільки ж, скільки й по всій дошці, тобто 12.6 %. Ось і вся точність випадкового тику.

Наш сегмент дає 20.6 %. Це справді краще за жеребкування, але не в рази: кластер знає щось про шахрайство, і знає мало. Практичний бік ще сумніший — «детектор» упіймав половину шахраїв, але з кожних пʼяти піднятих тривог чотири хибні. Модератор, якому дати такий список, чотири рази з пʼяти читатиме чесне оголошення.

Є ще один орієнтир, з яким ми зустрілись у темі 05: модель, яка каже «усі оголошення чесні». Вона не піднімає жодної тривоги, тож помиляється рідше за наш сегмент — 12.6 % помилок проти 32 % — і при цьому не знаходить нікого взагалі. Recall у неї нуль. Саме тому «частка правильних відповідей» тут ні про що не говорить, а precision і recall — говорять.

Є й одне число, яке підсумовує все відразу. Скоригований індекс Ренда (adjusted Rand index) міряє, наскільки два розбиття тих самих обʼєктів схожі: 1 — повний збіг, 0 — збіг рівно такий, який дало б випадкове перемішування. Між нашими кластерами й колонкою шахрайське він дорівнює 0.007.

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

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

Тому знайдені кластери завжди перевіряють двома питаннями. Перше: чи можу я описати кожну групу словами так, щоб людина з предметної області кивнула? «Дешеві старі телефони» — так. «Кластер номер два» — ні. Друге: чи стійкі вони? Прибери десять відсотків рядків навмання, перезапусти — і подивись, чи лишилось розбиття тим самим. Кластери, які розсипаються від такої перевірки, описують не дані, а конкретний запуск.

10 / ДаліЩо далі

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

Обидва його обмеження мають прямі відповіді, і саме з них починається наступна тема.

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

Далі в практиці. У practice.ipynb ми напишемо k-means з нуля десятком рядків і подивимось, як падає інерція; звіримо свої числа з KMeans зі scikit-learn; проженемо кілька випадкових стартів і побачимо розкид; побудуємо криву ліктя й силует для k від 2 до 10; порівняємо розбиття до й після масштабування; і наприкінці зіставимо кластери з колонкою шахрайське, якої алгоритм не бачив.

Далі в темі

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