Sklearn에서 Train / Test / Validation Set Splitting


59

Sklearn을 사용하여 데이터 행렬과 해당 레이블 벡터를 어떻게 X_train, X_test, X_val, y_train, y_test, y_val로 무작위로 나눌 수 있습니까? 내가 아는 한, sklearn.cross_validation.train_test_split세 개가 아닌 두 개로 만 나눌 수 있습니다 ...

답변:


81

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)

1
그렇습니다. 물론 작동하지만 더 우아한 것을 원했습니다.) 걱정하지 마십시오.이 대답을 받아들입니다.
Hendrik

1
: 난 당신이 최고의 하이퍼 매개 변수를 검색 할 검증 세트를 사용하려는 경우에는 분할 후 다음을 수행 할 수있는 추가하고 싶었 gist.github.com/albertotb/1bad123363b186267e3aeaa26610b54b
SKD

12
이 예제에서 최종 기차, 테스트, 검증 비율은 무엇입니까? 두 번째 train_test_split 에서는 이전 80/20 분할에 대해이 작업을 수행하고 있기 때문입니다 . 따라서 귀하의 발은 80 %의 20 %입니다. 분할 비율은 이러한 방식으로 매우 간단하지 않습니다.
Monica Heddneck 2016 년

1
@Monica Heddneck에 동의하면 64 % 기차, 16 % 유효성 검사 및 20 % 테스트 스플릿이 더 명확 할 수 있습니다. 이 솔루션으로 수행해야하는 성가신 추론입니다.
페리

32

numpy와 pandas를 사용 하는 SO에 대해서는 이 질문에 대한 훌륭한 답변이 있습니다.

명령 (토론에 대한 답변 참조) :

train, validate, test = np.split(df.sample(frac=1), [int(.6*len(df)), int(.8*len(df))])

교육, 검증 및 테스트 세트를 위해 60 %, 20 %, 20 % 분할을 생성합니다.


2
.660 % 의 의미 를 볼 수 있지만 그 .8의미는 무엇입니까?
Tom Hale

1
@TomHale np.split은 셔플 배열 길이의 60 %에서 분할 된 다음 길이의 80 % (데이터의 추가 20 %)로 분할되므로 나머지 20 %의 데이터가 남습니다. 이것은 기능의 정의 때문입니다. x = np.arange(10.0)다음을 사용하여 테스트 / 재생할 수 있습니다. 다음에np.split(x, [ int(len(x)*0.6), int(len(x)*0.8)])
0_0

3

대부분 자신이 한 번만 분할하지는 않지만 첫 번째 단계에서는 훈련 및 테스트 세트에서 데이터를 분할합니다. 그런 다음 'split k-fold'또는 'leave-one-out (LOO)'알고리즘을 사용한 교차 검증과 같은보다 복잡한 분할을 통합하는 매개 변수 검색을 수행합니다.


3

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 %가 될 것이다.


2

위의 가장 좋은 대답은 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)

이 경우 모든 초기 파티션이 저장됩니다.


1

다음은 또 다른 접근법입니다 (동일한 3 방향 분할이라고 가정).

# 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:]

이것은 더 간결하게 만들 수 있지만 설명을 위해 자세하게 설명했습니다.


0

주어진 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

0

(75, 15, 10)과 같은 사전 정의 된 비율을 고려하면서 @ hh32의 답변에 추가 :

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

보존 된 비율 로 @ 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)

첫 번째 분할 후 나머지 데이터 세트가 줄어들 기 때문에 다음 데이터를 풀면 축소 된 데이터 세트에 대한 새로운 비율을 계산해야합니다.

RremainingRnew=Rold

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.