складність 1/5 Безкоштовно
Train-test split
Відкладіть частину рядків від навчання, щоб звітувана оцінка була виміряна на даних, яких модель не бачила. Поділ має йти першим, бути достатньо великим і зважати на те, як надходять рядки.
Інтуїція
Похибка моделі на даних, на яких її підганяли, — не доказ. Її можна звести до нуля запам’ятовуванням, а запам’ятовування — саме те, що ви намагаєтеся виявити [1, §3.6.1.1].
Тож частину рядків відкладають. Модель ніколи їх не бачить, і її похибка на них заступає похибку на даних, яких ще не існує [1, §3.6.1]. Усе складне в поділі випливає з буквального прочитання цього речення: ніколи їх не бачить — сильніша вимога, ніж здається [1, §3.6.3], а число, яке повертається, шумніше, ніж здається.
Формальне визначення
Величину, що нас цікавить, обчислити неможливо. На практиці «ми мусимо оцінювати похибку узагальнення, застосовуючи модель до незалежного тестового набору, що складається з випадково відібраних прикладів… відкладених від нашого навчального набору» [1, §3.6.1].
Ця оцінка спирається на припущення, яке варто проговорити вголос: «ми припускаємо, що навчальні й тестові дані взято незалежно з однакових розподілів… це зазвичай називають припущенням IID» [1, §3.6.1]. Четверта частина розв’язаного прикладу — про те, що буває, коли воно тихо не справджується.
Третій поділ з’являється, щойно ви порівнюєте моделі. «Похибку на відкладених даних, тобто на валідаційній вибірці, називають валідаційною похибкою» [1, §3.6.1], і розподіл праці такий: валідаційна вибірка обирає, а тестовий набір звітує.
Як це працює
Правило просте й постійно порушуване: «У принципі, нам не слід торкатися тестового набору, доки ми не обрали всі гіперпараметри» [1, §3.6.3]. Причина в тому, що до тестового набору можна перенавчитися, як і до будь-чого іншого, а збій буде тихим: «Якщо ми перенавчимося на навчальних даних, завжди є оцінка на тестових даних, яка тримає нас чесними. Але якщо ми перенавчимося на тестових даних, як ми взагалі про це дізнаємося?» [1, §3.6.3].
Звідси три частини: «Звичайна практика розв’язання проблеми навчання на тестовому наборі — ділити дані на три частини, додаючи до навчального й тестового наборів ще й валідаційну вибірку» [1, §3.6.3].
Де застосовується
Перш за все інше, і один раз на проєкт. Кожна оцінка на цьому сайті, описана як відкладена, походить із такого поділу, а крос-валідація — та сама ідея, застосована k разів, щоб кожен рядок побував по той бік.
У коді це один виклик — train_test_split або аргумент cv, що ділить за вас
[2, §3.1]. Механіка ніколи не є проблемою. Проблема — у
чотирьох вимірюваннях нижче.
Чому і коли
Завжди, і з розміром, обраним свідомо, а не за звичкою. 80/20 з кожного туторіалу — це компроміс: більший тестовий набір робить звітуване число стабільнішим, а менший робить трохи кращою модель, для якої його звітують. Перша частина визначає ціну цього компромісу.
Діліть за групами щоразу, коли рядки не незалежні, і за часом щоразу, коли модель застосовуватимуть до майбутнього. В обох випадках порушується припущення IID [1, §3.6.1], і випадковий поділ цього не бачить.
Практичний приклад
Усе — у scripts/datasplit.py.
Один поділ — це одна вибірка
the same model and the same data, split 400 different ways
test rows mean accuracy std dev worst best spread
120 0.831 0.032 0.750 0.917 0.167
240 0.832 0.021 0.767 0.887 0.121
420 0.832 0.016 0.788 0.871 0.083
600 0.833 0.012 0.800 0.873 0.073
Nothing changed between those 400 runs except which rows landed on
which side. A single number from a single split is a draw from that
column, and the smaller the test set the wider the draw.За ці 400 прогонів у моделі не змінилося нічого. На 120 тестових рядках та сама модель отримує 0.750 або 0.917 залежно від перемішування, і цей розкид ширший за більшість звітованих покращень.
Вибір на тестовому наборі витрачає його
Відмінність між валідацією й тестом звучить як бухгалтерія. Ось скільки вона важить:
Python 7 рядків Показати код Сховати код
best, best_s = None, -1.0
for _ in range(k):
cols = g.choice(x.shape[1], size=6, replace=False)
wb = fit_logistic(x[tr][:, cols], y[tr])
s = accuracy(x[te][:, cols], y[te], wb)
if s > best_s:
best_s, best = s, (cols, wb)Вивід
pick the best of k independent models on one test set, then re-measure
models compared chosen score on fresh data optimism
1 0.576 0.572 +0.004
3 0.622 0.607 +0.015
10 0.647 0.623 +0.025
30 0.663 0.629 +0.034
100 0.672 0.633 +0.039
The chosen model's score on the set that chose it is not an estimate
of anything. It is the maximum of k noisy numbers, and the maximum of
k draws rises with k whether or not any model is better. The last row
is a model that looks 3.9 points better than it is.Максимум із k шумних чисел зростає з k незалежно від того, чи є якась модель кращою. Це той самий ефект, що й множинні порівняння, який заходить у двері, за якими ніхто не стежить.
Усе, що підігнали до поділу, бачило все
a target that is pure coin-flip noise, 600 rows, 4,000 features
feature selection done test accuracy
before the split (all rows) 0.701
inside the split (train rows only) 0.501
the truth 0.500
There is no signal in this data: y is a coin flip independent of every
one of the 4,000 columns. Selecting features while the test rows were
visible manufactures +0.201 of accuracy out of nothing. Doing the
identical selection on the training rows alone reports chance, which
is the correct answer. The split has to come first.Рядки, що надходять групами
60 subjects, 20 rows each: the same rows split two ways
split test accuracy what it measures
random rows 0.820 subjects it has seen
whole subjects 0.761 subjects it has not
+0.059 of the random split's accuracy is recognising subjects it
already trained on. If rows arrive in groups -- patients, users,
sessions, documents -- the split has to be over groups, or the score
answers a question nobody asked.Типові помилки
Звітувати один поділ так, ніби він і є відповіддю. Це вибірка з розподілу, ширину якого можна виміряти, і на малих тестових наборах ця ширина більша за заявлений ефект. Звітуйте розкид або використовуйте крос-валідацію.
Дозволяти тестовому набору обирати будь-що. Модель, ознаки, поріг, епоху зупинки чи просто «про який прогін написати» — кожен вибір витрачає його, і отримане число оптимістичне на величину, що зростає з кількістю порівняних варіантів.
Попередня обробка до поділу. Масштабування, імпутація, відбір ознак, пересемплування, цільове кодування: підганяйте лише на навчальних рядках. Вище відбір ознак, зроблений на мить зарано, виготовив 0.201 точності з цільової змінної, яка була підкиданням монети.
Ділити рядки, коли дані надходять групами. Пацієнти, користувачі, сесії, речення з одного документа. Випадковий поділ кладе ту саму групу по обидва боки, і модель оцінює себе на суб’єктах, яких уже зустрічала.
Ділити часові ряди випадково. Той самий збій, лише з годинником: моделі дають навчатися на майбутньому, а потім просять прогнозувати минуле. Діліть за датою.
Сприймати звітовану тестову оцінку як справжню тестову оцінку. Навіть ретельні джерела не завжди її мають — d2l каже про власні експерименти, що вони «насправді працюють із тим, що слід по праву називати навчальними й валідаційними даними, без справжніх тестових наборів» [1, §3.6.3]. Це відвертість, а не недбалість, і вона вартує такої ж відвертості щодо ваших власних чисел.
Ще не прочитаноДочитайте сторінку до кінця — і вона вважатиметься прочитаною.
Зберігайте свій прогресЗ доступом назавжди кожна дочитана сторінка позначається, і ви продовжуєте з того місця, де зупинилися, на всіх своїх пристроях.
Відкрити доступПеревірте себе
3 запитання
Кожну відповідь пояснено: який розділ вона перевіряє і з якого джерела.
На шпаргалці: Validation and generalisation →
Джерела
- Dive into Deep Learning — Generalizationbook · звірено 2026-09-21https://d2l.ai/chapter_linear-regression/generalization.html
- User Guide — Cross-validation: evaluating estimator performancedocs · звірено 2026-09-21https://scikit-learn.org/stable/modules/cross_validation.html