5

Как создать тестовые и обучающие выборки из одного DataFrame с помощью pandas?

17

У меня есть довольно большой набор данных в виде датафрейма, и я хотел бы узнать, как можно разбить этот датафрейм на две случайные выборки (80% для тренировки и 20% для тестирования).

Спасибо!

5 ответ(ов)

4

Вы можете использовать randn из библиотеки NumPy для генерации случайных данных, как показано в следующем примере:

import pandas as pd
import numpy as np

# Генерируем DataFrame с 100 строками и 2 столбцами случайных значений
df = pd.DataFrame(np.random.randn(100, 2))

# Создаем маску для разделения данных на обучающую и тестовую выборки
msk = np.random.rand(len(df)) < 0.8

# Формируем обучающую выборку
train = df[msk]

# Формируем тестовую выборку
test = df[~msk]

Чтобы убедиться, что разбиение произошло корректно, можно вывести длину обеих выборок:

# Выводим длину тестовой выборки
print(len(test))  # должно быть около 21

# Выводим длину обучающей выборки
print(len(train))  # должно быть около 79

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

4

Использование метода sample в Pandas позволяет случайным образом выбирать данные для обучения и тестирования следующим образом:

train = df.sample(frac=0.8, random_state=200)
test = df.drop(train.index)

Здесь параметр frac=0.8 указывает, что мы выбираем 80% данных для обучающей выборки, а оставшиеся 20% автоматически составляют тестовую выборку. При использовании одного и того же значения random_state вы всегда будете получать один и тот же набор данных в обучающей и тестовой выборках. Это добавляет уровень повторяемости, сохраняя при этом случайное разделение данных. Такой подход особенно полезен для обеспечения устойчивости к изменениям в обучении вашей модели.

0

Если вы хотите разделить данные на обучающую и тестовую выборки, то я бы использовал функцию train_test_split из библиотеки scikit-learn. Вы можете сгенерировать индексы для выборок следующим образом:

from sklearn.model_selection import train_test_split

y = df.pop('output')  # Извлекаем целевую переменную
X = df  # Оставляем только признаки

# Разделяем данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X.index, y, test_size=0.2)

# Получаем DataFrame для обучающей выборки
X_train_df = X.iloc[X_train]  # Вернёт DataFrame для обучающей выборки

Здесь X_train будет содержать индексы обучающей выборки, а X.iloc[X_train] вернет соответствующие строки из оригинального DataFrame X. Убедитесь, что вы корректно извлекаете целевую переменную y из вашего DataFrame с помощью pop().

0

Нет необходимости конвертировать в NumPy. Просто используйте DataFrame из pandas для выполнения разделения, и он вернёт DataFrame.

from sklearn.model_selection import train_test_split

train, test = train_test_split(df, test_size=0.2)

Если вы хотите разделить X и y, то используйте следующий код:

X_train, X_test, y_train, y_test = train_test_split(df[list_of_x_cols], df[y_col], test_size=0.2)

А если вы хотите разделить весь DataFrame:

X, y = df[list_of_x_cols], df[y_col]
0

Вопрос: Как правильно создать обучающую, тестовую и валидационную выборки для различных случаев в sklearn?

Ответ:

Существует множество способов создания обучающих/тестовых и даже валидационных выборок в зависимости от ваших потребностей и структуры данных. Вот несколько типичных случаев:

Случай 1: Классический способ train_test_split без дополнительных опций.

from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.3)

В этом примере данные делятся на обучающую (70%) и тестовую (30%) выборки без каких-либо дополнительных параметров.

Случай 2: Для очень небольших наборов данных (<500 строк) лучше использовать кросс-валидацию. В результате вы получите предсказания для каждой строки обучающего набора.

from sklearn.model_selection import KFold
kf = KFold(n_splits=10, random_state=0)
y_hat_all = []
for train_index, test_index in kf.split(X, y):
    reg = RandomForestRegressor(n_estimators=50, random_state=0)
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    clf = reg.fit(X_train, y_train)
    y_hat = clf.predict(X_test)
    y_hat_all.append(y_hat)

Здесь используется KFold для разделения данных на 10 частей, что позволяет каждому примеру участвовать в обучении и тестировании.

Случай 3а: Небалансированные наборы данных для задач классификации. Аналогично случаю 1, вы можете использовать параметр stratify:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.3)

Это гарантирует, что выборка будет сбалансирована по классам.

Случай 3б: Небалансированные наборы данных для задач классификации с использованием кросс-валидации. Используйте StratifiedKFold для сбалансированного разделения:

from sklearn.model_selection import StratifiedKFold
kf = StratifiedKFold(n_splits=10, random_state=0)
y_hat_all = []
for train_index, test_index in kf.split(X, y):
    reg = RandomForestRegressor(n_estimators=50, random_state=0)
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    clf = reg.fit(X_train, y_train)
    y_hat = clf.predict(X_test)
    y_hat_all.append(y_hat)

Этот подход позволяет эффективно работать с небалансированными данными, обеспечивая равноценное представительство классов.

Случай 4: Вы хотите создать обучающие, тестовые и валидационные наборы на больших данных для настройки гиперпараметров (60% — обучение, 20% — тестирование, 20% — валидация).

from sklearn.model_selection import train_test_split
X_train, X_test_val, y_train, y_test_val = train_test_split(X, y, test_size=0.6)
X_test, X_val, y_test, y_val = train_test_split(X_test_val, y_test_val, stratify=y, test_size=0.5)

Сначала мы делим данные на тренировочный набор и временный набор (тест и валидация), а затем временный набор разбивается на тестовый и валидационный.

Каждый из этих подходов может быть адаптирован в зависимости от конкретной задачи и структуры ваших данных.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь