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

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

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

1. **Тренировочный набор (Training Set)** используется для обучения модели, то есть подстройки ее параметров на основе этих данных. Модель "изучает" закономерности, присутствующие в тренировочных данных.
2. **Валидационный набор (Validation Set)** применяется для отслеживания производительности модели во время обучения и выбора наилучших гиперпараметров (параметров, не настраиваемых в процессе обучения). Модель периодически оценивается на валидационном наборе, и ее гиперпараметры подбираются таким образом, чтобы достичь максимальной производительности на этом наборе.
3. **Тестовый набор (Test Set)** используется для окончательной оценки производительности обученной модели на "новых" данных, которые не участвовали в процессе обучения и валидации. Это позволяет получить наиболее объективную оценку обобщающей способности модели.

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

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

* **Тренировочный набор**: 60-80% исходных данных
* **Валидационный набор**: 10-20% исходных данных
* **Тестовый набор**: 10-20% исходных данных

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

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

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

```python
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. Строим график цены закрытия, используя разные цвета для каждого набора данных.

<figure><img src="https://1003793957-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyNGqUz7iEjhOGUGQJzfG%2Fuploads%2FOXS5FPGAn5ylAOjjt22T%2F%D0%A0%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85.png?alt=media&#x26;token=b1a6d948-7244-45c2-ad07-1eee92df0a2d" alt=""><figcaption></figcaption></figure>

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