Câu trả lời:
Bạn chỉ có thể sử dụng sklearn.model_selection.train_test_split
hai lần. Đầu tiên để phân chia để đào tạo, kiểm tra và sau đó phân chia lại đào tạo thành xác nhận và đào tạo. Một cái gì đó như thế này:
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
, bạn đang thực hiện việc này trong lần phân tách 80/20 trước đó. Vì vậy, val của bạn là 20% của 80%. Tỷ lệ phân chia không đơn giản theo cách này.
Có một câu trả lời tuyệt vời cho câu hỏi này về SO sử dụng numpy và gấu trúc.
Lệnh (xem câu trả lời cho cuộc thảo luận):
train, validate, test = np.split(df.sample(frac=1), [int(.6*len(df)), int(.8*len(df))])
tạo ra sự phân chia 60%, 20%, 20% cho các bộ huấn luyện, xác nhận và kiểm tra.
.6
ý nghĩa 60% ... nhưng nó .8
có nghĩa là gì?
np.split
sẽ phân chia ở mức 60% chiều dài của mảng được xáo trộn, sau đó là 80% chiều dài (là 20% dữ liệu bổ sung), do đó chỉ còn lại 20% dữ liệu. Điều này là do định nghĩa của chức năng. Bạn có thể kiểm tra / chơi với : x = np.arange(10.0)
, theo saunp.split(x, [ int(len(x)*0.6), int(len(x)*0.8)])
Thông thường bạn sẽ thấy mình không chia tách nó một lần nhưng trong bước đầu tiên, bạn sẽ phân chia dữ liệu của mình trong tập huấn luyện và kiểm tra. Sau đó, bạn sẽ thực hiện tìm kiếm tham số kết hợp các mối nối phức tạp hơn như xác thực chéo với thuật toán 'tách k-gấp' hoặc 'rời khỏi một lần (LOO)'.
Bạn có thể sử dụng train_test_split
hai lần. Tôi nghĩ rằng điều này là đơn giản nhất.
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)
Bằng cách này, train
, val
, test
bộ sẽ là 60%, 20%, 20% của các tập dữ liệu tương ứng.
Câu trả lời hay nhất ở trên không đề cập đến việc bằng cách tách hai lần bằng cách train_test_split
không thay đổi kích thước phân vùng sẽ không cung cấp phân vùng dự định ban đầu:
x_train, x_remain = train_test_split(x, test_size=(val_size + test_size))
Sau đó, phần xác thực và bộ kiểm tra trong thay đổi x_remain và có thể được tính là
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)
Trong dịp này, tất cả các phân vùng ban đầu được lưu.
Đây là một cách tiếp cận khác (giả sử chia ba chiều bằng nhau):
# 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:]
Điều này có thể được thực hiện ngắn gọn hơn nhưng tôi giữ nó dài dòng cho mục đích giải thích.
Cho trước train_frac=0.8
, chức năng này tạo ra sự phân chia 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
Thêm vào câu trả lời của @ hh32 , đồng thời tôn trọng mọi tỷ lệ được xác định trước, chẳng hạn như (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)
Gia hạn câu trả lời của @ hh32 với các tỷ lệ được bảo toàn.
# 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)
Vì tập dữ liệu còn lại bị giảm sau lần phân tách đầu tiên, nên các tỷ lệ mới liên quan đến tập dữ liệu giảm phải được tính bằng cách giải phương trình: