Jawaban:
Anda bisa menggunakan sklearn.model_selection.train_test_split
dua kali saja. Pertama untuk membagi untuk melatih, menguji dan kemudian membagi lagi kereta ke validasi dan melatih. Sesuatu seperti ini:
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
, Anda melakukan ini selama 80/20 sebelumnya. Jadi val Anda adalah 20% dari 80%. Proporsi pembagian tidak terlalu mudah dengan cara ini.
Ada jawaban yang bagus untuk pertanyaan ini pada SO yang menggunakan numpy dan panda.
Perintah (lihat jawaban untuk diskusi):
train, validate, test = np.split(df.sample(frac=1), [int(.6*len(df)), int(.8*len(df))])
menghasilkan pemisahan 60%, 20%, 20% untuk pelatihan, validasi, dan set tes.
.6
artinya 60% ... tapi apa .8
artinya?
np.split
akan membagi 60% dari panjang array yang dikocok, kemudian 80% dari panjang (yang merupakan 20% dari data tambahan), sehingga menyisakan 20% dari data yang tersisa. Ini karena definisi fungsi. Anda dapat menguji / bermain dengan x = np.arange(10.0)
np.split(x, [ int(len(x)*0.6), int(len(x)*0.8)])
Paling sering Anda akan menemukan diri Anda tidak membelahnya sekali tetapi pada langkah pertama Anda akan membagi data Anda dalam satu set pelatihan dan tes. Selanjutnya Anda akan melakukan pencarian parameter yang menggabungkan splitting yang lebih kompleks seperti validasi silang dengan algoritma 'split k-fold' atau 'leave-one-out (LOO)'.
Anda bisa menggunakan train_test_split
dua kali. Saya pikir ini yang paling mudah.
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)
Dengan cara ini, train
, val
, test
set akan 60%, 20%, 20% dari dataset masing-masing.
Jawaban terbaik di atas tidak menyebutkan bahwa dengan memisahkan dua kali menggunakan train_test_split
tidak mengubah ukuran partisi tidak akan memberikan partisi yang dimaksud:
x_train, x_remain = train_test_split(x, test_size=(val_size + test_size))
Kemudian bagian dari validasi dan set tes di x_remain berubah dan bisa dihitung sebagai
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)
Dalam kesempatan ini semua partisi awal disimpan.
Berikut pendekatan lain (mengasumsikan pembagian tiga arah yang sama):
# 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:]
Ini bisa dibuat lebih ringkas tetapi saya tetap menggunakannya untuk tujuan penjelasan.
Diberikan train_frac=0.8
, fungsi ini menciptakan pemisahan 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
Menambahkan ke jawaban @ hh32 , sambil menghormati proporsi yang telah ditentukan sebelumnya seperti (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)
Perpanjangan jawaban @ hh32 dengan rasio yang diawetkan.
# 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)
Karena dataset yang tersisa berkurang setelah pemisahan pertama, rasio baru sehubungan dengan dataset yang dikurangi harus dihitung dengan menyelesaikan persamaan: