Como otimizar hiperparâmetros com GridSearchCV em Python
Um hiperparâmetro é uma definição que escolhemos antes de treinar o modelo — por exemplo, quantas árvores tem uma Random Forest. Escolher os melhores valores à mão é lento e pouco fiável: testamos um, mudamos outro e depressa perdemos o fio ao que já experimentámos. O GridSearchCV do scikit-learn automatiza esse trabalho: testa várias combinações com validação cruzada e indica qual delas dá o melhor resultado, tornando o modelo mais preciso com pouco esforço. A seguir fica um exemplo prático de tuning de hiperparâmetros em Python.
Pré-requisitos
- Python 3 com o
scikit-learne opandasinstalados (pip install scikit-learn pandas). - Saber treinar um modelo simples e dividir dados em treino e teste.
- Um notebook ou editor de código (Jupyter, VS Code ou equivalente).
Passo 1: Preparar os dados
Para não depender de ficheiros externos, usamos o dataset Wine que já vem incluído no scikit-learn — são 178 amostras de vinhos com 13 características e três classes. Carregamos os dados e reservamos 20% para teste; esse conjunto só será usado no fim, para uma avaliação honesta do modelo.
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
X, y = load_wine(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
Passo 2: Definir o modelo e a grelha
A grelha (grid) é um dicionário: cada chave é o nome de um hiperparâmetro e cada valor é a lista de opções a testar. O GridSearchCV vai experimentar todas as combinações possíveis. Aqui usamos uma Random Forest e variamos três definições importantes: o número de árvores (n_estimators), a profundidade máxima de cada árvore (max_depth) e o número mínimo de amostras necessário para dividir um nó (min_samples_split).
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(random_state=42)
param_grid = {
"n_estimators": [100, 200, 300],
"max_depth": [None, 5, 10],
"min_samples_split": [2, 5],
}
Dica: comece com uma grelha pequena. Estas três listas geram 18 combinações (3 × 3 × 2) e, com validação cruzada de 5 partes, resultam em 90 treinos. Quanto maior a grelha, mais tempo demora.
Passo 3: Executar a pesquisa com validação cruzada
Passamos o modelo e a grelha ao GridSearchCV. O parâmetro cv=5 divide os dados de treino em cinco partes e testa cada combinação em todas elas, dando uma estimativa muito mais fiável do que uma única divisão. Com scoring="accuracy" dizemos que a métrica a maximizar é a precisão, e n_jobs=-1 aproveita todos os núcleos do processador para acelerar a pesquisa.
from sklearn.model_selection import GridSearchCV
grid = GridSearchCV(
estimator=model,
param_grid=param_grid,
cv=5,
scoring="accuracy",
n_jobs=-1,
)
grid.fit(X_train, y_train)
Passo 4: Ver a melhor combinação
Terminado o treino, o GridSearchCV guarda a melhor combinação em best_params_ e a pontuação média de validação cruzada em best_score_. O melhor modelo, já reajustado com todos os dados de treino, fica disponível em best_estimator_ e pode ser usado diretamente para prever.
print("Best hyperparameters:", grid.best_params_)
print("Best CV score:", round(grid.best_score_, 3))
Passo 5: Avaliar no conjunto de teste
Por fim, medimos o desempenho do melhor modelo nos dados de teste que reservámos. É este valor — e não o da validação cruzada — que indica como o modelo se comporta perante dados que nunca viu.
accuracy = grid.score(X_test, y_test)
print("Test accuracy:", round(accuracy, 3))
Verificar o resultado
Se tudo correu bem, verá impressa a melhor combinação de hiperparâmetros e duas pontuações — a de validação cruzada e a de teste — ambas próximas e elevadas, normalmente acima de 0,9 neste dataset. Se a precisão no teste for muito inferior à da validação cruzada, pode ser sinal de overfitting: experimente reduzir a max_depth ou usar mais dados. Se ambas forem baixas, alargue a grelha com outros valores.
Conclusão
Com poucas linhas, deixou de adivinhar hiperparâmetros e passou a escolhê-los com base em dados. A partir daqui, use o RandomizedSearchCV quando a grelha for demasiado grande para testar por inteiro, ou combine o GridSearchCV com um Pipeline para afinar também o pré-processamento sem arriscar fugas de dados. Qual dos hiperparâmetros acha que fará a maior diferença no seu próximo modelo?