Три конверти

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

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

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

МотиваціяНавчальна помилка завжди бреше

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

Параметр k керує гнучкістю. При k = 1 модель відповідає за єдиним найближчим сусідом — і на навчальних даних це означає, що вона просто знаходить сама себе. Точність на навчальній вибірці буде рівно 100%, завжди, на будь-яких даних, навіть на чистому шумі. Це не досягнення, це визначення.

Чому не можна вірити точності на навчальних даних

Ліворуч — межа рішень методу k сусідів. Праворуч — дві криві точності залежно від k.

точність train—
точність test—
Що читати: при k = 1 навчальна точність рівно 100% — модель знаходить кожну точку саму в собі. Тестова при цьому найгірша: межа рішень порізана на клапті, які повторюють шум. Зі зростанням k межа згладжується, навчальна точність падає, а тестова спершу росте.

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

РозбиттяТри конверти, три ролі

Стандартна практика — розділити наявні дані на три незалежні частини. Слово «незалежні» тут ключове: жоден обʼєкт не має потрапити у дві частини одночасно.

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

Гіперпараметр — налаштування, яке ти задаєш перед навчанням і яке модель сама підібрати не може. Кількість сусідів k з попереднього розділу — саме такий. Звичайні параметри (ваги, пороги) модель добирає сама під час навчання; гіперпараметри добираєш ти, ззовні, перезапускаючи навчання.

Перенавчання (overfitting) — коли модель підлаштувалась під випадкові особливості саме тих даних, які бачила, замість того щоб вивчити загальне правило. Ліва картинка в інтерактиві вище при k = 1 — це воно й є: межа порізана на клапті навколо окремих точок. Тема має власний розділ курсу — 17. Перенавчання, недонавчання і розклад помилки, — але сама ідея потрібна вже тут.

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

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

Термінологія плутана. У частині літератури (і в бібліотеці scikit-learn) «validation» і «test» називають навпаки або зливають в одне. Не сперечайся про слова — важлива лише роль: одна відкладена вибірка потрібна для вибору, друга для звіту. І це мають бути різні вибірки.

Прокляття переможцяЧому двох вибірок замало

