Разделение данных на тренировочный, валидационный и тестовый наборы

Одним из важнейших способов контроля обучения моделей машинного обучения, в том числе классифицирующих нейронных сетей, является разделение исходного набора данных на три независимые части: тренировочный, валидационный и тестовый наборы. Это позволяет оценить обобщающую способность модели и предотвратить переобучение.

Назначение каждого набора

  1. Тренировочный набор (Training Set) используется для обучения модели, то есть подстройки ее параметров на основе этих данных. Модель "изучает" закономерности, присутствующие в тренировочных данных.

  2. Валидационный набор (Validation Set) применяется для отслеживания производительности модели во время обучения и выбора наилучших гиперпараметров (параметров, не настраиваемых в процессе обучения). Модель периодически оценивается на валидационном наборе, и ее гиперпараметры подбираются таким образом, чтобы достичь максимальной производительности на этом наборе.

  3. Тестовый набор (Test Set) используется для окончательной оценки производительности обученной модели на "новых" данных, которые не участвовали в процессе обучения и валидации. Это позволяет получить наиболее объективную оценку обобщающей способности модели.

Типичное распределение данных

Общепринятой практикой является следующее распределение данных:

  • Тренировочный набор: 60-80% исходных данных

  • Валидационный набор: 10-20% исходных данных

  • Тестовый набор: 10-20% исходных данных

Точное распределение зависит от размера исходного набора данных и специфики задачи.

Пример разделения данных в Python

Рассмотрим пример разделения данных на тренировочный, валидационный и тестовый наборы с помощью библиотеки scikit-learn:

import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

# Загрузка данных котировок BTC с yfinance
ticker = "BTC-USD"
data = yf.download(ticker, start="2020-01-01", end="2023-01-01")

# Преобразование данных в формат Pandas DataFrame
data = pd.DataFrame(data["Adj Close"])
data = data.rename(columns={"Adj Close": "Price"})

# Разделение данных на тренировочный, валидационный и тестовый наборы
train_size = 0.6
val_size = 0.2
test_size = 0.2

X_train, X_test, y_train, y_test = train_test_split(data.index, data["Price"], test_size=test_size, shuffle=False)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=val_size/(train_size+val_size), shuffle=False)

# Построение графика цены закрытия
plt.figure(figsize=(12, 6))
plt.plot(X_train, y_train, color='green', label='Тренировочный набор')
plt.plot(X_val, y_val, color='blue', label='Валидационный набор')
plt.plot(X_test, y_test, color='red', label='Тестовый набор')
plt.xlabel('Дата')
plt.ylabel('Цена закрытия')
plt.title(f'Котировки {ticker}')
plt.legend()
plt.show()

В этом примере:

  1. Мы загружаем исторические данные котировок BTC с помощью yfinance.

  2. Преобразуем данные в формат Pandas DataFrame и оставляем только цену закрытия.

  3. Разделяем данные на тренировочный (60%), валидационный (20%) и тестовый (20%) наборы с помощью train_test_split из scikit-learn. Параметр shuffle=False сохраняет временную последовательность данных.

  4. Строим график цены закрытия, используя разные цвета для каждого набора данных.

Правильное разделение данных на независимые наборы имеет критическое значение для корректной оценки производительности модели и предотвращения переобучения. Использование валидационного набора позволяет настроить гиперпараметры модели, а тестовый набор дает финальную, наиболее объективную оценку качества обученной модели на "новых" данных.

Last updated