Implementasi validasi silang bersarang

10

Saya mencoba mencari tahu apakah pemahaman saya tentang validasi silang bersarang benar, oleh karena itu saya menulis contoh mainan ini untuk melihat apakah saya benar:

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)

Pikiran apa pun dihargai.

abudis
sumber
3
Bisakah Anda juga memberikan versi pemahaman Anda tentang validasi silang dalam teks untuk mereka yang tidak membaca Python?
gung - Reinstate Monica

Jawaban:

14

UPS, kodenya salah, tetapi dengan cara yang sangat halus !

a) pemisahan set kereta menjadi set pelatihan dalam dan set tes OK.

b) masalahnya adalah dua baris terakhir, yang mencerminkan kesalahpahaman halus tentang tujuan validasi silang bersarang. Tujuan dari CV bersarang bukan untuk memilih parameter, tetapi untuk memiliki evaluasi yang tidak memihak tentang apa yang diharapkan dari algoritma Anda, dalam hal ini ensemble.ExtraTreesRegressordalam data ini dengan hyperparameter terbaik apa pun itu .

Dan inilah yang dihitung dengan benar oleh kode Anda hingga ke baris:

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

Itu menggunakan nested-CV untuk menghitung prediksi yang tidak bias dari classifier. Tetapi perhatikan bahwa setiap lintasan loop luar dapat menghasilkan hyperparameter terbaik yang berbeda, seperti yang Anda tahu ketika Anda menulis baris:

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

Jadi sekarang Anda memerlukan loop CV standar untuk memilih hyperparameter terbaik akhir, menggunakan lipatan:

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])

yang merupakan kode Anda tetapi dengan referensi ke bagian dalam dihapus.

Sekarang parameter terbaik adalah tuned_parameter[index], dan sekarang Anda dapat mempelajari classifier final clf3seperti pada kode Anda.

Jacques Wainer
sumber
Terima kasih! Saya memang mempertimbangkan bahwa saya dapat memilih bestparameter yang berbeda dalam lipatan yang berbeda, tetapi saya tidak tahu bagaimana memilih yang terbaik. stats.stackexchange.com/questions/65128/… - di sini, dalam jawaban disebutkan bahwa sebenarnya tidak diinginkan untuk memilih model terbaik dari model k luar. Mungkin saya masih salah paham tentang sesuatu, tetapi saya berpikir bahwa ide loop CV dalam adalah untuk memilih model yang berkinerja terbaik dan loop CV luar adalah untuk memperkirakan kinerja. Bisakah Anda memberikan kode yang dimodifikasi lengkap?
abudis
Oke, saya pikir saya mengerti. Saya ingin melihat kode yang dimodifikasi penuh, hanya untuk memastikan. Terima kasih.
abudis
1
Saya bingung mengenai jawaban Jacques Wainer dan saya pikir perlu diklarifikasi. Jadi, apakah Wainer menyarankan bahwa loop CV standar harus mengikuti kode yang diberikan oleh pertanyaan awal atau bahwa itu hanya harus mengganti kode bagian "dalam" awal? thanx
Lingkaran CV standar mengikuti loop CV bersarang
Jacques Wainer
2
Bagian pertama adalah untuk menghitung prediksi kesalahan yang tidak bias. Jika Anda menguji banyak algoritma yang berbeda, Anda harus melakukan hanya bagian 1, lalu pilih algoritma dengan kesalahan terendah, dan hanya untuk yang satu itu, lakukan 2 bagian untuk memilih hyperparameter. Jika Anda hanya menggunakan satu algoritme saja, maka bagian pertama kurang penting, kecuali jika Anda ingin membuat pernyataan bos atau klien Anda bahwa prediksi terbaik Anda tentang kesalahan pengelompokan di masa depan adalah x, dan Anda harus menghitung x menggunakan tanggal 1 bersarang CV.
Jacques Wainer
0

Untuk meringkas jawaban Jacques,

Diperlukan CV untuk estimasi kesalahan model yang tidak bias. Kita dapat membandingkan skor berbagai model dengan cara ini. Dengan menggunakan informasi ini, kita kemudian dapat melakukan loop K-fold CV terpisah untuk pencarian parameter dari model yang dipilih.

Sharan Naribole
sumber