Sinto que esta questão está relacionada à teoria por trás da validação cruzada. Apresento aqui minha descoberta empírica e escrevi uma pergunta relacionada à teoria da validação cruzada lá .
Eu tenho dois modelos M1 e M2, uso o mesmo conjunto de dados para treiná-los e execute a validação cruzada usando o mesmo conjunto de dados para encontrar os parâmetros ideais para cada modelo. Digamos que, eventualmente, eu descobri que M1 sob seu parâmetro ideal, tem um desempenho melhor que M2 sob seu parâmetro ideal em termos de 10 vezes a pontuação de validação cruzada. Agora, se eu tiver outro conjunto de dados de teste independente com preditores e rótulos e esse conjunto de dados de teste for gerado a partir da mesma distribuição do meu conjunto de dados de treinamento, antes de aplicar esses dois modelos bem ajustados nesse novo conjunto de dados de teste, posso reivindicar ou devo esperar que o M1 ainda tenha um desempenho melhor que o M2 nesse novo conjunto de dados de teste?
Eu estava jogando o exemplo do Kaggle Titanic. Eu tenho 2 modelo xgboost, M1 está bem ajustado e M2 está menos bem ajustado, no sentido de que M1 tem uma melhor validação cruzada de 10 vezes, realizada no conjunto de dados de treinamento. Porém, quando enviei os dois, descobri que o modelo menos ajustado realmente tem melhores pontuações no conjunto de dados de teste. Como poderia ser? E se for verdade, o que devemos procurar quando ajustamos os dados em diferentes modelos e ajustamos os parâmetros do modelo?
Aqui estão meus resultados de envio específicos: fiz uma pesquisa em grade aleatória
params_fixed = {'silent': 1,'base_score': 0.5,'reg_lambda': 1,
'max_delta_step': 0,'scale_pos_weight':1,'nthread': 4,
'objective': 'binary:logistic'}
params_grid = {'max_depth': list(np.arange(1,10)),
'gamma': [0,0.05,0.1,0.3, 0.5,0.7,0.9],
'n_estimators':[1,2,5,7,10,15,19,25,30,50],
'learning_rate': [0.01,0.03,0.05,0.1,0.3,0.5,0.7,0.9,1],
'subsample': [0.5,0.7,0.9], 'colsample_bytree': [0.5,0.7,0.9],
'min_child_weight': [1,2,3,5], 'reg_alpha': [1e-5, 1e-2, 0.1, 0.5,1,10]
}
rs_grid = RandomizedSearchCV(
estimator=XGBClassifier(**params_fixed, seed=seed),
param_distributions=params_grid,
n_iter=5000,
cv=10,
scoring='accuracy',
random_state=seed
)
Cada vez que eu mudo a variável n_iter
. Primeiro, eu defino n_iter=10
, ele me fornece um conjunto de valores desses hiper parâmetros, vamos chamar esse vetore a pontuação cv (taxa de precisão) é 0,83389 , então eu usopara treinar meu modelo e gerar previsão no conjunto de dados de teste independente e, quando envio ao Kaggle, ele gera uma precisão verdadeira no conjunto de dados de teste 0.79426
Segundo, defino n_iter=100
, isso me dáe o escore cv é 0,83614 , ou seja, maior que o primeiro, faz sentido, mas quando me submeto a Kaggle, 0,78469 , menor que o primeiro.
Terceiro, defino n_iter = 1000
, isso me dáe a pontuação cv é 0,83951 , ou seja, maior que o segundo, faz sentido, mas quando me submeto ao Kaggle, 0,77990 , menor que o segundo.
Quarto, eu defino n_iter = 5000
, isso me dáe a pontuação cv é 0,84512 , ou seja, maior que o terceiro, faz sentido, mas quando me submeto a Kaggle, 0,72249 , menor que o terceiro.
Isso é realmente frustrado. O modelo está cada vez melhor na pontuação de validação cruzada, mas quando executado em um conjunto de dados independente real, seu desempenho está ficando cada vez pior. Interpretei as pontuações do CV da maneira exatamente oposta? Vejo algum artigo mencionado que a pontuação do CV pode ser otimista demais para inferir a verdadeira pontuação do teste. No entanto, mesmo que isso seja verdade, acho que as pontuações de CV para todos os meus quatro modelos devem ser otimistas quanto à sua própria pontuação de teste, ou seja, a ordem deve preservar. Mas, ao aplicar no conjunto de dados de teste real, a ordem foi revertida.
A única razão pela qual posso imaginar seria que o conjunto de dados de teste tem uma distribuição diferente do conjunto de dados de treinamento. No entanto, se for esse o caso, acredito que não exista um método sob o sol que possa curar esse problema.