Machine Learning para Previsão de Resultados
Dataset, feature engineering, treino com XGBoost e backtesting real — tudo que você precisa para construir um modelo preditivo de futebol.
Carregando
Dataset, feature engineering, treino com XGBoost e backtesting real — tudo que você precisa para construir um modelo preditivo de futebol.
Scripts Python prontos para coletar, armazenar e analisar odds de múltiplas casas automaticamente.
Monte projetos de data science com dados reais de apostas para portfólio e aprendizado.
Machine Learning para Previsão de Resultados. Dataset, feature engineering, treino com XGBoost e backtesting real — tudo que você precisa para construir um modelo preditivo de futebol.
Antes de qualquer código, preciso ser honesto sobre expectativas. Modelos de ML para futebol conseguem, em média, acurácia entre 50-55% na previsão de resultado de três vias (vitória mandante, empate, vitória visitante). O problema é que um chute puramente aleatório acerta ~33%, então o ganho real é menor do que parece.
O que ML consegue bem: identificar favoritos e azarões com mais precisão do que as odds implícitas em alguns mercados específicos. Identificar padrões em ligas menores onde há menos liquidez e, portanto, mais ineficiência. Calibrar probabilidades com maior precisão do que analistas humanos para grandes volumes de jogos.
O que ML não consegue: prever jogos individuais com confiança alta. Incorporar informações em tempo real como lesões de última hora, condições climáticas extremas ou motivação dos times em casos específicos — a menos que você codifique essas features manualmente. Superar consistentemente os mercados de alta liquidez da Pinnacle ou Betfair, onde o preço já incorpora praticamente toda a informação pública disponível.
Dito isso, o processo de construção do modelo é extremamente valioso como exercício de data science. Você vai aprender feature engineering com dados temporais, lidar com data leakage (um dos erros mais comuns nesse tipo de projeto), implementar backtesting correto, e trabalhar com XGBoost num problema de classificação multiclasse. São skills diretos para qualquer posição de data scientist. Tudo isso com dados reais e contexto que faz sentido.
A qualidade do seu modelo depende da qualidade dos dados. Boa notícia: existem fontes excelentes e gratuitas para futebol.
Essa é a fonte histórica mais usada pela comunidade. Cobre mais de 30 ligas europeias com dados desde os anos 90 em alguns casos. Cada arquivo CSV tem resultado final, resultado intervalo, estatísticas básicas (chutes, chutes no gol, escanteios, faltas, cartões) e as odds históricas de mais de 30 casas de apostas. Gratuito. Download direto sem autenticação. Simplesmente acessa football-data.co.uk e baixa.
A limitação é que o dataset não tem estatísticas avançadas — sem xG (expected goals), sem passes progressivos, sem dados de pressão defensiva. Para Brasileirão, a cobertura começou a melhorar só nos últimos anos. Mas para começar e validar seu pipeline, é perfeito.
Para quem quer dados avançados, o FBref é o destino certo. Em parceria com a StatsBomb, o site oferece xG, xA, pressões defensivas, carries, passes progressivos e muito mais para as principais ligas mundiais. Dá pra fazer web scraping com a biblioteca soccerdata do Python — que abstrai todo o scraping e entrega DataFrames prontos para análise.
A StatsBomb também disponibiliza alguns datasets gratuitamente via GitHub (statsbomb/open-data), incluindo dados de Copa do Mundo e algumas ligas específicas com detalhamento de eventos em nível de passe a passe. São os dados mais ricos disponíveis publicamente e usados por times profissionais da Premier League.
Para quem quer construir algo sólido, minha recomendação: começa com Football-Data.co.uk pra validar o pipeline completo, depois incorpora features do FBref conforme o modelo amadurece. Não tenta usar só dados avançados no início — a complexidade de limpar e alinhar esses datasets vai te travar antes de chegar na parte interessante.
Aqui mora boa parte da mágica — e dos erros. Feature engineering para dados de futebol tem um desafio central: data leakage. Você não pode usar informações do futuro para prever o passado durante o treino. Parece óbvio, mas é fácil de errar quando você calcula médias móveis sem cuidado.
As features mais básicas e poderosas ao mesmo tempo: média de gols marcados e sofridos nas últimas N partidas (tipicamente 5 ou 10), média de chutes, chutes no gol, escanteios e faltas. O segredo é sempre calcular essas médias com uma janela rolling que exclui o jogo atual — caso contrário você tem leakage. No pandas: df.groupby('team')['goals_scored'].shift(1).rolling(5).mean() é o padrão correto.
Forma recente é mais do que média de gols. Você quer capturar momentum — se um time ganhou os últimos 5 jogos seguidos, isso tem impacto diferente de ganhar 3 nos últimos 10. Uma feature útil: pontos nos últimos 5 jogos (0 a 15), com pesos que dão mais importância aos jogos mais recentes. Outra: sequência atual — quantos jogos seguidos sem perder, ou quantos sem ganhar.
Também vale separar desempenho em casa vs fora. Times que jogam muito bem em casa mas são inconsistentes fora são diferentes de times equilibrados. O modelo precisa dessas features separadas, não uma média geral.
Confrontos diretos históricos têm valor em alguns matchups específicos. Times que historicamente dominam um rival específico — independente de forma atual — podem ter um edge psicológico e tático que os dados de forma recente não capturam. Mas cuidado: o histórico de head-to-head às vezes tem poucos pontos de dados, o que pode introduzir ruído em vez de sinal. Use com cautela e só para confrontos com pelo menos 5-10 histórico.
Com as features prontas, o treino em si é a parte mais simples. O alvo é uma variável de 3 classes: H (vitória mandante), D (empate), A (vitória visitante). Scikit-learn e XGBoost lidam com multiclasse nativamente.
Comece sempre com Random Forest como baseline. É robusto, não precisa de normalização, lida bem com features correlacionadas e dá feature importance de graça. Configure com 200 árvores, max_depth entre 5-8, e min_samples_leaf de 10 pra evitar overfitting. Você provavelmente vai ver acurácia entre 48-52% nessa primeira rodada — totalmente normal.
Depois migra pro XGBoost. Com learning_rate baixo (0.01-0.05), n_estimators alto (500-1000) e early stopping baseado num validation set, o XGBoost tipicamente melhora 2-4 pontos percentuais em relação ao Random Forest. O ganho parece pequeno, mas em termos de calibração de probabilidade — que é o que realmente importa pra identificar value bets — a diferença é significativa.
Uma dica importante: use log-loss como métrica principal, não acurácia. Log-loss penaliza previsões confiantes e erradas muito mais do que previsões incertas e erradas. Um modelo que diz '80% chance de vitória mandante' e erra é muito pior do que um que diz '60%'. Pra identificar value bets, você precisa de probabilidades bem calibradas — não apenas de acertar qual resultado vai ocorrer.
Backtesting é onde a maioria dos projetos falha. A tentação é pegar toda a série histórica, treinar o modelo e testar no mesmo período. Isso garante resultados incríveis que não se replicam em dados novos — overfitting puro.
O backtesting correto para dados temporais usa walk-forward validation. Você treina no passado, testa no futuro imediato, avança a janela, treina com mais dados, testa no próximo período, e assim por diante. É computacionalmente mais pesado, mas é a única forma honesta de avaliar o modelo.
Uma métrica crucial no backtesting de apostas: simule apostas reais com as previsões do modelo. Toda vez que o modelo encontra um edge acima do threshold, simule uma aposta de 1 unidade. Ao final, calcule o ROI total: (lucro total / total apostado) × 100. Se o ROI for positivo no período de teste, você tem algo. Se for negativo, o modelo não está gerando valor real independente da acurácia percentual.
Olha também o número de apostas simuladas. Se você teve ROI de +15% mas fez apenas 30 apostas, isso é estatisticamente insignificante — pode ser ruído puro. Você precisa de pelo menos 200-300 apostas no período de backtesting para ter alguma confiança estatística. Ligas pequenas ou nichos de mercado podem não ter volume suficiente pra isso.
Vou falar o que a maioria dos tutoriais de 'previsão de futebol com ML' não fala: modelos públicos com features públicas têm dificuldade enorme de vencer o mercado de apostas de alta liquidez no longo prazo. Por quê? Porque os preços das casas como Pinnacle já incorporam praticamente toda a informação pública disponível — incluindo modelos similares ao seu.
Onde há oportunidade real: ligas com menor liquidez de mercado, onde as casas têm menos dados e menos apostadores sofisticados. Copa do Brasil em fase inicial, Série B e C do Brasileirão, ligas regionais europeias de segundo escalão. Nesses mercados, a ineficiência é maior e modelos simples podem ter edge real.
Outra área: mercados alternativos. Em vez de prever resultado H/D/A — o mercado mais líquido e eficiente — tente prever número de escanteios, número de cartões, ou total de gols (over/under). Esses mercados têm menos liquidez e, portanto, potencialmente mais ineficiência.
A honestidade aqui é importante: o maior valor desse projeto é o aprendizado técnico. Feature engineering com dados temporais, prevenção de data leakage, calibração de probabilidades, backtesting correto — são skills que qualquer empresa de dados quer ver no seu portfólio. O projeto de ML para futebol aparece muito bem em entrevistas porque é concreto, tem dados reais, e demonstra maturidade no processo de modelagem. Se quiser ver exemplos de como montar esse tipo de projeto para portfólio, confira o artigo sobre <a href='/2026/projetos-data-science-apostas-esportivas'>projetos de data science com dados de apostas</a>. E para uma perspectiva prática sobre o mercado de apostas em si, vale ler <a href='/2025/i-found-a-way-to-beat-sportsbo'>/2025/i-found-a-way-to-beat-sportsbo</a> antes de decidir onde aplicar o modelo.