Curso
No vasto campo de Machine Learning, encontrar os melhores hiperparâmetros durante o treinamento de modelos — em meio a conjuntos de dados grandes e complexos — é um desafio frequente.
Métodos convencionais, como random search e grid search, podem ser demorados e ineficientes, especialmente quando lidamos com arquiteturas de modelos complexas ou dados em larga escala.
É aí que surge a necessidade de uma abordagem mais inteligente e adaptativa: a otimização bayesiana, cada vez mais essencial para o ajuste de hiperparâmetros.
O primeiro objetivo deste artigo é explicar o que é otimização bayesiana, oferecendo uma base teórica sólida. Porém, antes de mergulhar no conceito, vale entender os diferentes métodos de otimização de hiperparâmetros à nossa disposição.
A segunda parte do artigo traz uma implementação prática dos conceitos-chave usando a linguagem Python. Na última seção, você vai aprender a usar a otimização bayesiana para o ajuste fino dos hiperparâmetros de um modelo de machine learning.
O que é otimização bayesiana?
Antes de definir otimização bayesiana, vamos ver um panorama dos quatro principais métodos de otimização de hiperparâmetros com exemplos simples:
- Busca manual
- Random search
- Grid search, e
- Otimização bayesiana.
Busca manual
É o método mais básico, baseado em experiência, intuição ou tentativa e erro. Costuma ser demorado e depende muito da expertise de quem executa.
Por exemplo, um confeiteiro experiente define a temperatura do forno e o tempo de assar com base na experiência e na intuição.
Um ponto de partida típico pode ser 350°F por 30 minutos, refletindo configurações que geralmente funcionam bem. Os ajustes são feitos conforme o resultado de cada fornada.
Random search
Essa abordagem escolhe aleatoriamente combinações de temperatura e tempo dentro de um intervalo definido. Por exemplo, temperaturas entre 325°F e 375°F e tempos entre 25 e 35 minutos.
A seleção pode começar com 330°F por 27 minutos, depois 370°F por 31 minutos, e assim por diante, até identificar a combinação mais eficaz.
Grid search
Aqui, exploramos sistematicamente várias combinações de valores de hiperparâmetros.
Seguindo o exemplo do bolo, o confeiteiro cria uma grade estruturada de combinações de temperatura e tempo.
A grade pode incluir incrementos de 5°F entre 325°F e 375°F e de 2 minutos entre 25 e 35 minutos. O bolo seria assado em cada combinação (325°F por 25 minutos, 325°F por 27 minutos, ... , 375°F por 35 minutos) para encontrar a melhor.
Busca bayesiana
A otimização bayesiana é uma forma mais inteligente de encontrar a melhor temperatura e o melhor tempo para assar um bolo, em comparação ao random search.
No random search, o confeiteiro testaria várias combinações de forma aleatória, muitas delas resultando em bolos crus ou passados.
Na otimização bayesiana, a busca pelas condições ideais é guiada e informada pelos resultados anteriores.
Por exemplo, se o confeiteiro percebe que bolos assados perto de 350°F por 30 minutos tendem a dar certo, ele passa a focar mais em combinações próximas a esses valores nas próximas tentativas.
Esse método reduz o número de testes porque ele “aprende” quais combinações têm mais chance de gerar o bolo perfeito com base nos resultados anteriores.
Em resumo, a otimização bayesiana se baseia no teorema de Bayes para otimizar funções-objetivo caras de avaliar. É especialmente eficaz quando amostrar é custoso e a função objetivo é desconhecida, mas pode ser amostrada.
Normalmente, usa-se um modelo probabilístico, como um processo gaussiano, para estimar a função objetivo e, depois, uma função de aquisição para decidir onde amostrar em seguida.
Desafios da otimização bayesiana
Essa abordagem já foi aplicada com sucesso em vários domínios. Ainda assim, apresenta alguns desafios importantes, listados a seguir:
Avaliação em lote / paralela
Um desafio é conduzir avaliações em lote ou em paralelo de forma eficiente. Tradicionalmente, a otimização bayesiana opera de modo sequencial, escolhendo um ponto por vez para avaliar. Estender isso para avaliar vários pontos simultaneamente não é trivial e exige equilibrar diversidade e eficiência nos pontos escolhidos.
Otimização não míope
Refere-se ao desafio de tomar decisões estratégicas de longo prazo sobre quais pontos avaliar. Métodos não míopes consideram o impacto futuro das avaliações atuais, o que pode ser computacionalmente caro e complexo de modelar.
Dimensionalidade do espaço
À medida que a dimensionalidade do espaço de busca aumenta, a otimização bayesiana tende a perder eficácia, por causa da “maldição da dimensionalidade”: o volume do espaço cresce exponencialmente, dificultando encontrar ótimos com poucas avaliações.
Espaço de busca estruturado
Em muitos problemas reais, o espaço de busca não é um espaço n-dimensional contínuo simples, mas possui estrutura complexa, como dependências entre variáveis ou restrições. Tratar bem esses espaços estruturados é um grande desafio.
Busca multi-tarefa/objetivo e multi-fidelidade
Estender a otimização bayesiana para lidar com múltiplos objetivos simultaneamente ou integrar informações de avaliações com diferentes níveis de fidelidade (precisão) é complexo. Esses cenários exigem equilibrar trade-offs entre objetivos distintos ou níveis de detalhe nas avaliações.
Warm-start
Envolve usar conhecimento ou dados prévios para acelerar a otimização. Incorporar essas informações ao arcabouço bayesiano sem enviesar os resultados é desafiador.
Grande número de avaliações
Embora a otimização bayesiana seja pensada para cenários em que avaliar é caro, em alguns casos ainda pode ser necessário um grande número de avaliações. Gerenciar e navegar eficientemente por esse volume pode ser desafiador em termos de recursos computacionais e tempo.
Funções-objetivo “difíceis”
Lidar com funções-objetivo com muitos ótimos locais, descontinuidades ou não estacionárias (quando a função muda ao longo do tempo) é complicado. Essas características podem “enganar” o processo de otimização e dificultar a busca do ótimo global.
Observação indireta
Em alguns cenários, a função-objetivo não pode ser observada diretamente, apenas por medições indiretas. Isso adiciona complexidade, pois o algoritmo precisa inferir a função real a partir dessas observações.
Funções de aquisição e tomada de decisão
Na otimização bayesiana, as funções de aquisição guiam a busca pelos valores ótimos.
Funções de aquisição e modelos substitutos (surrogates) são interdependentes na otimização bayesiana.
O modelo substituto fornece uma previsão probabilística da função-objetivo, que a função de aquisição usa para determinar os pontos mais promissores a avaliar. Modelos como Gaussian Process Regression são especialmente úteis quando a função-objetivo é complexa ou cara de avaliar diretamente.
Além disso, ao atualizar continuamente o modelo substituto com novos pontos, a função de aquisição é direcionada com mais precisão para regiões do espaço de busca com maior chance de bons resultados.
Algumas funções de aquisição comuns na otimização bayesiana incluem:
- Thompson Sampling: seleciona pontos com base em uma estimativa probabilística da função-objetivo.
- Upper Confidence Bound (UCB): seleciona o ponto com maior probabilidade de melhorar o melhor valor observado. Usa a diferença entre o possível novo resultado e o atual melhor, calculando a probabilidade de melhora.
- Probability of Improvement (PI): escolhe o ponto com maior probabilidade de superar o melhor valor observado até agora.
- Expected Improvement (EI): seleciona o ponto com maior melhora esperada em relação ao melhor valor observado.
Não existe “a melhor” função. Cada função de aquisição tem seus pontos fortes e é escolhida conforme as necessidades específicas do problema de otimização.
Aplicações da otimização bayesiana
A otimização bayesiana já foi aplicada com sucesso em muitos setores. Abaixo, destacamos quatro casos de uso:
- Processamento de linguagem natural
- Machine Learning e ajuste de hiperparâmetros
- Testes A/B, e
- Reforço/aprendizado por reforço e robótica
Esses exemplos são especialmente relevantes e úteis para Data Scientists.
Processamento de linguagem natural
Ao aplicar Machine Learning a problemas de processamento de linguagem natural (PLN), há várias decisões sobre como representar os textos de entrada — e essas escolhas impactam o resultado do modelo.
A otimização bayesiana é usada para automatizar a escolha da melhor forma de representar texto em modelos de PLN, simplificando o desenvolvimento, ganhando eficiência e mantendo — ou até melhorando — a performance dos modelos.
Para saber mais sobre embeddings, nosso curso Introduction to Embeddings with OpenAI API traz um guia completo de como usar a API da OpenAI para criar embeddings.
Machine Learning e ajuste de hiperparâmetros
Na automação de machine learning (AutoML), a otimização bayesiana automatiza a seleção do melhor modelo e de seus hiperparâmetros para um determinado problema e dataset.
Aplicações recentes mostram sua eficácia no ajuste de modelos complexos, como deep belief networks, redes neurais convolucionais e métodos de Markov Chain Monte Carlo.
Além disso, tem sido útil para automatizar a escolha entre modelos oferecidos por bibliotecas populares como WEKA e scikit-learn.
Testes A/B
Em testes A/B, a otimização bayesiana aumenta a eficiência ao comparar diferentes configurações de produto — como anúncios, apps, jogos ou sites.
Ao apresentar duas opções (A e B) para um subconjunto de usuários, as equipes coletam feedback para otimizar métricas como engajamento ou taxa de cliques. O grande desafio é encontrar a melhor configuração dentro de um orçamento limitado de experimentação.
A otimização bayesiana facilita esse processo usando o feedback de testes anteriores para decidir quais subconjuntos consultar em seguida, buscando otimizar a performance geral do produto enquanto minimiza custos de oportunidade.
Aprendizado por reforço e robótica
A otimização bayesiana tem sido aplicada com sucesso em robótica e aprendizado por reforço.
Em robótica, foi usada para otimizar a marcha de um robô para objetivos como velocidade ou suavidade, como demonstrado com o Sony AIBO ERS-7. Também foi empregada em tarefas de navegação, ajudando robôs a reduzir a incerteza sobre sua posição e sobre mapas enquanto se movem.
No aprendizado por reforço hierárquico, já foi aplicada para ajustar automaticamente parâmetros de políticas de redes neurais e aprender funções de valor em diferentes níveis de um sistema hierárquico.
Além disso, a técnica foi usada para desenvolver políticas de atenção em rastreamento de imagens com redes profundas, mostrando sua versatilidade em diferentes aspectos de aprendizado e tomada de decisão em ambientes complexos.
Guia passo a passo para implementar otimização bayesiana
As seções anteriores apresentaram uma visão completa da otimização bayesiana. Agora, vamos otimizar os hiperparâmetros de um XGBRegressor usando a biblioteca GPyOpt.
PyMC3 é outra biblioteca poderosa para otimização bayesiana; nosso curso Bayesian Data Analysis in Python oferece um guia completo com exemplos do mundo real.
Se você prefere aplicar otimização bayesiana em R, o curso Fundamentals of Bayesian Data Analysis in R é a escolha certa.
Vamos aplicar dois métodos: grid search e otimização bayesiana. O objetivo é identificar qual fornece os melhores hiperparâmetros e, consequentemente, um modelo superior. O código completo está neste workbook do DataLab; você pode criar uma cópia para editar e rodar no navegador sem instalar nada no seu computador.
Pré-requisitos
As seguintes bibliotecas são necessárias para executar ambas as técnicas:
- numpy: biblioteca para computação numérica em Python.
- scipy: biblioteca para computação científica em Python.
- sklearn: biblioteca de machine learning em Python.
- GPyOpt: biblioteca de otimização bayesiana em Python.
- Xgboost: para o modelo XGBoost
Você pode instalar essas bibliotecas com pip a partir do Jupyter Notebook:
!pip -q install xgboost scikit-learn GPyOpt numpy
Após a instalação, faça os imports com o comando import:
import xgboost as xgb
from sklearn.datasets import fetch_california_housing as fch
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import RandomizedSearchCV
from GPyOpt.methods import BayesianOptimization
from sklearn.model_selection import cross_val_score
import numpy as np
Preparação do dataset
A análise de benchmark usa o dataset California housing.
- 70% dos dados são usados para treinar o modelo XGBoost
- Os 30% restantes são usados para teste
A divisão entre treino e teste é feita assim:
# Load dataset
california_housing = fch()
X = california_housing.data
y = california_housing.target
# Split the dataset into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.3,
random_state=2024)
Depois de carregar os dados de treino e teste, verifique os tamanhos com .shape:
print(f"Training Shape: {X_train.shape}")
print(f"Testing Shape: {X_test.shape}")
Ajuste de hiperparâmetros com random search
Esta seção mostra como configurar e executar o ajuste de hiperparâmetros com a abordagem de Gridsearch para uma regressão XGBoost usando a classe RandomizedSearchCV do scikit-learn.
Definir a grade de parâmetros
Criamos um dicionário chamado param_dist com diferentes hiperparâmetros como chaves e listas de valores possíveis como valores. Os hiperparâmetros incluem:
- max_depth: profundidade máxima da árvore. Valores: 3, 10, 5, 15.
- min_child_weight: soma mínima de peso (hessiana) necessária em um nó filho. Valores: 1, 5, 10.
- subsample: fração de amostras de treino usada. Valores: 0.5, 0.7, 1.0.
- colsample_bytree: fração de colunas amostradas ao construir cada árvore. Valores: 0.5, 0.7, 1.0.
- n_estimators: número de árvores (rodadas de boosting). Valores: 100, 200, 300, 400.
param_dist = {
'max_depth': [3, 10, 5, 15],
'min_child_weight': [1, 5, 10],
'subsample': [0.5, 0.7, 1.0],
'colsample_bytree': [0.5, 0.7, 1.0],
'n_estimators': [100, 200, 300, 400],
'learning_rate': [0.01, 0.05, 0.1, 0.15, 0.2]
}
Inicializar o XGBoost Regressor
Criamos uma instância da classe XGBRegressor da biblioteca XGBoost:
xgb_reg = xgb.XGBRegressor()
Configurar o RandomizedSearchCV
O RandomizedSearchCV é configurado com os seguintes parâmetros:
- O estimator (xgb_reg) é o regressor XGBoost.
- param_distributions=param_dist define o dicionário de parâmetros a serem amostrados.
- n_iter=25 indica que 25 combinações diferentes serão testadas.
- scoring='neg_mean_squared_error' define o métrico como erro quadrático médio negativo.
- cv=3 define 3 folds na validação cruzada.
- verbose=1 habilita saída detalhada.
- random_state=2024 garante reprodutibilidade.
random_search = RandomizedSearchCV(
xgb_reg, param_distributions=param_dist, n_iter=25,
scoring='neg_mean_squared_error', cv=3, verbose=1, random_state=2024
)
Treinar o modelo e acessar os parâmetros
O método fit executa a busca aleatória nos dados de treino (X_train e y_train):
random_search.fit(X_train, y_train)
O atributo best_params_ do modelo ajustado contém os melhores hiperparâmetros que levaram ao melhor desempenho.
Você pode obtê-los assim:
print("Random Search Best Parameters:", random_search.best_params_)

Melhores parâmetros via random search
Entre todas as opções, os melhores parâmetros para o XGBoost usando random search foram:
'subsample': 0.5,
'n_estimators': 400,
'min_child_weight': 5,
'max_depth': 10,
'learning_rate': 0.05,
'colsample_bytree': 1.0
}
Avaliar o modelo
Com esses valores, avaliamos o modelo e verificamos sua performance:
Primeiro, inicializamos o modelo com os melhores hiperparâmetros e treinamos.
# Initialize and train the model
model_random_search = xgb.XGBRegressor(**params_random_search)
model_random_search.fit(X_train, y_train)
Depois, avaliamos o modelo nos dados de teste:
predictions_random_search = model_random_search.predict(X_test)
mse_random_search = mean_squared_error(y_test, predictions_random_search)
print("MSE for Random Search: ", mse_random_search)
A execução gera o seguinte valor de erro quadrático médio:

MSE do XGBoost usando hiperparâmetros do random search
Ajuste de hiperparâmetros com otimização bayesiana
Seguindo uma lógica similar ao random search, vamos gerar os melhores hiperparâmetros usando otimização bayesiana, passo a passo.
Definir os limites dos parâmetros
Os limites dos hiperparâmetros são definidos na lista baysian_opt_bounds. Cada hiperparâmetro é um dicionário com as chaves: name, type e domain.
- max_depth, min_child_weight, n_estimators são variáveis discretas.
- subsample, colsample_bytree, learning_rate são variáveis contínuas.
- O domain especifica o intervalo de valores de cada hiperparâmetro.
baysian_opt_bounds = [
{'name': 'max_depth', 'type': 'discrete', 'domain': (3, 10, 5, 15)},
{'name': 'min_child_weight', 'type': 'discrete', 'domain': (1, 5, 10)},
{'name': 'subsample', 'type': 'continuous', 'domain': (0.5, 1.0)},
{'name': 'colsample_bytree', 'type': 'continuous', 'domain': (0.5, 1.0)},
{'name': 'n_estimators', 'type': 'discrete', 'domain': (100, 200, 300, 400)},
{'name': 'learning_rate', 'type': 'continuous', 'domain': (0.01, 0.2)}
]
Definir a função objetivo
Definimos a função objetivo xgb_cv_score para calcular o erro quadrático médio negativo com validação cruzada de um modelo XGBoost.
- A função recebe um conjunto de parâmetros e os converte para o formato esperado.
- cross_val_score avalia o XGBoost com os parâmetros informados.
- A média negativa dos scores na validação cruzada é retornada como objetivo a minimizar.
def xgb_cv_score(parameters):
parameters = parameters[0]
score = -cross_val_score(
xgb.XGBRegressor(
max_depth=int(parameters[0]),
min_child_weight=int(parameters[1]),
subsample=parameters[2],
colsample_bytree=parameters[3],
n_estimators=int(parameters[4]),
learning_rate=parameters[5]),
X_train, y_train, scoring='neg_mean_squared_error', cv=3).mean()
return score
Inicializar e executar o modelo bayesiano
Instanciamos a otimização bayesiana com os seguintes parâmetros:
- f=xgb_cv_score: função objetivo a minimizar.
- domain=baysian_opt_bounds: limites dos hiperparâmetros.
- model_type='GP': usa processos gaussianos.
- acquisition_type='EI': usa Expected Improvement como função de aquisição.
- max_iter=25: número de iterações do processo de otimização.
O processo começa com optimizer.run_optimization()
optimizer = BayesianOptimization(
f=xgb_cv_score, domain=baysian_opt_bounds, model_type='GP',
acquisition_type='EI', max_iter=25
)
optimizer.run_optimization()
Acessar os melhores parâmetros
Após a otimização, extraímos e formatamos os melhores parâmetros:
- Os parâmetros são obtidos de optimizer.x_opt.
- Parâmetros discretos (max_depth, min_child_weight, n_estimators) são convertidos para inteiros.
Em seguida, imprimimos os melhores parâmetros:
print("Bayesian Optimization Best Parameters:", best_params_bayesian)

Melhores parâmetros via otimização bayesiana
Avaliar o modelo
A inicialização e o ajuste seguem o mesmo processo de antes, agora usando os parâmetros da otimização bayesiana:
params_bayesian_opt = {
'max_depth': 10,
'min_child_weight': 10,
'subsample': 0.820222997732141,
'colsample_bytree': 0.6710357796023916,
'n_estimators': 300,
'learning_rate': 0.04797554348030097
}
# Initialize and train the model
model_bayesian_opt = xgb.XGBRegressor(**params_bayesian_opt)
model_bayesian_opt.fit(X_train, y_train)
# Make predictions and evaluate
predictions_bayesian_opt = model_bayesian_opt.predict(X_test)
mse_bayesian_opt = mean_squared_error(y_test, predictions_bayesian_opt)
print("MSE for Bayesian Optimization: ", mse_bayesian_opt)
Após a execução, obtemos a performance do modelo, conforme abaixo:

MSE do XGBoost usando hiperparâmetros da otimização bayesiana
Interpretação dos resultados
A partir dos dois experimentos, observamos que:
- MSE menor com otimização bayesiana: o modelo treinado com hiperparâmetros da otimização bayesiana obteve MSE menor (0,204) do que o do random search (0,219). Esse valor mais baixo indica que o modelo, em média, fica mais próximo dos valores verdadeiros.
- Desempenho do modelo: o MSE menor mostra que a otimização bayesiana foi mais eficaz para ajustar os hiperparâmetros do XGBoost. Isso sugere melhor capacidade de generalização para dados não vistos (o conjunto de teste).
- Eficiência da otimização bayesiana: no geral, a abordagem tende a gerar melhores resultados no ajuste de hiperparâmetros porque usa um modelo probabilístico para guiar a busca, aprendendo com avaliações anteriores e direcionando o processo para regiões mais promissoras.
Neste caso específico, a otimização bayesiana entregou melhores resultados, evidenciados pelo MSE menor. Para esse dataset e modelo (XGBoost), ela foi mais eficaz em identificar o conjunto de hiperparâmetros que minimizou o erro de previsão no teste.
Vale lembrar que, embora aqui a otimização bayesiana tenha se saído melhor, a escolha entre random search e otimização bayesiana depende de fatores como complexidade do modelo, natureza dos dados e recursos computacionais.
Em cenários em que a precisão do ajuste de hiperparâmetros é crucial e os recursos permitem, a otimização bayesiana costuma ser a melhor escolha.
Conclusão
Este artigo apresentou uma exploração completa da otimização bayesiana, técnica-chave para otimizar funções complexas.
Começamos definindo o que é otimização bayesiana e, em seguida, discutimos desafios na otimização de funções — reforçando sua relevância.
Com um guia prático, abordamos a implementação, destacando Gaussian Process Regression e funções de aquisição. Uma parte importante foi o uso da otimização bayesiana para ajuste de hiperparâmetros em modelos de machine learning, mostrando sua utilidade na prática.
No geral, este conteúdo funciona tanto como visão introdutória quanto como guia prático, destacando o papel fundamental da otimização bayesiana em machine learning e otimização computacional.
Traz insights valiosos para profissionais, pesquisadores e entusiastas, enfatizando a aplicabilidade e o impacto do método nos desafios computacionais atuais.
Se você quer se aprofundar em otimização bayesiana e sua implementação em Python, nosso curso Hyperparameter Tuning in Python oferece prática com metodologias comuns de ajuste automático de hiperparâmetros usando a biblioteca Scikit Learn. Entre as metodologias avançadas estão algoritmos bayesianos e genéticos.
A Zoumana desenvolve ferramentas de IA LLM para ajudar as empresas a realizar due diligence de sustentabilidade e avaliações de risco. Anteriormente, ele trabalhou como cientista de dados e engenheiro de aprendizado de máquina na Axionable e na IBM. Zoumana é o fundador da plataforma de tecnologia educacional de aprendizagem entre pares ETP4Africa. Ele escreveu mais de 20 tutoriais para o DataCamp.

