Estoy tratando de averiguar si mi comprensión de la validación cruzada anidada es correcta, por lo tanto, escribí este ejemplo de juguete para ver si tengo razón:
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)
Cualquier pensamiento apreciado.
cross-validation
python
scikit-learn
abudis
fuente
fuente
scikit-learn
versión propia: scikit-learn.org/stable/auto_examples/model_selection/…Respuestas:
UPS, el código está mal, ¡pero de una manera muy sutil !
a) la división del conjunto de trenes en un conjunto de entrenamiento interno y un conjunto de prueba está bien.
b) el problema son las dos últimas líneas, que reflejan el malentendido sutil sobre el propósito de una validación cruzada anidada. El propósito de un CV anidado no es seleccionar los parámetros, sino tener una evaluación imparcial de cuál es la precisión esperada de su algoritmo, en este caso
ensemble.ExtraTreesRegressor
en estos datos con el mejor hiperparámetro, sean los que sean .Y esto es lo que su código calcula correctamente hasta la línea:
Usó el CV anidado para calcular una predicción imparcial del clasificador. Pero tenga en cuenta que cada paso del bucle externo puede generar un mejor hiperparámetro diferente, como sabía cuando escribió la línea:
Así que ahora necesita un bucle CV estándar para seleccionar el mejor hiperparámetro final, usando pliegues:
cual es tu código pero con referencias a interno eliminado.
Ahora el mejor parámetro es
tuned_parameter[index]
, y ahora puedes aprender el clasificador finalclf3
como en tu código.fuente
best
parámetros en diferentes pliegues, pero no sabía cómo elegir los mejores. stats.stackexchange.com/questions/65128/… - aquí, en la respuesta, se menciona que en realidad no es deseable seleccionar el mejor modelo de los modelos k externos. Tal vez todavía estoy malinterpretando algo, pero pensé que la idea del bucle CV interno es seleccionar el modelo con mejor rendimiento y el bucle CV externo es estimar el rendimiento. ¿Podría proporcionar el código modificado completo?Para resumir la respuesta de Jacques,
Se requiere CV anidado para la estimación de error imparcial de un modelo. Podemos comparar la puntuación de diferentes modelos de esta manera. Con esta información, podemos realizar un bucle CV K-fold separado para el ajuste de parámetros de los modelos seleccionados.
fuente