Найпоширеніше заперечення звучить так: «навіщо три? Навчив на train, поміряв на test, обрав найкращу модель — хіба цього мало?» Мало. І щоб зрозуміти чому, треба побачити ефект, який в економіці називають прокляттям переможця (winner's curse).

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

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

Два позначення, які знадобляться просто зараз.

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

E[…] — математичне сподівання, тобто «середнє значення, якби дослід повторили нескінченно багато разів». Приклад на пальцях: E[кількість очок на кубику] = 3.5. Жодного разу ти не викинеш 3.5 — але якщо кидати довго й усереднювати, число приходить саме туди. Так само E[точність̂] — це те, куди прийшла б виміряна точність, якби ти міряв її на нескінченній кількості різних тестових вибірок.
E[ maxm точність̂m ]  >  maxm E[ точність̂m ]

Читається так: у середньому найбільше з кількох вимірювань більше, ніж найкраща зі справжніх якостей. Розбір по знаках: m — номер моделі (від першої до двадцятої), maxm — «візьми найбільше серед усіх моделей», точність̂m — виміряна на тесті точність моделі номер m, E[…] — усереднення по всіх можливих тестових вибірках.

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

Що станеться, якщо обирати модель по тесту

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

вибір по тесту—
насправді—
вибір по валід.—
насправді—
Що видно: рожева точка — переможець за тестовою оцінкою. Вона майже завжди лежить вище лінії «оцінка = правда»: її обрали саме за те, що вимірювання їй підіграло. Бірюзова точка — модель, обрана по валідації; її оцінка на тесті чесна, бо тест не брав участі у виборі.

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

ДисциплінаТесту торкаємось рівно один раз

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

На практиці це дає таку послідовність:

  1. Розділив дані на три частини до того, як почав щось робити.
  2. Тестову частину поклав окремо і не відкривав.
  3. Навчав десятки моделей на train, порівнював їх на validation.
  4. Обрав переможця, зафіксував усі гіперпараметри, більше нічого не змінюєш.
  5. Тепер, і тільки тепер, порахував метрику на test. Це число — у звіт.

Схема · Ті самі пʼять кроків, але в часі

Три доріжки — три вибірки. Кожна риска на доріжці — один дотик до цих даних.

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

ВитікЩо таке витік даних

Витік даних (data leakage) — це ситуація, коли інформація з тестової вибірки якимось шляхом дісталася до моделі під час навчання. Оцінка після цього стає завищеною, іноді до абсурду: 99 % на тесті і повний провал у продакшені — тобто вже в реальній роботі, коли модель обслуговує справжніх користувачів на справжніх даних.

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

Механізм: як саме тестові дані просочуються в навчання

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

18 · 42 · 55 · 61 · 74 · 88 · 96 · 120 · 140 · 205

Перед навчанням ознаки зазвичай нормалізують. Найпростіша нормалізація (її звуть min-max) стискає всі значення в проміжок від 0 до 1 за правилом «відніми мінімум і поділи на розмах»:

x′ = (x − мін) / (макс − мін)

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

Ключове тут — те, що мін і макс треба звідкись узяти. Це не константи з підручника, це числа, вирахувані з наявних даних. І от у цій точці рішення й ховається витік. Нехай тестовими стануть три обʼєкти — 18, 96 і 205, а решта сім підуть у train. Тоді:

Порахуймо руками, що станеться з тестовими обʼєктами в кожному з двох порядків. За порядком «нормалізували все, потім розділили»: 18 перетворюється на (18 − 18) / 187 = 0.000; 96 — на (96 − 18) / 187 = 78 / 187 = 0.417; 205 — на (205 − 18) / 187 = 1.000. Усі три слухняно вклались у проміжок від 0 до 1.

За чесним порядком «розділили, потім нормалізували по train»: 18 перетворюється на (18 − 42) / 98 = −0.245; 96 — на (96 − 42) / 98 = 54 / 98 = 0.551; 205 — на (205 − 42) / 98 = 1.663. Двоє з трьох вийшли за межі проміжку.

Схема · Один рядок коду, поставлений на два рядки вище

Ті самі десять обʼєктів. Уся різниця — звідки взято мінімум і максимум для нормалізації.

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

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

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

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

Практичне правило одним рядком. Перетворення має два різні кроки: навчитись на даних (запамʼятати мін, макс, середнє, список ознак, словник) і застосуватись до даних. Навчатись воно має тільки на train, а застосовуватись — до всіх трьох вибірок. У scikit-learn це буквально два різні виклики: fit_transform на навчальній частині і transform на решті. Клас Pipeline існує саме для того, щоб цей порядок не можна було переплутати руками.

СценаріїЧотири способи отруїти собі оцінку

Сценарій 1 · Препроцесинг до розбиття

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

Список підозрюваних, тобто перетворень із параметрами, які треба навчати лише на train: середнє й стандартне відхилення (стандартизація), мінімум і максимум (нормалізація), значення для заповнення пропусків, список обраних ознак, набір категорій для кодування, словник слів у тексті, а також будь-яке зменшення розмірності на кшталт PCA. Якщо ти не певен, чи має перетворення параметри, спитай себе: чи змінився б його результат, якби до даних додали ще один рядок? Якщо так — параметри є, і навчати їх можна лише на train.

Сценарій 2 · Дублікати й групи

Один пацієнт зробив три знімки. Один користувач залишив пʼятдесят відгуків. Один товар зʼявляється в каталозі під двома артикулами. Якщо розбивати випадково по рядках, копії того самого обʼєкта опиняться і в train, і в test — і модель просто впізнає їх, а не узагальнює.

Лікується груповим розбиттям: спочатку ділиш групи (пацієнтів, користувачів, товари), потім усі рядки групи їдуть в одну вибірку цілком.

Сценарій 3 · Витік із майбутнього

Якщо дані мають час, випадкове розбиття вбиває задачу. Модель, навчена на подіях за весь рік, передбачає події березня, «знаючи» вересень. У житті такої розкоші не буде: завтрашній день прогнозують, маючи лише вчорашній. Розбиття для часових рядів завжди хронологічне: минуле у train, майбутнє у test.

Сценарій 4 · Ознака, що містить відповідь

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

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

Скільки коштує витік: замір

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

замір 1 · відбір ознак до розбиття

Беремо 200 обʼєктів і 300 ознак чистого шуму — випадкові числа, жодного звʼязку з міткою. Мітку теж кидаємо монеткою. Правильної відповіді тут не існує в принципі: будь-яка чесна модель приречена на 50 %, як вгадування.

Далі два порядки дій. Нечесний: відбираємо 10 ознак, найсильніше повʼязаних із міткою, по всіх 200 обʼєктах, і аж потім ділимо на train і test. Чесний: спершу ділимо, потім відбираємо ті самі 10 ознак, дивлячись лише на навчальну частину. В обох випадках учимо ту саму модель і міряємо точність на тих самих тестових обʼєктах. Повторюємо 200 разів і усереднюємо.

нечесний порядок: 0.68  ·  чесний порядок: 0.50

Чесний порядок дає рівно те, що й мусить: 0.50, тобто нуль знання. Нечесний — 0.68, завищення на 18 відсоткових пунктів на даних, де немає жодної закономірності. Скорочення «пп» тут і далі означає різницю між двома відсотками — так її записують, щоб не плутати з відсотком від відсотка. Модель нічого не вивчила; вона підглянула, які саме випадкові ознаки вдало збіглися з мітками саме цих тестових обʼєктів.

замір 2 · нормалізація до розбиття

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

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

що з цього випливає

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

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

Інтерактив нижче міряє реальний масштаб трьох із цих сценаріїв. Порівняй, наскільки різні за силою витоки бувають:

Скільки коштує кожен вид витоку

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

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

БалансСтратифікація

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

Порахуємо. Тестова вибірка на 100 обʼєктів, мінорний клас 2 %. Очікувано в ній буде 2 позитивні приклади. Але «очікувано» не означає «завжди»: скільки саме їх туди попаде — це, по суті, сто кидків монетки, яка випадає «позитив» з імовірністю 0.02. Наскільки сильно результат гуляє навколо двійки, каже стандартне відхилення — міра типового розміру відхилення від середнього:

√( n · p · (1 − p) ) = √( 100 · 0.02 · 0.98 ) = √1.96 ≈ 1.4

Символи: n — скільки обʼєктів у тестовій вибірці (тут 100), p — частка мінорного класу (тут 0.02), знак √ — квадратний корінь. Звідки береться сама формула, розберемо трохи далі, у розділі про похибку; поки що важливий висновок. Типове відхилення від середнього — приблизно 1.4 обʼєкта, а середнє всього 2. Тобто «нуль позитивних прикладів у тесті» — це не екзотика, а буденний результат: він трапляється приблизно в кожному сьомому розбитті (докладніше — нижче, у формулі 0.98¹⁰⁰). А якщо позитивних прикладів нуль, ламаються цілі метрики: скажімо, recall — це частка знайдених позитивних прикладів серед усіх позитивних, і коли позитивних нуль, у знаменнику стоїть нуль, тобто величини просто не існує (докладно — у темі 05. Precision і Recall). Уся оцінка перетворюється на лотерею.

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

Чому «приблизно кожне сьоме». Щоб у тесті не було жодного позитивного прикладу, кожен зі ста відібраних обʼєктів має виявитись негативним. Імовірність цього для одного обʼєкта — 0.98. Для ста незалежних — 0.98, помножена сама на себе сто разів: 0.98¹⁰⁰ ≈ 0.133, тобто 13 %. Один із семи-восьми випадків. Мала ймовірність для одного досліду, помножена сто разів, дає зовсім не малу ймовірність — і це рівно та арифметика, через яку рідкісні класи вимагають окремої уваги.

Стратифікація при дисбалансі класів

600 випадкових розбиттів і 600 стратифікованих. По горизонталі — яка частка мінорного класу опинилась у тесті.

розкид випадк.—
розкид страт.—
розбиттів без жодного мінорного—
У коді: у scikit-learn це один аргумент — train_test_split(..., stratify=y). Коштує нічого, а прибирає цілий клас проблем. Для регресії, де класів немає, цільову величину спершу ріжуть на кілька смуг за значенням (наприклад, чотири смуги, у кожній чверть обʼєктів) і балансують уже ці смуги.

ПропорціїЯк обирати розміри вибірок

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

обсяг данихтипове розбиттячому саме так
< 1 000крос-валідаціяокрема валідаційна вибірка вийде надто малою, щоб щось міряти
1 000 — 100 00060 / 20 / 20класика: і вчитись є на чому, і міряти є на чому
> 1 000 00098 / 1 / 11% від мільйона — це 10 000 обʼєктів, а такої вибірки для оцінки вже вистачає

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

Розбиття та розкид оцінки

Смуга зверху — пропорції. Гістограма знизу — точність на тесті по 300 різних випадкових розбиттях тих самих даних.

середня точність—
розкид (σ)—
обʼєктів у test—
розмах 5–95%—
Спробуй крайні значення: постав train на 85% і validation на 5% — на тест лишиться 20 обʼєктів, і гістограма розповзеться на десятки відсоткових пунктів. Потім постав train на 10%: тепер тесту вдосталь і оцінка стабільна, зате моделі немає на чому вчитись — уся гістограма зсувається вліво. Обидві крайності однаково марні, просто з різних причин.

ПохибкаСкільки коштує мала тестова вибірка

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

Три слова, без яких далі не піти.

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

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

Стандартна похибка (standard error, SE) — те саме стандартне відхилення, але не для однієї величини, а для результату вимірювання: наскільки гуляло б виміряне число, якби ти повторив вимірювання на іншій тестовій вибірці того самого розміру.

Тепер формула. Стандартна похибка виміряної точності дорівнює:

SE = √( p(1 − p) / n )

Словами: чим ближча точність до 0 або до 1 і чим більша вибірка, тим надійніше виміряне число. Символи: p — справжня точність моделі (частка правильних відповідей, число від 0 до 1), n — розмір тестової вибірки, √ — квадратний корінь. Виведення — три кроки, кожен на один рядок.

крок 1 · одна спроба

Розгляньмо один тестовий обʼєкт. Величина «модель вгадала» приймає лише два значення: 1 з імовірністю p і 0 з імовірністю 1−p. Її середнє дорівнює p, а дисперсія такої величини (це стандартний результат, який легко перевірити підстановкою):

Var = p(1 − p)

Перевіримо на числах: при p = 0.5 дисперсія 0.25 — максимум, бо саме тут невизначеність найбільша. При p = 0.95 дисперсія 0.0475 — модель майже завжди вгадує, і гуляти нема чому.

крок 2 · середнє з n спроб

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

Var(точність̂) = p(1 − p) / n

Корінь із цього і є SE. Порахуймо для p = 0.85 і n = 100: 0.85 · 0.15 = 0.1275; поділити на 100 — 0.001275; корінь — 0.0357, тобто приблизно 3.6 відсоткових пункти, або 3.6 пп.

крок 3 · довірчий інтервал

Одне SE — це «типове» відхилення, але хочеться межі, у які результат потрапляє майже завжди. При достатньому n виміряна точність розподілена приблизно нормально («дзвоном»), а для дзвону відомо: у проміжок «середнє ± 1.96 стандартного відхилення» потрапляє 95 % усіх випадків. Звідси й береться множник:

точність̂ ± 1.96 · SE

Для нашого прикладу: 0.0357 · 1.96 ≈ 0.070. Отже виміряні 85 % на ста обʼєктах — це насправді «десь від 78 до 92 %». Число 1.96 не має жодного глибокого сенсу: це просто ширина дзвону, у яку вкладаються 95 % випадків. Хочеш 99 % — множник стає 2.58.

Ключовий наслідок — корінь у знаменнику. Щоб зменшити похибку вдвічі, вибірку треба збільшити вчетверо: корінь із чотирьох дорівнює двом. Тому інтуїція «додам ще трохи даних у тест» працює погано: від 100 до 200 обʼєктів похибка падає лише приблизно на 30 % (бо √2 ≈ 1.41, а 1 / 1.41 ≈ 0.71).

Стандартна похибка й довірчий інтервал

Крива SE(n) у логарифмічному масштабі. Праворуч — як виглядає 95% інтервал навколо виміряної точності.

SE—
95% ДІ ±—
n для інтервалу ±1 пп—
Практичний висновок: перш ніж радіти, що модель A дала 87%, а модель B 86%, порахуй SE. Якщо тестова вибірка на 200 обʼєктів, похибка близько 2.4 пп — різниця в один пункт просто не існує. Повзунок розміру тут навмисне логарифмічний: подивись, як швидко крива стає майже пласкою.

АльтернативаКоли даних мало: крос-валідація

На маленькому датасеті одна валідаційна вибірка нічого не варта: 15% від 400 обʼєктів — це 60 обʼєктів, і за формулою вище похибка оцінки складе близько 5 пп. Порівнювати на цьому моделі безглуздо.

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

Порахуємо, що це дає. Тих самих 400 обʼєктів, k = 5. Кожен фолд — 80 обʼєктів, і кожне окреме вимірювання все ще хитке. Але вимірювань тепер пʼять, і кожен із 400 обʼєктів устиг побути перевірочним рівно один раз, тож усереднена оцінка спирається на всі 400, а не на 60. Ціна теж очевидна: навчань стало пʼять замість одного, тобто робота подорожчала впʼятеро. Саме тому крос-валідацію беруть тоді, коли даних мало, а не завжди — на великому датасеті одна валідаційна вибірка і так достатньо точна, а пʼятикратна вартість навчання нікуди не зникає. Докладний розбір — у темі 18. Крос-валідація.

Важливо. Крос-валідація замінює валідаційну вибірку, а не тестову. Правильна схема: спочатку відкладаємо test, потім робимо крос-валідацію на решті, обираємо модель, навчаємо її на всіх нетестових даних і один раз міряємо на test. І ще одне: всередині крос-валідації нормалізатор та інші перетворення мусять налаштовуватись заново на кожному фолді, лише по тих k − 1 частинах, на яких цього разу вчаться. Якщо налаштувати їх один раз на всіх даних — повертається рівно той витік, який ми щойно розібрали по числах, тільки заховати його стало легше.

ПідсумокЧекліст перед тим, як довіритись числу

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