Відповіді:
Ви могли просто використовувати sklearn.model_selection.train_test_split
двічі. Спершу розділити поїзд, протестувати, а потім розділити поїзд знову на перевірку та поїзд. Щось на зразок цього:
X_train, X_test, y_train, y_test
= train_test_split(X, y, test_size=0.2, random_state=1)
X_train, X_val, y_train, y_val
= train_test_split(X_train, y_train, test_size=0.2, random_state=1)
train_test_split
, ви робите це протягом попереднього розколу 80/20. Значить, ваш вал становить 20% від 80%. Розподільні пропорції не дуже прості.
На це питання є чудова відповідь на SO, який використовує numpy та панди.
Команда (див. Відповідь для обговорення):
train, validate, test = np.split(df.sample(frac=1), [int(.6*len(df)), int(.8*len(df))])
виробляє 60%, 20%, 20% розбиття для навчальних, валідаційних та тестових наборів.
.6
значення 60% ... але що це .8
означає?
np.split
розділить на 60% довжини перетасованого масиву, потім 80% довжини (що становить додаткові 20% даних), тим самим залишивши 20% даних. Це пов’язано з визначенням функції. Ви можете випробувати / грати з:, x = np.arange(10.0)
а даліnp.split(x, [ int(len(x)*0.6), int(len(x)*0.8)])
Найчастіше ви виявите, що ви не розділяєте їх один раз, але на першому кроці ви поділите свої дані в навчальному і тестовому наборі. Згодом ви виконаєте пошук параметрів, включаючи більш складні розбиття, такі як перехресна перевірка з алгоритмом 'split k-fold' або 'left-one-out (LOO)'.
Можна використовувати train_test_split
двічі. Я думаю, що це найпростіше.
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=1)
X_train, X_val, y_train, y_val = train_test_split(
X_train, y_train, test_size=0.25, random_state=1)
Таким чином, train
, val
, test
набір буде 60%, 20%, 20% набору даних відповідно.
Найкраща відповідь вище не зазначає, що, розділяючи два рази, train_test_split
не змінюючи розміри розділу, ви не дасте початково призначеного розділу:
x_train, x_remain = train_test_split(x, test_size=(val_size + test_size))
Тоді частина наборів перевірки та тестування в x_remain змінюється і може бути зарахована як
new_test_size = np.around(test_size / (val_size + test_size), 2)
# To preserve (new_test_size + new_val_size) = 1.0
new_val_size = 1.0 - new_test_size
x_val, x_test = train_test_split(x_remain, test_size=new_test_size)
У цьому випадку всі початкові розділи зберігаються.
Ось ще один підхід (передбачає рівний тристоронній розкол):
# randomly shuffle the dataframe
df = df.reindex(np.random.permutation(df.index))
# how many records is one-third of the entire dataframe
third = int(len(df) / 3)
# Training set (the top third from the entire dataframe)
train = df[:third]
# Testing set (top half of the remainder two third of the dataframe)
test = df[third:][:third]
# Validation set (bottom one third)
valid = df[-third:]
Це можна зробити більш стислим, але я дотримувався його багатослівного для пояснення.
Враховуючи train_frac=0.8
, ця функція створює 80% / 10% / 10% розбиття:
import sklearn
def data_split(examples, labels, train_frac, random_state=None):
''' https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html
param data: Data to be split
param train_frac: Ratio of train set to whole dataset
Randomly split dataset, based on these ratios:
'train': train_frac
'valid': (1-train_frac) / 2
'test': (1-train_frac) / 2
Eg: passing train_frac=0.8 gives a 80% / 10% / 10% split
'''
assert train_frac >= 0 and train_frac <= 1, "Invalid training set fraction"
X_train, X_tmp, Y_train, Y_tmp = sklearn.model_selection.train_test_split(
examples, labels, train_size=train_frac, random_state=random_state)
X_val, X_test, Y_val, Y_test = sklearn.model_selection.train_test_split(
X_tmp, Y_tmp, train_size=0.5, random_state=random_state)
return X_train, X_val, X_test, Y_train, Y_val, Y_test
Додавання до відповіді @ hh32 , дотримуючись будь-яких заздалегідь визначених пропорцій, таких як (75, 15, 10):
train_ratio = 0.75
validation_ratio = 0.15
test_ratio = 0.10
# train is now 75% of the entire data set
# the _junk suffix means that we drop that variable completely
x_train, x_test, y_train, y_test = train_test_split(dataX, dataY, test_size=1 - train_ratio)
# test is now 10% of the initial data set
# validation is now 15% of the initial data set
x_val, x_test, y_val, y_test = train_test_split(x_test, y_test, test_size=test_ratio/(test_ratio + validation_ratio))
print(x_train, x_val, x_test)
Подовження відповіді @ hh32 із збереженими співвідношеннями.
# Defines ratios, w.r.t. whole dataset.
ratio_train = 0.8
ratio_val = 0.1
ratio_test = 0.1
# Produces test split.
x_remaining, x_test, y_remaining, y_test = train_test_split(
x, y, test_size=test_ratio)
# Adjusts val ratio, w.r.t. remaining dataset.
ratio_remaining = 1 - ratio_test
ratio_val_adjusted = ratio_val / ratio_remaining
# Produces train and val splits.
x_train, x_val, y_train, y_val = train_test_split(
x_remaining, y_remaining, test_size=ratio_val_adjusted)
Оскільки решта даних зменшується після першого розбиття, нові співвідношення відносно скороченого набору даних повинні бути обчислені шляхом вирішення рівняння: