J'essaie de comprendre si ma compréhension de la validation croisée imbriquée est correcte, j'ai donc écrit cet exemple de jouet pour voir si j'ai raison:
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)
Toutes les pensées appréciées.
scikit-learn
propre version: scikit-learn.org/stable/auto_examples/model_selection/…Réponses:
UPS, le code est erroné, mais d'une manière très subtile !
a) la division du train en un ensemble d'entraînement intérieur et un ensemble de test est OK.
b) le problème est les deux dernières lignes, qui reflètent le malentendu subtil sur le but d'une validation croisée imbriquée. Le but d'un CV imbriqué n'est pas de sélectionner les paramètres, mais d'avoir une évaluation impartiale de la précision attendue de votre algorithme, dans ce cas
ensemble.ExtraTreesRegressor
dans ces données avec le meilleur hyperparamètre quel qu'il soit .Et c'est ce que votre code calcule correctement jusqu'à la ligne:
Il a utilisé le nested-CV pour calculer une prédiction non biaisée du classificateur. Mais notez que chaque passage de la boucle externe peut générer un meilleur hyperparamètre différent, comme vous le saviez lorsque vous avez écrit la ligne:
Alors maintenant, vous avez besoin d'une boucle CV standard pour sélectionner le meilleur hyperparamètre final, en utilisant des plis:
qui est votre code mais avec des références à l' intérieur supprimé.
Maintenant, le meilleur paramètre est
tuned_parameter[index]
, et maintenant vous pouvez apprendre le classificateur finalclf3
comme dans votre code.la source
best
paramètres dans différents plis, mais je ne savais pas comment choisir les meilleurs. stats.stackexchange.com/questions/65128/… - ici, dans la réponse, il est mentionné qu'il n'est en fait pas souhaitable de sélectionner le meilleur modèle parmi les modèles k externes. Peut-être que je ne comprends toujours pas quelque chose, mais je pensais que l'idée de la boucle de CV interne est de sélectionner le modèle le plus performant et la boucle de CV externe est d'estimer les performances. Pourriez-vous s'il vous plaît fournir le code modifié complet?Pour résumer la réponse de Jacques,
Un CV imbriqué est requis pour l'estimation d'erreur non biaisée d'un modèle. Nous pouvons comparer le score de différents modèles de cette manière. À l'aide de ces informations, nous pouvons ensuite effectuer une boucle CV séparée en K pour le réglage des paramètres des modèles sélectionnés.
la source