Хороший способ понять суть тестовой выборки сравнить её с экзаменом. Когда студент готовится к экзамену, он изучает учебный материал и решает задачи из учебника, запоминая принципы их решения. Но на самом экзамене ему предлагаются совершенно новые задачи, которые он раньше не видел. Если он действительно понял материал, он сможет их решить, даже если они отличаются от тех, что были в учебнике. Если же он просто заучил решения конкретных примеров, но не понял сути, то на экзамене он растеряется и не сможет справиться с новыми задачами.
С моделью машинного обучения происходит то же самое. Если она слишком сильно запомнила обучающие данные, но не научилась их обобщать, она провалит тестирование. Это называется переобучением модель становится слишком привязанной к обучающему набору и плохо справляется с новыми данными. Именно поэтому тестирование на независимой выборке является обязательным этапом, который позволяет выявить, насколько модель действительно готова к практическому применению.
Чаще всего данные делят в пропорции: 70-80% на обучение и 20-30% на тестирование. Такой баланс выбран неслучайно. Если выделить слишком мало данных для обучения, модель не сможет выявить устойчивые закономерности, так как у неё будет недостаточно примеров. Если же оставить слишком мало данных для тестирования, то сложно будет объективно оценить качество модели: её результаты на новой информации могут оказаться случайными.
Дополнительно иногда выделяют валидационную выборку отдельный набор данных, который используется во время настройки модели. Это особенно важно при выборе гиперпараметров, таких как сложность модели или скорость обучения. Валидационные данные позволяют тестировать различные конфигурации модели без риска подгонки под тестовую выборку. Если этого не делать, можно случайно подобрать модель, которая хорошо работает только на тестовых данных, но плохо справляется с реальными задачами.
Такое разделение можно сравнить с процессом подготовки спортсмена к соревнованиям. На этапе тренировок (обучающая выборка) он изучает
технику, развивает выносливость и учится справляться с нагрузками. Перед важным турниром он может участвовать в контрольных тренировках и пробных забегах (валидационная выборка), где тестирует свою подготовку. Но финальная проверка его навыков это соревнование (тестовая выборка), на котором становится ясно, насколько хорошо он умеет применять свои знания и навыки в реальных условиях.
Без тестирования на новых данных невозможно сказать, действительно ли модель научилась решать задачу или просто запомнила ответы из обучающей выборки. Если модель показывает отличные результаты на обучающих данных, но терпит неудачу на тестовых, значит, она переобучилась и не сможет работать с реальными данными. Именно поэтому правильное разделение данных является обязательным шагом в процессе создания моделей машинного обучения.
Рассмотрим несколько примеров кода на Python с использованием библиотеки `scikit-learn`, чтобы лучше понять процесс разделения данных.
Пример 1: Базовое разбиение данных
Этот код показывает, как разделить данные на обучающую и тестовую выборки с помощью `train_test_split`.
```python
from sklearn.model_selection import train_test_split
import numpy as np
# Создадим массив данных (обычно здесь загружаются реальные данные)
X = np.array([[i] for i in range(1, 11)]) # Признаки (например, номера объектов)
y = np.array([i * 2 for i in range(1, 11)]) # Целевые значения (например, цены)
# Разделяем на 80% обучение, 20% тест
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print("Обучающая выборка (X_train):", X_train.ravel())
print("Тестовая выборка (X_test):", X_test.ravel())
```
Вывод: Обучающая и тестовая выборки будут сформированы случайным образом, но примерно 80% данных пойдет на обучение, а 20% на тестирование.
Пример 2: Добавление валидационной выборки
Иногда, помимо тестовой выборки, выделяют валидационную. Это можно сделать в два этапа.
```python
# Разделяем данные: 70% обучение, 15% валидация, 15% тест
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.3, random_state=42)
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)
print("Обучающая выборка:", X_train.ravel())
print("Валидационная выборка:", X_val.ravel())
print("Тестовая выборка:", X_test.ravel())
```
Объяснение: Сначала мы отделяем 70% данных для обучения, а затем оставшиеся 30% делим пополам, чтобы получить валидационную и тестовую выборки по 15% каждая.
Пример 3: Разбиение данных в задаче машинного обучения (предсказание цен квартир)
Этот пример показывает реальное применение разбиения данных в задаче предсказания стоимости квартир.
```python
import pandas as pd
from sklearn.model_selection import train_test_split
# Загрузим данные (пример сгенерированных данных)
data = pd.DataFrame({
"Площадь": [30, 45, 60, 75, 90, 105, 120, 135, 150, 165],
"Этаж": [2, 3, 5, 1, 8, 10, 12, 15, 17, 20],
"Цена": [3.5, 5.2, 6.8, 7.1, 9.3, 10.5, 12.7, 14.2, 15.8, 17.5] # Цена в миллионах рублей