중첩 교차 검증의 구현


10

중첩 교차 유효성 검사에 대한 이해가 올바른지 알아 내려고 노력하고 있으므로이 장난감 예제를 작성하여 내가 옳은지 확인했습니다.

import operator
import numpy as np
from sklearn import cross_validation
from sklearn import ensemble
from sklearn.datasets import load_boston

# set random state
state = 1

# load boston dataset
boston = load_boston()

X = boston.data
y = boston.target

outer_scores = []

# outer cross-validation
outer = cross_validation.KFold(len(y), n_folds=3, shuffle=True, random_state=state)
for fold, (train_index_outer, test_index_outer) in enumerate(outer):
    X_train_outer, X_test_outer = X[train_index_outer], X[test_index_outer]
    y_train_outer, y_test_outer = y[train_index_outer], y[test_index_outer]

    inner_mean_scores = []

    # define explored parameter space.
    # procedure below should be equal to GridSearchCV
    tuned_parameter = [1000, 1100, 1200]
    for param in tuned_parameter:

        inner_scores = []

        # inner cross-validation
        inner = cross_validation.KFold(len(X_train_outer), n_folds=3, shuffle=True, random_state=state)
        for train_index_inner, test_index_inner in inner:
            # split the training data of outer CV
            X_train_inner, X_test_inner = X_train_outer[train_index_inner], X_train_outer[test_index_inner]
            y_train_inner, y_test_inner = y_train_outer[train_index_inner], y_train_outer[test_index_inner]

            # fit extremely randomized trees regressor to training data of inner CV
            clf = ensemble.ExtraTreesRegressor(param, n_jobs=-1, random_state=1)
            clf.fit(X_train_inner, y_train_inner)
            inner_scores.append(clf.score(X_test_inner, y_test_inner))

        # calculate mean score for inner folds
        inner_mean_scores.append(np.mean(inner_scores))

    # get maximum score index
    index, value = max(enumerate(inner_mean_scores), key=operator.itemgetter(1))

    print 'Best parameter of %i fold: %i' % (fold + 1, tuned_parameter[index])

    # fit the selected model to the training set of outer CV
    # for prediction error estimation
    clf2 = ensemble.ExtraTreesRegressor(tuned_parameter[index], n_jobs=-1, random_state=1)
    clf2.fit(X_train_outer, y_train_outer)
    outer_scores.append(clf2.score(X_test_outer, y_test_outer))

# show the prediction error estimate produced by nested CV
print 'Unbiased prediction error: %.4f' % (np.mean(outer_scores))

# finally, fit the selected model to the whole dataset
clf3 = ensemble.ExtraTreesRegressor(tuned_parameter[index], n_jobs=-1, random_state=1)
clf3.fit(X, y)

모든 의견에 감사드립니다.


3
파이썬을 읽지 않는 사람들을 위해 텍스트의 교차 검증에 대한 이해의 버전을 제공 할 수 있습니까?
gung-복직 모니카

답변:


14

UPS, 코드가 잘못되었지만 매우 미묘 합니다!

a) 열차 세트를 내부 트레이닝 세트와 테스트 세트로 분할해도됩니다.

b) 문제는 마지막 두 줄로 중첩 교차 검증 의 목적 에 대한 미묘한 오해를 반영한다 . 중첩 된 CV의 목적은 하지 파라미터를 선택하지만,이 경우, 알고리즘의 예상 정확도 무엇의 공정한 평가하도록 ensemble.ExtraTreesRegressor최선 hyperparameter이 데이터 가있을 수 있습니다 무엇을 .

그리고 이것은 코드가 라인까지 올바르게 계산하는 것입니다.

    print 'Unbiased prediction error: %.4f' % (np.mean(outer_scores))

중첩 된 CV를 사용하여 분류 자의 편견없는 예측을 계산했습니다. 그러나 외부 루프의 각 패스는 라인을 작성할 때 알고 있듯이 다른 최고 하이퍼 파라미터를 생성 할 수 있습니다.

   print 'Best parameter of %i fold: %i' % (fold + 1, tuned_parameter[index])

이제 접기를 사용하여 최종 최고 하이퍼 파라미터 를 선택하려면 표준 CV 루프가 필요합니다 .

tuned_parameter = [1000, 1100, 1200]
for param in tuned_parameter:

    scores = []

    # normal cross-validation
    kfolds = cross_validation.KFold(len(y), n_folds=3, shuffle=True, random_state=state)
    for train_index, test_index in kfolds:
        # split the training data
        X_train, X_test = X[train_index], X[test_index]
        y_train, y_test = y[train_index], y[test_index]

        # fit extremely randomized trees regressor to training data
        clf2_5 = ensemble.ExtraTreesRegressor(param, n_jobs=-1, random_state=1)
        clf2_5.fit(X_train, y_train)
        scores.append(clf2_5.score(X_test, y_test))

    # calculate mean score for folds
    mean_scores.append(np.mean(scores))

# get maximum score index
index, value = max(enumerate(mean_scores), key=operator.itemgetter(1))

print 'Best parameter : %i' % (tuned_parameter[index])

이것은 코드이지만 inner에 대한 참조가 제거되었습니다.

이제 가장 좋은 매개 변수는입니다 tuned_parameter[index]. 이제 clf3코드에서와 같이 최종 분류자를 배울 수 있습니다.


감사! 나는 best다른 접기에서 다른 매개 변수를 선택할 수 있다고 생각 했지만 가장 좋은 것을 선택하는 방법을 몰랐습니다. stats.stackexchange.com/questions/65128/…- 여기서 대답은 외부 k 모델 중에서 가장 좋은 모델을 선택하는 것이 바람직하지 않다는 것입니다. 어쩌면 나는 여전히 무언가를 오해하고 있지만 내부 CV 루프의 아이디어는 최고의 성능 모델을 선택하고 외부 CV 루프는 성능을 추정하는 것이라고 생각했습니다. 전체 수정 된 코드를 제공해 주시겠습니까?
abudis 2019

알았어요 그래도 전체 수정 된 코드를보고 싶습니다. 감사.
abudis

1
나는 Jacques Wainer의 대답에 대해 혼란스러워하고 그것을 명확히 할 가치가 있다고 생각합니다. Wainer는 표준 CV 루프가 초기 질문에서 제공 한 코드를 따라야하는지 또는 초기 "내부"부품 코드를 대체해야한다고 제안합니까? 고맙습니다

표준 CV 루프는 중첩 된 CV 루프를 따릅니다
Jacques Wainer

2
첫 번째 부분은 오차의 편견 예측을 계산하는 것입니다. 여러 가지 다른 알고리즘을 테스트하는 경우 첫 번째 부분 만 수행 한 다음 오류가 가장 적은 알고리즘을 선택하고 해당 알고리즘에 대해서만 두 부분을 수행하여 하이퍼 파라미터를 선택해야합니다. 알고리즘을 하나만 사용하도록 설정 한 경우, 분류 자의 미래 오류에 대한 최선의 예측이 x이고 1을 사용하여 x를 계산해야한다고 상사 나 고객에게 말하지 않는 한 첫 번째 부분은 덜 중요합니다. 중첩 CV.
Jacques Wainer

0

Jacques의 답변을 요약하면

모델의 바이어스되지 않은 오차 추정에는 중첩 CV가 필요합니다. 이 방식으로 다른 모델의 점수를 비교할 수 있습니다. 이 정보를 사용하여 선택한 모델의 파라미터 튜닝을 위해 별도의 K- 폴드 CV 루프를 수행 할 수 있습니다.

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