Как создать обучающий и тестовый набор из фрейма данных Pandas
При подгонке моделей машинного обучения к наборам данных мы часто разбиваем набор данных на два набора:
1. Набор для обучения: используется для обучения модели (70-80% исходного набора данных).
2. Тестовый набор: используется для получения объективной оценки производительности модели (20-30% исходного набора данных).
В Python существует два распространенных способа разделить DataFrame pandas на обучающий и тестовый наборы:
Способ 1: используйте train_test_split() из sklearn
from sklearn. model_selection import train_test_split train, test = train_test_split(df, test_size= 0.2 , random_state= 0 )
Способ 2: использовать sample() из панд
train = df.sample (frac= 0.8 ,random_state= 0 ) test = df.drop (train. index )
В следующих примерах показано, как использовать каждый метод со следующими пандами DataFrame:
import pandas as pd import numpy as np #make this example reproducible np.random.seed (1) #create DataFrame with 1,000 rows and 3 columns df = pd.DataFrame() #view first few rows of DataFrame df.head () x1 x2 y 0 5 1 1 1 11 8 0 2 12 4 1 3 8 7 0 4 9 0 0
Пример 1: Используйте train_test_split() из sklearn
В следующем коде показано, как использовать функцию train_test_split() из sklearn для разделения DataFrame pandas на обучающие и тестовые наборы:
from sklearn. model_selection import train_test_split #split original DataFrame into training and testing sets train, test = train_test_split(df, test_size= 0.2 , random_state= 0 ) #view first few rows of each set print(train.head()) x1 x2 y 687 16 2 0 500 18 2 1 332 4 10 1 979 2 8 1 817 11 1 0 print(test.head()) x1 x2 y 993 22 1 1 859 27 6 0 298 27 8 1 553 20 6 0 672 9 2 1 #print size of each set print(train. shape , test. shape ) (800, 3) (200, 3)
Из вывода мы видим, что было создано два набора:
- Учебный набор: 800 строк и 3 столбца.
- Набор для тестирования: 200 строк и 3 столбца.
Обратите внимание, что test_size управляет процентом наблюдений из исходного DataFrame, которые будут принадлежать тестовому набору, а значение random_state делает разделение воспроизводимым.
Пример 2: Используйте sample() из панд
В следующем коде показано, как использовать функцию sample() из pandas для разделения кадра данных pandas на обучающие и тестовые наборы:
#split original DataFrame into training and testing sets train = df.sample (frac= 0.8 ,random_state= 0 ) test = df.drop (train. index ) #view first few rows of each set print(train.head()) x1 x2 y 993 22 1 1 859 27 6 0 298 27 8 1 553 20 6 0 672 9 2 1 print(test.head()) x1 x2 y 9 16 5 0 11 12 10 0 19 5 9 0 23 28 1 1 28 18 0 1 #print size of each set print(train. shape , test. shape ) (800, 3) (200, 3)
Из вывода мы видим, что было создано два набора:
- Учебный набор: 800 строк и 3 столбца.
- Набор для тестирования: 200 строк и 3 столбца.
Обратите внимание, что frac управляет процентом наблюдений из исходного DataFrame, которые будут принадлежать обучающему набору, а значение random_state делает разделение воспроизводимым.
Дополнительные ресурсы
В следующих руководствах объясняется, как выполнять другие распространенные задачи в Python:
Как разбить .txt файл на обучающую и тестовую выборки (80/20)?
Обычно функцию train_test_split() используют уже после того как вы получили выборку, готовую к обучению. Все известные мне модели работают с числовыми матрицами/тензорами и не смогут работать напрямую с текстом или набором букв. Соответственно вам сначала придется обработать текст для того, чтобы получить из него числовую выборку и уже после этого нужно будет воспользоваться функцией train_test_split() для того, чтобы разделить выборку на обучающую и тестовую.
Отслеживать
ответ дан 6 дек 2020 в 14:34
MaxU — stand with Ukraine MaxU — stand with Ukraine
149k 12 12 золотых знаков 59 59 серебряных знаков 132 132 бронзовых знака
- python
- машинное-обучение
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.11.15.1019
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Примеры разделения датасета на train и test c Scikit-learn
Если вы разбиваете датасет на данные для обучения и тестирования, нужно помнить о некоторых моментах. Далее следует обсуждение трех передовых практик, которые стоит учитывать при подобном разделении. А также демонстрация того, как реализовать эти соображения в Python.
В данной статье обсуждаются три конкретных особенности, которые следует учитывать при разделении набора данных, подходы к решению связанных проблем и практическая реализация на Python.
Для наших примеров мы будем использовать модуль train_test_split библиотеки Scikit-learn, который очень полезен для разделения датасетов, независимо от того, будете ли вы применять Scikit-learn для выполнения других задач машинного обучения. Конечно, можно выполнить такие разбиения каким-либо другим способом (возможно, используя только Numpy). Библиотека Scikit-learn включает полезные функции, позволяющее сделать это немного проще.
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.67, random_state=42)Возможно, вы использовали этот модуль для разделения данных в прошлом, но при этом не приняли во внимание некоторые детали.
Случайное перемешивание строк
Первое, на что следует обратить внимание: перемешаны ли ваши экземпляры? Это следует делать пока нет причин не перетасовывать данные (например, они представляют собой временные интервалы). Мы должны убедиться в том, что наши экземпляры не разбиты на выборки по классам. Это потенциально вносит в нашу модель некоторую нежелательную предвзятость.
Например, посмотрите, как одна из версий набора данных iris, упорядочивает свои экземпляры при загрузке:
from sklearn.datasets import load_iris iris = load_iris() X, y = iris.data, iris.target print(f"Классы датасета: ")Классы датасета: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]Если такой набор данных с тремя классами при равном числе экземпляров в каждом разделить на две выборки: 2/3 для обучения и 1/3 для тестирования, то полученные поднаборы будут иметь нулевое пересечение классовых меток. Это, очевидно, недопустимо при изучении признаков для предсказания классов. К счастью, функция train_test_split по умолчанию автоматически перемешивает данные (вы можете переопределить это, установив для параметра shuffle значение False ).
- В функцию должны быть переданы как вектор признаков, так и целевой вектор (X и y).
- Для воспроизводимости вы должны установить аргумент random_state .
- Также необходимо определить либо train_size , либо test_size , но оба они не нужны. Если вы явно устанавливаете оба параметра, они должны составлять в сумме 1.
Вы можете убедится, что теперь наши классы перемешаны.
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.67, random_state=42) print(f"Классы в y_train:\n") print(f"Классы в y_test:\n")Классы в y_train: [1 2 1 0 2 1 0 0 0 1 2 0 0 0 1 0 1 2 0 1 2 0 2 2 1 1 2 1 0 1 2 0 0 1 1 0 2 0 0 1 1 2 1 2 2 1 0 0 2 2 0 0 0 1 2 0 2 2 0 1 1 2 1 2 0 2 1 2 1 1 1 0 1 1 0 1 2 2 0 1 2 2 0 2 0 1 2 2 1 2 1 1 2 2 0 1 2 0 1 2] Классы в y_test: [1 0 2 1 1 0 1 2 1 1 2 0 0 0 0 1 2 1 1 2 0 2 0 2 2 2 2 2 0 0 0 0 1 0 0 2 1 0 0 0 2 1 1 0 0 1 2 2 1 2]Стратификация (равномерное распределение) классов
Данное размышление заключается в следующем. Равномерно ли распределено количество классов в наборах данных, разделенных для обучения и тестирования?
import numpy as np print(f"Количество строк в y_train по классам: ") print(f"Количество строк в y_test по классам: ")Количество строк в y_train по классам: [31 35 34] Количество строк в y_test по классам: [19 15 16]Это не равная разбивка. Главная идея заключается в том, получает ли наш алгоритм равные возможности для изучения признаков каждого из представленных классов и последующего тестирования результатов обучения, на равном числе экземпляров каждого класса. Хотя это особенно важно для небольших наборов данных, желательно постоянно уделять внимание данному вопросу.
Мы можем задать пропорцию классов при разделении на обучающий и проверяющий датасеты с помощью параметра stratify функции train_test_split . Стоит отметить, что мы будем стратифицировать в соответствии распределению по классам в y .
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.67, random_state=42, stratify=y) print(f"Количество строк в y_train по классам: ") print(f"Количество строк в y_test по классам: ")Количество строк в y_train по классам: [34 33 33] Количество строк в y_test по классам: [16 17 17]Сейчас это выглядит лучше, и представленные числа говорят нам, что это наиболее оптимально возможное разделение.
Дополнительное разделение
Третье соображение относится к проверочным данным (выборке валидации). Есть ли смысл для нашей задачи иметь только один тестовый датасет. Или мы должны подготовить два таких набора — один для проверки наших моделей во время их точной настройки, а еще один — в качестве окончательного датасета для сравнения моделей и выбора лучшей.
Если мы определим 2 таких набора, это будет означать, что одна выборка, будет храниться до тех пор, пока все предположения не будут проверены, все гиперпараметры не настроены, а все модели обучены для достижения максимальной производительности. Затем она будет показана моделям только один раз в качестве последнего шага в наших экспериментах.
Если вы хотите использовать датасеты для тестирования и валидации, создать их с помощью train_test_split легко. Для этого мы разделяем весь набор данных один раз для выделения обучающей выборки. Затем еще раз, чтобы разбить оставшиеся данные на датасеты для тестирования и валидации.
Ниже, используя набор данных digits, мы разделяем 70% для обучения и временно назначаем остаток для тестирования. Не забывайте применять методы, описанные выше.
from sklearn.datasets import load_digits digits = load_digits() X, y = digits.data, digits.target X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7, random_state=42, stratify=y) print(f"Количество строк в y_train по классам: ") print(f"Количество строк в y_test по классам: ")Количество строк в y_train по классам: [124 127 124 128 127 127 127 125 122 126] Количество строк в y_test по классам: [54 55 53 55 54 55 54 54 52 54]Обратите внимание на стратифицированные классы в полученных наборах. Затем мы повторно делим тестовый датасет.
X_test, X_val, y_test, y_val = train_test_split(X_test, y_test, train_size=0.5, random_state=42, stratify=y_test) print(f"Количество строк в y_test по классам: ") print(f"Количество строк в y_val по классам: ")Количество строк в y_test по классам: [27 27 27 27 27 28 27 27 26 27] Количество строк в y_val по классам: [27 28 26 28 27 27 27 27 26 27]Обратите внимание на стратификацию классов по всем наборам данных, которая является оптимальной.
Теперь вы готовы обучать, проверять и тестировать столько моделей машинного обучения, сколько вы сочтете нужным для ваших данных.Еще один совет: вы можете подумать об использовании перекрестной валидации вместо простой стратегии обучение/тестирование или обучение/валидация/тестирование. Мы рассмотрим вопросы кросс-валидации в следующий раз.
Как разделить данные на обучающую и тестовую выборки
Узнайте, как правильно разделить данные на обучающую и тестовую выборки для оценки производительности моделей аналитики данных.
Алексей Кодов
Автор статьи
23 июня 2023 в 18:28Важным шагом в процессе аналитики данных является разделение исходных данных на обучающую и тестовую выборки. Это позволяет нам обучить модель на одной части данных и проверить ее производительность на другой, независимой части. В этой статье мы рассмотрим принципы разделения данных и примеры на практике.
Обучающая и тестовая выборки
Обучающая выборка используется для обучения модели, а тестовая выборка – для оценки ее производительности. Обычно данные делятся в пропорции 70-80% на обучение и 20-30% на тестирование.
Процесс разделения может быть случайным или стратифицированным. Случайное разделение означает, что каждый объект данных имеет одинаковый шанс попасть в обучающую или тестовую выборку. Стратифицированное разделение гарантирует, что в каждой из выборок будет представлено одинаковое соотношение классов.
Аналитик данных: новая работа через 5 месяцев
Получится, даже если у вас нет опыта в IT
Пример разделения данных на обучающую и тестовую выборки
Предположим, у нас есть набор данных размером 1000 объектов. Мы хотим разделить эти данные на обучающую и тестовую выборки в пропорции 70% и 30% соответственно.
Случайное разделение
В Python с помощью библиотеки sklearn мы можем использовать функцию train_test_split :
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)Здесь X и y – это исходные данные и метки классов соответственно, а random_state – это параметр, который гарантирует одинаковое разделение при каждом запуске.
Стратифицированное разделение
Для стратифицированного разделения мы также можем использовать функцию train_test_split , указав параметр stratify :
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state=42)Теперь в каждой из выборок будет одинаковое соотношение классов, что может быть полезным, если у нас есть несбалансированные данные.
Вывод
Разделение данных на обучающую и тестовую выборки является важным шагом в аналитике данных. Это позволяет нам оценить производительность модели на независимой выборке и предотвратить переобучение. В Python с помощью библиотеки sklearn можно легко разделить данные случайным или стратифицированным способом.
Удачного обучения и тестирования ваших моделей!


