Проєкт від початку до кінця

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

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

Задача одна на всю тему: детектор шахрайських оголошень на тій самій дошці про вживані телефони, що і в темі 08. 1 200 оголошень, вісім колонок, 16 % шахрайських. Ми пройдемо шлях від сирої таблиці до рішення, чи можна цю модель випускати до людей — з усіма числами й з усіма помилками, які на цьому шляху легко зробити.

Нового матеріалу тут немає. Кожен крок ти вже знаєш окремо: поділ даних, вибір метрики, крос-валідація, налаштування, вибір моделі, конвеєр, ознаки. Цінність цієї теми — у послідовності й у пастках між кроками. Тому далі буде багато посилань і мало переказу.

ПостановкаПостановка перед кодом

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

Чотири питання, на які треба відповісти до першого import.

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

Кому потрібен прогноз і що він із ним зробить. Модератор дошки. Він не читає всі оголошення підряд — він читає ті, які модель підняла нагору. Отже, прогноз має бути не «так/ні», а чергою, і в неї є пропускна здатність: скільки оголошень людина встигає перевірити за день.

Скільки коштує помилка кожного типу. Ось де ця задача перестає бути симетричною.

Ціна двох помилок

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

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

Яка з цього метрика. Точність (accuracy) тут не годиться взагалі: шахрайських оголошень 16 %, тож константа «всі чесні» дає 84 % і не знаходить нікого (тема 05). Нам потрібні дві величини одночасно — скільки шахраїв упіймали (recall) і яка частка тривог виявилась справжньою (precision). Щоб порівнювати кроки одним числом, беремо F1 — їхнє гармонійне середнє.

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

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

ПоділПоділ — перша дія

Друга дія проєкту — і теж без жодної моделі. Ще до того, як подивитись на розподіли, порахувати пропуски й побудувати хоч одну гістограму, ми відкладаємо 25 % рядків і більше їх не чіпаємо.

Чому саме тут, а не після розвідки? Бо розвідка змінює тебе. Ти побачив, що ціна має довгий хвіст — і вирішив узяти логарифм. Побачив чотири дивні рядки — і вирішив їх прибрати. Кожне таке рішення підігнане під ті дані, які ти бачив. Якщо серед них був і тест, то тест перестав бути незалежним ще до першого навчання (тема 03). Модель нічого не підглядала, зате підглянув ти — і результат той самий.

навч_X, тест_X, навч_y, тест_y = train_test_split( усі_ознаки, таргет, test_size=0.25, random_state=42, stratify=таргет)

stratify тут не прикраса. Шахрайських оголошень 195 із 1 200; без стратифікації їхня частка в тесті гуляє на кілька відсотків просто від жеребкування, і різниця між двома моделями потоне в цьому шумі. З нею частка однакова в обох частинах: 16.2 % і 16.3 %.

Дві речі можна зробити до поділу, бо вони не рахують із даних жодного числа: привести памʼять до одного запису (128 замість 128 ГБ) і прибрати повні дублікати рядків. Дублікати — саме до поділу: якщо той самий рядок потрапить і в навчальну, і в тестову частину, тест перевірятиме модель на тому, що вона вже бачила напамʼять. А от медіани, межі викидів і заповнення пропусків — тільки після (тема 09).

Саме тут таблиця й міняє розмір. У вигрузці з дошки 1 212 рядків; повних дублікатів серед них дванадцять, і після їх видалення лишається рівно 1 200. Це те число, з яким працює вся тема: 1 200 = 900 навчальних + 300 відкладених. Дванадцять рядків — дрібниця для розміру вибірки й не дрібниця для чесності заміру: кожен дубль, що розʼїхався по обидва боки поділу, підняв би тестове число задарма.

Правило переходу до кроку 3. Тестова частина лежить в окремій змінній, і далі в коді немає жодного рядка, який до неї звертається. Поки такий рядок є — розвідку не починають, бо будь-яке число, пораховане по всіх 1 200, уже забруднене.

Порядок дій і три місця, де ховається витік

Вісім кроків проєкту в порядку виконання. Тестова частина замкнена від кроку 2 до кроку 7.

Усі три витоки внизу непомітні в коді — і всі три завищують результат. Кожен крок підписаний тим значенням F1, яке він дав; сира таблиця має 1 212 рядків, після зняття дванадцяти повних дублікатів лишається 1 200. Тестова частина відходить убік на кроці 2 і повертається аж на кроці 7.

РозвідкаРозвідка: три відповіді

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

Слово «тільки» тут не обережність, а те саме правило, що й у темі 03 і темі 09, лише в найширшій формі. Витік — це будь-який шлях, яким знання про тестові рядки потрапляє в рішення. Медіана, порахована по всіх 1 200, — витік у коді. Гістограма, побудована по всіх 1 200 і побачена тобою, — витік у голові, і він не менш реальний, просто його не видно в git diff. Обидва завищують кінцеве число, і обидва лікуються однією звичкою: усе, що дивиться на дані, дивиться тільки на 900.

Перша: де пропуски й чи вони випадкові. Ціни немає у 72 рядках, стану — у 30. І пропуск у ціні аж ніяк не випадковий: серед рядків без ціни шахрайських 54.2 %, серед рядків із ціною — 12.9 %. Отже, ці рядки не викидають: відсутність ціни сама по собі є сигналом, і їй потрібен окремий прапорець (тема 09).

Друга: чи немає колонки, якої в момент прогнозу ще не існує. Це питання ставлять числом. Кореляція кожної колонки з таргетом:

ціна −0.054 вік_акаунта −0.099 рік +0.035 памʼять_гб +0.113 скарг +0.891

Колонка скарг має лякати, а не радувати. Скарги зʼявляються після публікації, коли шахрая вже викрили; у мить, коли модель має відповісти, там нуль у всіх. Це витік, і коштує він дорого: модель зі скарг дає F1 0.974 на крос-валідації і нуль у бою. Колонку викидаємо назавжди — і з навчальної частини, і з тестової.

Третя: що з викидами. Найдорожче оголошення в навчальній частині — 95 000 грн. Це не помилка даних у чистому вигляді: чотири рядки — колекційні Gamma X 2017 року, а ще два — одруки із зайвим нулем. Ми їх поки не чіпаємо й побачимо у розділі 7, у що це вилилось.

ВідлікБазова лінія

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

accuracy = 0.838    F1 = 0.000

Дві цифри в одному рядку — і вони описують ту саму модель. Вона не помиляється у 84 % випадків і не знаходить жодного шахрая. Ось чому accuracy тут не метрика, а декорація: щоб отримати 84 %, не треба нічого вміти.

Тепер уяви звіт «наша модель має точність 94 %». Без другої половини — «а базова лінія дає 84 %» — перша не читається. Правильна форма звіту завжди подвійна (тема 29).

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

Правило переходу до кроку 5. Два числа базової лінії записані у звіт (0.838 і 0.000), і будь-яке наступне число з цієї миті наводиться в парі з ними. Одинарне число зі звіту викидаємо — воно нічого не означає.

Перша модельПерша чесна модель

Не найкраща — перша. Логістична регресія (тема 14) на вихідних стовпцях, усередині конвеєра, з пʼятиразовою крос-валідацією.

Конвеєр (Pipeline) тут не для краси. Усередині нього закриваються пропуски, масштабуються числа й кодуються категорії — і все це рахується заново на кожному фолді крос-валідації, окремо для навчальної частини фолда. Якщо винести підготовку назовні, медіана для заповнення пропусків буде порахована по всіх 900 рядках, зокрема й по тих, на яких модель зараз перевіряють. Число підросте, а причини цього в коді буде не видно (тема 09).

F1 = 0.013    базова лінія: 0.000

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

А ми знаємо, чого саме немає. «Ціна 1 310 грн» не означає нічого, поки не сказано, скільки коштує такий самий телефон (тема 10). Будуємо цю ознаку — медіанну ціну всередині групи «модель + рік», а далі модуль логарифма відношення:

відхилення = |ln(ціна ÷ типова ціна)|

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

ІтераціїІтерації, зокрема невдалі

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

Шлях проєкту з числами

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

F10.000
зміна F1—
precision0.000
recall0.000
Кроки 0-4 — середнє по пʼяти фолдах крос-валідації на 900 навчальних оголошеннях. Крок 5 — єдиний замір на 300 відкладених. Пунктир на висоті 0.844 — найкраще, що обіцяла крос-валідація.

Розберемо, що сталось на кожному кроці.

Крок 2, ознака: 0.013 → 0.835. Один стовпчик, зроблений із двох чисел, які вже були в таблиці. Жодних нових даних, жодної складнішої моделі. Це найбільший приріст усього проєкту, і так буває майже завжди.

Крок 3, інша модель: 0.835 → 0.804. Хід був очевидний: випадковий ліс бачить нелінійності й взаємодії, працює зі значеннями за замовчуванням, не боїться масштабу. Мав виграти — і програв. Причина видима, коли її вже знаєш: розділювальна межа тут майже пряма («відхилення більше за поріг — шахрай»), а ламана межа з дерев таку пряму лише наслідує, щоразу трохи промахуючись.

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

