Как разделить выборку на обучающую и тестовую python

Как разделить выборку на обучающую и тестовую python

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

Один из самых распространённых способов разделить данные – это функция train_test_split из модуля sklearn.model_selection. Эта функция автоматически разделяет массив данных на две части: обучающую и тестовую. Важно помнить, что разделение данных должно быть случайным, чтобы избежать смещения результатов, однако в некоторых случаях можно использовать параметр stratify, который позволяет учитывать распределение классов в данных, что особенно важно при работе с несбалансированными выборками.

Типичная пропорция разделения – 70-80% данных для обучения и 20-30% для тестирования. Однако в зависимости от объема данных и конкретной задачи этот баланс может варьироваться. При малом объеме данных рекомендуется использовать кросс-валидацию, чтобы максимально эффективно использовать все доступные данные для тренировки модели и её оценки.

Необходимо также учитывать важность случайности при разделении. Даже при одинаковых данных, каждый запуск функции train_test_split может давать разные результаты. Для обеспечения воспроизводимости экспериментов, можно задать параметр random_state, который фиксирует начальное состояние генератора случайных чисел, гарантируя одинаковое разделение при повторных запусках.

Как использовать train_test_split из библиотеки scikit-learn для деления данных

Как использовать train_test_split из библиотеки scikit-learn для деления данных

Основной синтаксис функции:

train_test_split(*arrays, test_size=None, train_size=None, random_state=None, shuffle=True, stratify=None)
  • *arrays – массивы или DataFrame, которые нужно разделить (например, признаки и целевая переменная).
  • test_size – доля данных, которая пойдет в тестовую выборку. Обычно указывается значение от 0 до 1. Например, 0.2 – это 20% данных для теста.
  • train_size – доля данных для обучающей выборки. Если указана и test_size не задана, это параметр определяет размер обучающей выборки.
  • random_state – параметр для фиксирования случайных чисел, что делает разбиение повторяемым при одинаковых параметрах.
  • shuffle – флаг, который контролирует, нужно ли перемешивать данные перед разбиением. По умолчанию True.
  • stratify – позволяет разделить данные с учётом распределения классов целевой переменной, что особенно важно для классификации, чтобы сохранить пропорции классов в обучающей и тестовой выборках.

Пример использования:

from sklearn.model_selection import train_test_split
X = ...  # Признаки
y = ...  # Целевая переменная
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)

В этом примере данные разделяются на 70% для обучения и 30% для тестирования. Параметр stratify=y обеспечивает, что распределение классов в обучающей и тестовой выборках будет одинаковым. Указание random_state=42 позволяет повторить разбиение с теми же самыми результатами в будущем.

Дополнительные рекомендации:

  • Если в данных имеются выбросы или сильные дисбалансы, рассмотрите возможность применения стратифицированного разбиения для сохранения пропорций классов в обеих выборках.
  • При работе с большими данными можно использовать shuffle=False, чтобы ускорить процесс разделения, если данные уже случайным образом перемешаны.
  • Перед делением важно убедиться, что данные подготовлены (например, нормализованы или стандартизированы), чтобы разделение не влияло на результаты.

Функция train_test_split – это простой и быстрый способ организовать корректное разбиение данных, что значительно упрощает подготовку данных для дальнейшего обучения моделей машинного обучения.

Какие параметры train_test_split влияют на размер выборок

Какие параметры train_test_split влияют на размер выборок

test_size – это параметр, который определяет долю данных, выделяемых для тестирования. Значение может быть числовым, например, 0.2, что означает 20% от общего объема данных, или целым числом, которое указывает количество объектов в тестовой выборке. Важно помнить, что если задан только test_size, то train_size рассчитывается автоматически как разница между размером всей выборки и размером тестовой.

train_size аналогичен test_size, но отвечает за размер обучающей выборки. Установив это значение, можно точно контролировать долю данных, которая пойдет на обучение. Если задан и train_size, и test_size, то они должны совместно покрывать все данные, в противном случае возникнет ошибка.

Если оба параметра не указаны, то по умолчанию используется стандартная настройка, при которой тестовая выборка составляет 25% данных, а обучающая – 75%. Система сама определяет пропорции, если оба значения отсутствуют.

random_state не влияет напрямую на размер выборок, но оказывает влияние на воспроизводимость разбиения данных. Установка фиксированного значения для random_state гарантирует, что разбиение будет одинаковым при каждом запуске функции, что особенно важно при проведении экспериментов и сравнении моделей.

Влияние параметров test_size и train_size напрямую связано с размером исходной выборки. Например, при большом объеме данных небольшие изменения в значениях этих параметров не оказывают сильного влияния на конечный результат, но для малых выборок изменение одного из параметров может существенно повлиять на обучение модели.

Как сохранить разделённые данные в новые файлы

Для сохранения разделённых данных в новые файлы в Python можно использовать библиотеки pandas и scikit-learn. После того как данные будут разделены на обучающую и тестовую выборки, необходимо сохранить их в отдельные файлы, чтобы впоследствии использовать их для обучения модели и оценки её качества. Рассмотрим, как это сделать.

Для начала загрузим необходимые библиотеки и разделим данные. В примере ниже используется pandas для работы с данными и scikit-learn для их разделения:

import pandas as pd
from sklearn.model_selection import train_test_split
# Загрузка данных
data = pd.read_csv('data.csv')
# Разделение на обучающую и тестовую выборки
train_data, test_data = train_test_split(data, test_size=0.2, random_state=42)

После того как данные разделены, можно сохранить их в новые файлы. Для этого используем функцию to_csv() из библиотеки pandas. Этот метод позволяет сохранять данные в формате CSV.

Пример сохранения обучающей и тестовой выборок в файлы:

train_data.to_csv('train_data.csv', index=False)
test_data.to_csv('test_data.csv', index=False)

Здесь index=False означает, что индексы строк не будут сохраняться в файл, что часто бывает ненужно при обработке данных. Если требуется, можно настроить разделители или кодировку с помощью дополнительных параметров метода to_csv().

Если ваши данные представлены в другом формате, например, в виде Excel-файла, можно использовать метод to_excel() для сохранения выборок в Excel:

train_data.to_excel('train_data.xlsx', index=False)
test_data.to_excel('test_data.xlsx', index=False)

Для работы с большими объёмами данных или сохранения их в других форматах (например, JSON) также доступны аналогичные методы, такие как to_json() или to_pickle().

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

Как разделить данные на обучающую и тестовую выборки с учётом классов (stratify)

Как разделить данные на обучающую и тестовую выборки с учётом классов (stratify)

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

Для этого в библиотеке scikit-learn есть удобный метод train_test_split, который принимает параметр stratify. При указании этого параметра данные разделяются так, что соотношение классов в обучающей и тестовой выборке сохраняется. Например, если в исходных данных 70% положительных и 30% отрицательных примеров, то аналогичное соотношение будет соблюдаться в каждой выборке.

Пример использования:

from sklearn.model_selection import train_test_split
X = # ваши данные
y = # метки классов
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)

В этом примере train_test_split разделяет данные так, чтобы 20% данных оказалось в тестовой выборке, при этом пропорции классов в y_train и y_test будут одинаковыми, как в исходной выборке.

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

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

Как разделить данные с временными метками на обучающую и тестовую выборки

Как разделить данные с временными метками на обучающую и тестовую выборки

При работе с временными рядами нельзя перемешивать данные перед разделением, так как это нарушит хронологический порядок. Модель должна обучаться на прошлых значениях и проверяться на будущих.

Рекомендуется использовать деление по дате. Например, если данные охватывают период с 2015 по 2024 год, можно взять всё до конца 2022 года как обучающую выборку, а данные с 2023 года – как тестовую. Такой подход гарантирует, что модель будет проверяться на ещё не встречавшихся значениях.

