#python #train-test-split #k-fold
#python #поезд-тест-сплит #k-кратный
Вопрос:
Я всего лишь новичок в ML и пытаюсь понять, в чем именно преимущество (стратифицированного) KFold перед классическим train_test_split.
Классический train_test_split использует ровно одну часть для обучения (в данном случае 75%) и одну часть для тестирования (в данном случае 25%). Здесь я точно знаю, какие точки данных используются для обучения и тестирования (см. Код)
При разделении с помощью (стратифицированного) Kfold мы используем 4 разделения, в результате чего у нас получается 4 разных обучающих / тестовых части. Для меня неясно, какая из 4 частей будет использоваться для обучения / тестирования логистической регрессии. Имеет ли смысл устанавливать это разделение таким образом? Насколько я понял, преимущество (стратифицированного) Kfold заключается в том, что вы можете использовать все данные для обучения. Как мне нужно изменить код для достижения этой цели?
Создание данных
import pandas as pd
import numpy as np
target = np.ones(25)
target[-5:] = 0
df = pd.DataFrame({'col_a':np.random.random(25),
'target':target})
df
train_test_split
from sklearn.model_selection import train_test_split
X = df.col_a
y = df.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, shuffle=True)
print("TRAIN:", X_train.index, "TEST:", X_test.index)
Output:
TRAIN: Int64Index([1, 13, 8, 9, 21, 12, 10, 4, 20, 19, 7, 5, 15, 22, 24, 17, 11, 23], dtype='int64')
TEST: Int64Index([2, 6, 16, 0, 14, 3, 18], dtype='int64')
Стратифицированный KFold
from sklearn.model_selection import StratifiedKFold
X = df.col_a
y = df.target
skf = StratifiedKFold(n_splits=4)
for train_index, test_index in skf.split(X, y):
X_train, X_test = X.loc[train_index], X.loc[test_index]
y_train, y_test = y.loc[train_index], y.loc[test_index]
print("TRAIN:", train_index, "TEST:", test_index)
Output:
TRAIN: [ 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 22 23 24] TEST: [ 0 1 2 3 4 20 21]
TRAIN: [ 0 1 2 3 4 10 11 12 13 14 15 16 17 18 19 20 21 23 24] TEST: [ 5 6 7 8 9 22]
TRAIN: [ 0 1 2 3 4 5 6 7 8 9 15 16 17 18 19 20 21 22 24] TEST: [10 11 12 13 14 23]
TRAIN: [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 20 21 22 23] TEST: [15 16 17 18 19 24]
Использование логистической регрессии
from sklearn.linear_model import LogisticRegression
X_train = X_train.reshape(-1, 1)
X_test = X_test.reshape(-1, 1)
clf = LogisticRegression()
clf.fit(X_train, y_train)
clf.predict(X_test)
Ответ №1:
Начнем с того, что они оба делают то же самое, но то, как они это делают, имеет значение.
Тест-разделение поезда:
Test-train split случайным образом разбивает данные на тестовые и обучающие наборы. Нет никаких правил, кроме процентного разделения.
У вас будет только одна обучающая информация для обучения и одна тестовая информация для тестирования модели.
K-кратный:
Данные случайным образом разбиваются на несколько комбинаций тестовых и обучающих данных. Единственным правилом здесь является количество комбинаций.
Проблема с разделением данных случайным образом может привести к искажению представления класса — т. Е. Один или несколько целевых классов представлены в тестовом / обучающем разделении больше, чем другие. Это может привести к смещению в обучении модели.
Чтобы предотвратить это, тестовые и обучающие разбиения должны иметь одинаковые пропорции целевых классов. Этого можно достичь с помощью StratifiedKFold .
Если вам нравится смотреть видео (смотреть с ~ 4.30): https://youtu.be/gJo0uNL-5Qw
Примечание: если вы пытаетесь улучшить обучение с помощью kfold, то может помочь объединение StratifiedKFold с GridSearchCV .
Ответ №2:
у train_test_split есть вызываемый параметр stratify
. Выбор его в отношении меток гарантирует, что у вас будет равное представление классов как в обучающих, так и в тестовых данных. Согласно документации
Если нет, данные разделяются стратифицированным образом, используя это в качестве меток классов.