Крок 4, налаштування: 0.835 → 0.844. Шість поєднань C і class_weight перебором (тема 20). Приріст є — і порівняй його з попереднім: ознака дала 0.835 − 0.013 = 0.822, налаштування дало 0.844 − 0.835 = 0.009. Це у 91 раз менше при тому, що на перебір пішло більше машинного часу, ніж на ознаку. Пропорція нормальна, і вона підказує, куди вкладати наступну годину: у дані, а не в ручки.

Зверни увагу на ще одну деталь кроку 4: налаштовували ми логістичну, а не ліс. Невдалий крок 3 із гілки випав — його не «покращують», а закривають. Тому й приріст 0.009 рахується від 0.835, а не від 0.804: остання прийнята точка гілки — це та, з якої проєкт рушив далі, а не та, яку зробили останньою за часом.

ПомилкиПомилки очима

Метрика каже, скільки помилок. Вона ніколи не каже, які. Тому після кожного серйозного кроку варто відкрити самі рядки, на яких модель помилилась.

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

  1. Візьми прогнози, яких модель не підглядала. cross_val_predict віддає для кожного з 900 оголошень прогноз тієї моделі, у навчанні якої це оголошення не брало участі. Не прогноз навченої моделі на її ж даних — на них помилок майже немає, і дивитись нема на що. І не тест: він закритий.
  2. Розклади рядки на чотири купи — спіймані шахраї, пропущені шахраї, хибні тривоги, чесні названі чесними — і запиши розмір кожної. У нас: 122, 24, 21 і 733. Дві середні купи — це і є всі 45 помилок проєкту.
  3. Порахуй у кожній купі те саме, що рахував по всій вибірці: медіану головної ознаки, частку пропусків, медіанний вік акаунта. Стовпчик, у якому число різко вибивається, і є підказкою. Саме так знайшлась перша знахідка: пропусків ціни в помилках 62 %, а в усій вибірці 8 %.
  4. Відкрий руками десяток окремих рядків із найбільшою впевненістю моделі — тих, де вона помилилась голосно. Числа показують, де проблема; сирі рядки показують, яка вона.
  5. Назви причину і поклади її в один із трьох кошиків: це дефект даних (лікується на вході, до моделі), брак ознаки (лікується наступною ітерацією) або межа задачі (лікується рішенням про продукт, а не кодом). Кошик визначає, хто це робить і скільки це коштує.

Далі — дві знахідки, які ця процедура дала на нашій дошці, по одній із двох різних кошиків.

Що спільного в помилок

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

група
оголошень24
без ціни12
мед. відхилення0.62
мед. вік акаунта143
Вертикальна вісь — вік акаунта в днях, шкала логарифмічна, бо вік змінюється від 5 днів до майже десяти років. Горизонтальна — відхилення ціни від типової; нуль означає «ціна рівно типова». Оголошення без ціни винесені в окрему смугу ліворуч, бо для них ця величина не існує.

Обидві групи помилок помітно зміщені в смугу ліворуч від риски. Порахуємо це прямо: помилок усього 45, з них 28 (62 %) — на оголошеннях без ціни. А самих таких оголошень 72 з 900, тобто 8 %. Вісім відсотків даних дають шістдесят два відсотки помилок.

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

Друга знахідка — у хибних тривогах, де ціна таки є. Їх пʼять, і три ми вже бачили: два Gamma X 2017 року за 82 і 88 тисяч (ті самі колекційні з теми 08) і Gamma X Ultra за 76 000 грн — одрук із зайвим нулем, справжня ціна 7 600. Модель робить рівно те, чого ми її навчили: бачить ціну в 12-17 разів вищу за типову й кричить «шахрай».

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

Коли цикл зупиняють

Ітерації не закінчуються самі. Питання «а може, ще одна ідея?» має відповідь «так» завжди, тому момент зупинки треба призначити правилом, а не настроєм. Робочих сигналів три, і достатньо будь-якого.

У нашому проєкті спрацювали перші два одночасно. Тому цикл закривається, і відкривається сейф.

Чого в цій лекції немає — і в тебе має бути. Жодне число проєкту вище не наведене з розкидом: скрізь стоїть лише середнє по пʼяти фолдах. Для 0.013 проти 0.835 це не має значення — різниця величезна. Для 0.835 проти 0.844 має, і чесна форма запису тут — cross_val_score(...).mean() разом зі .std(). Одне число без розкиду вирішує суперечку між двома близькими моделями підкиданням монети.

ФіналФінальний замір

Ознаки обрано, модель обрано, гіперпараметри підібрано, поріг визначено — усе це на крос-валідації, і поріг теж: як саме його обирали, розберемо в розділі 9, але обрано його до цієї миті. Тепер навчаємо на всіх 900 рядках і міряємо на 300 відкладених. Один раз.

крос-валідація F1 = 0.844 тест F1 = 0.796 precision 0.841 recall 0.755

Тест нижчий на 0.048, і це не збіг і не невдача. Ми обирали ознаку, модель, гіперпараметри й поріг за числом крос-валідації — а те, що обирали максимізуванням, завжди виходить трохи завищеним (тема 20). Шість поєднань у сітці — шість спроб, і найкраще з шести чисел уже містить дрібку везіння. Тест цього відбору не бачив, тому й показує менше.

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

«А якщо тільки подивитись, нічого не змінюючи?» Не буває. Ти подивився й побачив, що модель провалюється на дорогих телефонах. Далі ти або зміниш щось (і тест зіпсовано), або не зміниш — і тоді навіщо дивився. Єдиний спосіб мати незалежний тест — тримати його закритим до самого кінця, а для експериментів мати крос-валідацію.

ЗапускЧи можна це запускати

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

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

Поріг рішення в наслідках, а не в метриках

Дві криві: скільки шахраїв проходить повз і скільки чесних продавців даремно потурбовано. Проведи повзунок від краю до краю.

пропущено шахраїв24
хибних тривог21
precision0.853
recall0.836
900 навчальних оголошень, 146 шахрайських. Числа пораховані на прогнозах крос-валідації, а не на тесті — поріг теж є рішенням, і обирати його на тесті означає підглянути. У проєкті ми лишили 0.5: він дає найбільший F1 (0.844), а формулювати ціну помилки в гривнях у нас поки нема на чому.

Тепер повернімось до знахідки з розділу 7. Гіпотезу «якість тримається на оголошеннях із ціною» ми сформулювали на навчальній частині, до того, як відкрили сейф. Тому розкласти той самий єдиний замір на дві підгрупи — не другий погляд на тест, а докладніший запис першого: рядки ті самі 300, прогнози ті самі, модель після цього не змінюється. Видно:

оголошення з ціною 272 шт. F1 = 0.900 precision 0.964 оголошення без ціни 28 шт. F1 = 0.606
Де тут проходить межа. Розкласти фінальний замір на підгрупи, названі до його відкриття, — законно: це форма звіту, а не новий експеримент. Незаконно — перебирати підгрупи після й доповідати ту, де вийшло красивіше («на телефонах дорожче за 20 000 наш F1 — 0.93!»), або міняти модель за побаченим. Різниця не в коді, а в тому, що записано раніше: перелік підгруп має існувати до відкриття сейфа. У нас він складався з однієї — «є ціна / немає ціни», — і записали ми її в розділі 7, на навчальній частині, задовго до фінального заміру.

Отже рішення про запуск не одне, а два. Оголошення з ціною — 91 % потоку — модель вирішує сама: з 28 піднятих тривог 27 виявились справжніми. Оголошення без ціни йдуть у чергу до модератора без моделі; не тому, що модель погана, а тому, що в цих рядках немає з чого робити висновок. Розділити задачу — теж інженерне рішення, і часто краще за спроби витиснути ще 0.01 з метрики.

Далі — чотири питання, які вирішує не той, хто пише код.

Рішення про запуск і на що воно впливає

Жодне з цих рішень не міняє F1. Кожне міняє те, чим модель обернеться для людей.

рішенняваріантина що впливає
Що система робить із тривогоюблокувати · показати попередження · підняти в черзі модератораціну хибної тривоги — від «нічого» до «чесний продавець пішов на іншу дошку»
Хто перевіряє чергу і скільки встигаєодин модератор · команда · автоматично понад порогом 0.95поріг: пропускна здатність людей задає, скільки тривог має сенс піднімати
Як оскаржити рішеннякнопка «це помилка» · лист у підтримку · ніякі довіру, і дані: скарги на хибні тривоги — це нова розмітка
Як міряємо якість після запускущотижневий замір на свіжій розмітці · дивимось на скарги · ніякчи помітимо взагалі, що модель зіпсувалась
Останній рядок найважливіший і найчастіше порожній. Без заміру після запуску модель мовчки псується, і перший, хто про це дізнається, — користувач.

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

ЧеклістЧекліст проєкту

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

Чекліст наскрізного проєкту

Шість груп у порядку виконання: зліва направо, згори вниз. Пропущений пункт із верхніх груп коштує дорожче за будь-який із нижніх.

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

ДаліЩо далі

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

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

Чого цей проєкт не покриває

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

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