Si entiendo correctamente, el CV anidado puede ayudarme a evaluar qué modelo y proceso de ajuste de hiperparámetro es mejor. El bucle interno ( GridSearchCV
) encuentra los mejores hiperparámetros, y el bucle externo ( cross_val_score
) evalúa el algoritmo de ajuste del hiperparámetro. Luego elijo qué combo de ajuste / modelo del bucle externo que minimiza mse
(estoy mirando el clasificador de regresión) para mi prueba de modelo final.
He leído las preguntas / respuestas sobre validación cruzada anidada, pero no he visto un ejemplo de una tubería completa que utilice esto. Entonces, ¿mi código a continuación (ignore los rangos reales de hiperparámetros, esto es solo por ejemplo) y el proceso de pensamiento tiene sentido?
from sklearn.cross_validation import cross_val_score, train_test_split
from sklearn.grid_search import GridSearchCV
from sklearn.metrics import mean_squared_error
from sklearn.ensemble import RandomForestRegressor
from sklearn.svm import SVR
from sklearn.datasets import make_regression
# create some regression data
X, y = make_regression(n_samples=1000, n_features=10)
params = [{'C':[0.01,0.05,0.1,1]},{'n_estimators':[10,100,1000]}]
# setup models, variables
mean_score = []
models = [SVR(), RandomForestRegressor()]
# split into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.3)
# estimate performance of hyperparameter tuning and model algorithm pipeline
for idx, model in enumerate(models):
clf = GridSearchCV(model, params[idx], scoring='mean_squared_error')
# this performs a nested CV in SKLearn
score = cross_val_score(clf, X_train, y_train, scoring='mean_squared_error')
# get the mean MSE across each fold
mean_score.append(np.mean(score))
print('Model:', model, 'MSE:', mean_score[-1])
# estimate generalization performance of the best model selection technique
best_idx = mean_score.index(max(mean_score)) # because SKLearn flips MSE signs, max works OK here
best_model = models[best_idx]
clf_final = GridSearchCV(best_model, params[best_idx])
clf_final.fit(X_train, y_train)
y_pred = clf_final.predict(X_test)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
print('Final Model': best_model, 'Final model RMSE:', rmse)
fuente
best_idx = np.where(np.mean(cv,1).min())[0]; final_m = GridSearchCV(models[best_idx], params[best_idx]); final_m.fit(X,y)
for model, param in zip(models, params): clf = GridSearchCV(model, param) my_score = cross_val_score(clf, X, y, scoring='mean_squared_error') my_scores.append(my_score)
La validación cruzada anidada estima el error de generalización de un modelo, por lo que es una buena manera de elegir el mejor modelo de una lista de modelos candidatos y sus cuadrículas de parámetros asociadas. La publicación original está cerca de hacer un CV anidado: en lugar de hacer una sola división de prueba de tren, uno debería usar un segundo divisor de validación cruzada. Es decir, uno "anida" un divisor de validación cruzada "interno" dentro de un divisor de validación cruzada "externo".
El divisor interno de validación cruzada se usa para elegir hiperparámetros. El divisor externo de validación cruzada promedia el error de prueba en múltiples divisiones de prueba de tren. Promediar el error de generalización en múltiples divisiones de tren-prueba proporciona una estimación más confiable de la precisión del modelo en datos no vistos.
Modifiqué el código de la publicación original para actualizarlo a la última versión de
sklearn
(consklearn.cross_validation
reemplazado porsklearn.model_selection
y con'mean_squared_error'
reemplazado por'neg_mean_squared_error'
), y utilicé dosKFold
divisores de validación cruzada para seleccionar el mejor modelo. Para obtener más información sobre la validación cruzada anidada, ver elsklearn
's ejemplo de anidado de validación cruzada .fuente
X
yy
). Hasta donde entiendo, esto es lo correcto, pero luego el comentario tiene que ser corregido. ¿Qué piensas?Usted no necesita
GridSearchCV
hace esto por ti Para tener una idea del proceso de búsqueda en la cuadrícula, intente usarGridSearchCV(... , verbose=3)
Para extraer puntuaciones para cada pliegue, vea este ejemplo en la documentación de scikit-learn
fuente