Đào tạo / Kiểm tra / Xác thực bộ tách trong Sklearn


59

Làm cách nào tôi có thể chia ngẫu nhiên một ma trận dữ liệu và vectơ nhãn tương ứng thành X_train, X_test, X_val, y_train, y_test, y_val với Sklearn? Theo như tôi biết, sklearn.cross_validation.train_test_splitchỉ có khả năng chia làm hai chứ không phải trong ba ...

Câu trả lời:


81

Bạn chỉ có thể sử dụng sklearn.model_selection.train_test_splithai 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)

1
Vâng, điều này tất nhiên hoạt động nhưng tôi hy vọng cho một cái gì đó thanh lịch hơn;) Đừng bận tâm, tôi chấp nhận câu trả lời này.
Hendrik

1
Tôi muốn thêm rằng nếu bạn muốn sử dụng bộ xác thực để tìm kiếm các tham số siêu tốt nhất, bạn có thể thực hiện các thao tác sau sau khi chia: gist.github.com/albertotb/1bad123363b186267e3aeaa26610b54b
skd

12
Vì vậy, tỷ lệ đào tạo, kiểm tra, xác nhận cuối cùng trong ví dụ này là gì? Bởi vì vào lần thứ hai 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.
Monica Heddneck

1
Tôi đồng ý với @Monica Heddneck rằng 64% đào tạo, xác thực 16% và thử nghiệm 20% có thể rõ ràng hơn. Đó là một suy luận khó chịu mà bạn phải thực hiện với giải pháp này.
Perry

32

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.


2
Tôi có thể thấy .6ý nghĩa 60% ... nhưng nó .8có nghĩa là gì?
Tom Hale

1
@TomHale np.splitsẽ 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)])
0_0

3

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)'.


3

Bạn có thể sử dụng train_test_splithai 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, testbộ sẽ là 60%, 20%, 20% của các tập dữ liệu tương ứng.


2

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_splitkhô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.


1

Đâ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.


0

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

0

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)

0

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:

RremainingRnew=Rold

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.