В pandas это делается через фильтрацию по дате:

df['timestamp'] = pd.to_datetime(df['timestamp'])
train = df[df['timestamp'] < '2023-01-01']
test = df[df['timestamp'] >= '2023-01-01']

Если данных немного, можно использовать скользящее окно: например, обучаться на 3 предыдущих года, тестироваться на следующем. Затем окно сдвигается вперёд. Это позволяет проверить устойчивость модели во времени.

Нельзя использовать функцию train_test_split, так как она не учитывает порядок. В задачах с временными метками важно сохранить последовательность событий.

Как правильно разделить данные, если их слишком мало

Как правильно разделить данные, если их слишком мало

При ограниченном объёме данных стандартное разбиение на обучающую и тестовую выборки (например, 80/20) может привести к потере информации. В таких случаях предпочтительнее использовать перекрёстную проверку.

Наиболее надёжный метод – K-fold cross-validation. Данные делятся на K равных частей. Каждая из них поочерёдно используется как тестовая, а оставшиеся – как обучающие. Это позволяет использовать все доступные данные для обучения и оценки.

Если данных крайне мало (менее 50 наблюдений), лучше использовать Leave-One-Out Cross-Validation (LOOCV). Каждый объект поочерёдно становится тестовым, а оставшиеся – обучающими. Это даёт максимально возможное использование данных, но требует больше времени на вычисления.

Пример разбиения с использованием K-fold:

from sklearn.model_selection import KFold
import numpy as np
X = np.array([[1], [2], [3], [4], [5]])
y = np.array([1, 2, 3, 4, 5])
kf = KFold(n_splits=5)
for train_index, test_index in kf.split(X):
print("Обучающая:", train_index, "Тестовая:", test_index)

Если модель выбирается из нескольких, необходимо включать перекрёстную проверку и на этапе подбора параметров, чтобы избежать переобучения. В таких случаях используйте Nested Cross-Validation.

При использовании нейронных сетей, где перекрёстная проверка затратна, можно уменьшить долю валидации (например, 90/10) и применять регуляризацию или раннюю остановку для контроля переобучения.

В малых выборках важно зафиксировать генератор случайных чисел для воспроизводимости результатов:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Избегайте случайного разбиения без стратификации при несбалансированных классах. Для этого используйте параметр stratify:

train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)

Как использовать кросс-валидацию для проверки моделей на разных выборках

Как использовать кросс-валидацию для проверки моделей на разных выборках

Кросс-валидация делит выборку на несколько непересекающихся подмножеств и поочерёдно использует каждое из них в роли тестовой. Наиболее распространённый вариант – KFold. Например, KFold(n_splits=5) делит данные на 5 частей: модель обучается на четырёх и проверяется на оставшейся, процедура повторяется 5 раз.

Для применения кросс-валидации используйте cross_val_score из sklearn.model_selection. Пример:

from sklearn.model_selection import cross_val_score, KFold
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
kf = KFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(model, X, y, cv=kf)

Параметр shuffle=True обязателен, если порядок объектов в выборке не случаен. Без перемешивания возможна утечка информации или смещение оценок. random_state фиксирует результат.

Для несбалансированных классов используйте StratifiedKFold, который сохраняет пропорции классов в каждом подмножестве:

from sklearn.model_selection import StratifiedKFold
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

Значения cross_val_score – это метрики качества модели на каждой итерации. Для средней оценки используйте scores.mean(), для оценки разброса – scores.std(). Это даст представление о стабильности модели.

Если требуется использовать собственные метрики, передайте параметр scoring, например scoring='f1' или scoring='neg_log_loss'. Список поддерживаемых метрик доступен в sklearn.metrics.get_scorer_names().

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

Вопрос-ответ:

Ссылка на основную публикацию