B∑

Sassamaru Docs

Documentação técnica do modelo

← Voltar ao índice
Sassamaru: Um modelo probabilístico de previsão de partidas de futebol
Arquitectura, parâmetros e decisões de design para previsão de partidas e simulação de competições usando regressão de Poisson bivariada, ratings Elo e correção Dixon-Coles.
Poisson bivariado Ratings Elo Dixon-Coles Temporal decay Monte Carlo Brasileirão 2003–2026 International 1872–2026
Março 2026 · Versão 1.0
Índice
  1. Motivação e escopo
  2. Dados
  3. Arquitetura do modelo
  4. Da λ às probabilidades e odds
  5. Validação e backtesting
  6. Simulação Monte Carlo
  7. Diferenças entre os apps
  8. Limitações conhecidas
  9. ToDo e próximos passos
§ 1

Motivação e escopo

O Sassamaru nasceu de uma pergunta simples: é possível construir um modelo de previsão de futebol robusto que rode inteiramente no navegador, sem servidor, sem API externa, usando apenas dados históricos públicos?

A resposta é sim — com ressalvas. Modelos probabilísticos de futebol têm longa tradição acadêmica, começando com Maher (1982) e Dixon & Coles (1997). O Sassamaru reimplementa essa tradição em JavaScript client-side, priorizando transparência, reprodutibilidade e facilidade de uso.

O escopo é deliberadamente limitado: previsão de resultados 1X2 (mandante vence / empate / visitante vence) com probabilidades calibradas e odds derivadas. Não há previsão de escanteios, cartões, marcadores individuais ou mercados asiáticos.

O que o modelo não é: Uma ferramenta de apostas. As odds geradas são odds justas derivadas das probabilidades do próprio modelo, com overround fixo. Elas não refletem o mercado real e não incorporam informação de escalações, lesões ou condição de campo.
§ 2

Dados

Brasileirão

Dataset customizado campeonatobrasileirolimpo.csv com 9 200+ partidas do Campeonato Brasileiro Série A entre 2003 e 2026 (rodadas 1–8 da edição atual). As colunas usadas são: rodada (rodata), mandante, visitante e placar.

Atenção — estrutura temporal: O dataset não contém datas — apenas o número da rodada. O modelo usa a rodada como unidade de tempo, o que exige detecção automática de temporadas via clustering de "rodada 1" (mínimo de 5 ocorrências consecutivas). Isso torna o decay temporal independente de calendário, mas também significa que jogos fora de rodada (amistosos, copas) não estão presentes.

Internacional

Dataset público de Mart Jürisoo disponível no Kaggle (international football results), com 49 000+ partidas entre seleções desde 1872. Colunas: date, home_team, away_team, home_score, away_score, neutral. O campo neutral é booleano e indica se o jogo foi disputado em campo neutro.

Para o modelo de seleções, o decay é date-based (dias desde cada partida), não round-based. O treinamento usa dados a partir de 1990 por padrão, já que o futebol pré-Copa do Mundo moderna tem distribuições estatísticas bastante distintas das atuais.

Jogos (Brasileirão)
9 200+
2003 – 2026
Clubes ativos
~50
ao longo dos anos
Jogos (internacional)
49 000+
1872 – 2026
Seleções
~270
com dados históricos
§ 3

Arquitetura do modelo

O pipeline de previsão segue cinco etapas principais:

1. Pesos temporais 2. Poisson (λ) 3. Elo (ajuste λ) 4. Dixon-Coles P(H/D/A)
Figura 1 — Pipeline de previsão. Cada etapa refina a estimativa de gols esperados (λ) ou a distribuição de placares resultante.

3.1 Pesos temporais (temporal decay)

Partidas mais antigas são menos informativas do que partidas recentes. Para capturar isso, cada jogo histórico recebe um peso calculado com uma função de half-life exponencial:

w(age) = max(w_min, 0.5 ^ (age / half_life))
ageIdade do jogo em rodadas (Brasileirão) ou dias (seleções)
half_lifeMeia-vida — quando age = half_life, o peso cai para 0.5
w_minPeso mínimo — evita que jogos muito antigos sejam zerados

Três pesos independentes são calculados, com half-lives diferentes, para os três componentes que os usam:

ComponenteHalf-life (Brasileirão)Half-life (Seleções)Peso mínimo
Elo76 rodadas (~2 temporadas)730 dias (~2 anos)0.10
Poisson (λ)152 rodadas (~4 temporadas)1 460 dias (~4 anos)0.25
Forma recentenão usado (ver 3.4)120 dias (~4 meses)0.35

A intuição por trás dos diferentes half-lives: a força de ataque e defesa (Poisson) muda devagar — um time bom geralmente permanece bom por anos. A força relativa (Elo) muda um pouco mais rápido.

3.2 Regressão de Poisson

O modelo central assume que o número de gols marcados por cada time em uma partida segue distribuições de Poisson independentes com parâmetros λH (gols esperados do mandante) e λA (gols esperados do visitante).

λ_H = atk_H × def_A × league_home_avgλ_A = atk_A × def_H × league_away_avg
atk_HForça de ataque do mandante jogando em casa (razão sobre a média da liga)
def_AVulnerabilidade defensiva do visitante fora de casa
league_home_avgMédia ponderada de gols por jogo em casa na liga

As quatro forças por time (ataque em casa, defesa em casa, ataque fora, defesa fora) são calculadas como razões em relação à média da liga, usando médias ponderadas pelos pesos temporais de Poisson:

atk_H(t) = Σ(gols_marcados_em_casa × w_poi) / Σ(w_poi) ÷ league_home_avgdef_H(t) = Σ(gols_sofridos_em_casa × w_poi) / Σ(w_poi) ÷ league_away_avg
Valores > 1 indicam força acima da média da liga · valores < 1 indicam abaixo. w_poi = peso temporal de Poisson de cada partida.

Essa estrutura é a base do modelo de Dixon & Coles (1997) e equivale a uma regressão log-linear de Poisson com efeitos fixos por time e por lado (casa/fora).

3.3 Ratings Elo

O sistema Elo, desenvolvido originalmente para xadrez por Arpad Elo, foi adaptado para futebol pela FIFA e por pesquisadores como Hvattum & Arntzen (2010). A ideia central é que cada time tem um rating que sobe quando vence e cai quando perde, proporcionalmente à surpresa do resultado.

R_novo = R_antigo + K × (resultado − E[resultado])E[resultado] = 1 / (1 + 10 ^ ((R_adversário − R_time) / 400))
resultado1 se vitória · 0.5 se empate · 0 se derrota
E[resultado]Probabilidade esperada de vitória via escala logística
KK_base × (1 + 0.5 × max(0, diff_gols − 1)) × w_elo
w_eloPeso temporal — reduz o impacto de jogos antigos no rating

O fator K é dinâmico: vitórias por maior placar geram atualização mais forte. O peso temporal w_elo reduz o impacto de jogos antigos no rating atual.

No início de cada temporada do Brasileirão, os ratings sofrem um reset parcial em direção ao valor inicial (1500), controlado pelo parâmetro SEASON_RESET_ALPHA = 0.20. Isso captura o fato de que, com mudanças de elenco, um time forte tende a regredir um pouco à média.

R_resetado = R_anterior × (1 − α) + R_inicial × α
αSEASON_RESET_ALPHA = 0.20 — fração de regressão à média a cada temporada

O Elo entra no modelo como um ajuste multiplicativo em λ, usando o parâmetro γ (gamma):

λ_H_ajustado = λ_H × exp( +γ × ΔElo / 400 )λ_A_ajustado = λ_A × exp( −γ × ΔElo / 400 )
ΔEloR_mandante − R_visitante
γ0.06 — controla o quanto o Elo pesa sobre λ
clampO ajuste é limitado a [−0.18, +0.18] para evitar distorções extremas
Por que não usar Elo diretamente? Seria possível derivar probabilidades direto do Elo via fórmula logística, mas isso perderia a informação de gols esperados — fundamental para calcular distribuição de placares. A abordagem híbrida (Poisson + Elo como ajuste) captura tanto a intensidade ofensiva/defensiva quanto a força relativa histórica.

3.4 Forma recente — por que foi removida

O modelo do Brasileirão aplicava um fator de forma: as médias de gols marcados e sofridos nos últimos 5 jogos viravam multiplicadores de λ, limitados a ±25%. A ideia é intuitiva — um time em crise tende a continuar mal — mas o backtest walk-forward mostrou que ela piorava as previsões.

Medido sobre as três últimas temporadas, retirando apenas o fator de forma e mantendo todo o resto igual:

ConfiguraçãoLog-loss ↓RPS ↓Acurácia ↑
Com fator de forma1.09750.222946.6%
Sem fator de forma1.05840.213449.2%

O motivo é estatístico. A média de 5 amostras de uma Poisson(1.3) tem desvio-padrão de aproximadamente 0.51, então a razão form_GF / média_liga tem desvio-padrão de cerca de 0.39 — bem maior do que a largura do próprio clamp. O fator passava quase todo o tempo saturado em 0.75 ou 1.25, respondendo a ruído amostral e não a sinal. Pior: esses mesmos 5 jogos já são os de maior peso na estimação de α e β, então a informação era contada duas vezes.

Um fator de forma melhor construído — baseado no resíduo (gols observados menos gols previstos pelo modelo) e ajustado pela força do adversário — pode ter valor. Enquanto não passar pelo backtest, o modelo não usa forma recente.

3.5 Correção Dixon-Coles

Dixon & Coles (1997) identificaram que o modelo de Poisson puro superestima a probabilidade de placares altos e subestima os placares baixos, particularmente 0-0, 1-0, 0-1 e 1-1. A correção introduz um parâmetro ρ (rho) que ajusta essas quatro células da matriz de placares:

P(g_H, g_A) ∝ Poisson(λ_H, g_H) × Poisson(λ_A, g_A) × τ(g_H, g_A) ⎧ 1 − λ_H·λ_A·ρ se g_H=0, g_A=0 ⎪ 1 + λ_A·ρ se g_H=1, g_A=0τ(g,g) = ⎨ 1 + λ_H·ρ se g_H=0, g_A=1 ⎪ 1 − ρ se g_H=1, g_A=1 ⎩ 1 caso contrário
ρEstimado via MLE — tipicamente entre −0.05 e −0.15 para o Brasileirão
ρ < 0Aumenta P(0-0) e P(1-1) · reduz P(1-0) e P(0-1)

O valor de ρ é estimado por máxima verossimilhança. No modelo de seleções isso é feito por busca em grade de −0.50 a +0.50 em passos de 0.01; no modelo do Brasileirão, ρ entra no vetor de parâmetros e é estimado junto com α, β, γ e μ pelo mesmo gradiente.

O valor empírico encontrado para o Brasileirão fica próximo de zero — bem menos negativo do que o −0.10 que já foi assumido por hipótese. Ou seja: nos dados do Brasileirão a correção de Dixon-Coles é quase inerte, e forçar ρ = −0.10 estava distorcendo os placares baixos sem ganho de acurácia. É um bom exemplo de por que estimar vale mais do que arbitrar.

O τ usado na previsão é o mesmo τ que a verossimilhança maximiza. Isso parece óbvio, mas por um tempo não foi verdade: o ajuste usava τ(0,0) = 1 − λ_H·λ_A·ρ enquanto a previsão aplicava 1 − ρ, sem os λ — três das quatro células com a forma funcional errada.

Normalização: Após aplicar a correção, a matriz de placares é renormalizada para que a soma de todas as probabilidades seja 1.0. Isso é necessário porque τ pode distorcer ligeiramente a soma total.

3.6 Fator de descanso — por que foi removido

O modelo ajustava λ em função de quantas rodadas o time havia descansado desde o jogo anterior (+3% por rodada extra, limitado a −8%/+6%). No backtest, ligar esse fator piorava o log-loss de 1.0975 para 1.0995.

Além de não ajudar, a construção era frágil: o descanso era inferido apenas pelo intervalo entre rodadas do Brasileirão. Um time que jogou Libertadores ou Copa do Brasil no meio de semana aparecia para o modelo como descansado — justamente o caso em que o efeito real deveria ser o oposto. Modelar isso direito exige o calendário de outras competições, que não está no dataset.

3.7 Campo neutro (seleções)

Aproximadamente 30% das partidas internacionais são disputadas em campo neutro (Copas do Mundo, torneios continentais, amistosos em terceiro país). Nesses casos, a vantagem de jogar em casa não existe, então λ é calculado usando a média entre league_home_avg e league_away_avg para ambos os lados:

base = (league_home_avg + league_away_avg) / 2λ_H = atk_H × def_A × baseλ_A = atk_A × def_H × base
Com vantagem de casa: λ_H usa league_home_avg (maior) e λ_A usa league_away_avg. No campo neutro, ambos usam a mesma base — eliminando o benefício do mandante.

Ao construir o modelo, jogos em campo neutro são tratados como "jogos fora" para ambos os times nos cálculos de força de ataque e defesa, evitando inflar o parâmetro de vantagem de casa com dados de jogos que não têm tal vantagem.

§ 4

Da λ às probabilidades e odds

Com λH e λA determinados, a probabilidade de cada placar possível (gH, gA) é calculada como produto das probabilidades de Poisson, corrigida por Dixon-Coles:

P(g_H, g_A) ∝ Pois(λ_H, g_H) × Pois(λ_A, g_A) × τ(g_H, g_A)Pois(λ, k) = λ^k × e^(−λ) / k!
g_H, g_AGols do mandante e visitante ∈ {0, 1, 2, …, 8} (MAX_GOALS = 8)
τ(g_H, g_A)Fator de correção Dixon-Coles (ver §3.5)

As probabilidades marginais de resultado (1X2) são obtidas pela soma das células da matriz:

P(Mandante) = Σ P(g_H, g_A) ∀ g_H > g_AP(Empate) = Σ P(g_H, g_A) ∀ g_H = g_AP(Visitante) = Σ P(g_H, g_A) ∀ g_H < g_A

As odds são derivadas dessas probabilidades adicionando um overround (margem da casa), que representa o lucro esperado do bookmaker. Com overround de 6%:

odd_H = 1 / (P(H) × (1 + overround))odd_D = 1 / (P(D) × (1 + overround))odd_A = 1 / (P(A) × (1 + overround))
overround0.06 — soma das probabilidades implícitas = 1.06
odd justa1 / P(X) sem overround — odd que um mercado eficiente pagaria
Log-space para evitar underflow: Para λ elevados, λ^k / k! pode causar underflow em ponto flutuante. O modelo calcula Poisson em log-space: exp(k × log(λ) − λ − logfact(k)), com log-fatoriais pré-computados em cache.
§ 5

Validação e backtesting

O modelo inclui um backtest walk-forward: para cada uma das últimas BACKTEST_SEASONS temporadas do Brasileirão, o modelo é treinado em todas as temporadas anteriores e avaliado nos jogos da temporada corrente. As métricas calculadas são:

Brier Score (multi-classe)

BS = (1/N) × Σ [(p_H − o_H)² + (p_D − o_D)² + (p_A − o_A)²]
o_X1 se X ocorreu, 0 caso contrário (variável indicadora)
range0 = perfeito · 2 = totalmente errado
benchmark~0.667 para modelo uniforme (1/3, 1/3, 1/3)

Log-Loss

LL = −(1/N) × Σ log( p_resultado )
p_resultadoProbabilidade atribuída pelo modelo ao resultado que de fato ocorreu
penalidadeConfiança errada é punida mais do que incerteza — log(0.1) >> log(0.4)
benchmarklog(3) ≈ 1.099 para modelo uniforme

Acurácia 1X2

Percentual de jogos em que o palpite do modelo (resultado mais provável) coincidiu com o resultado real. Sassamarumark de referência: ~46% (proporção de vitórias do mandante). O modelo historicamente atinge ~52–55% no Brasileirão.

Calibração

O modelo é considerado calibrado se, entre todos os jogos para os quais atribuiu probabilidade ~30%, aproximadamente 30% desses jogos ocorreram. A calibração é visualizada em um gráfico de confiabilidade com 10 bins de 10% cada.

Nota metodológica: O backtest usa o modelo treinado em dados históricos completos (até a temporada de teste), não um modelo re-treinado a cada rodada. Isso é uma simplificação que pode introduzir leve viés otimista, mas é computacionalmente viável para execução no navegador.
§ 6

Simulação Monte Carlo

Para os apps de simulação de temporada (Brasileirão e Copa do Mundo), o modelo é usado para gerar distribuições de resultados possíveis via Monte Carlo: o torneio inteiro é simulado N vezes (tipicamente 5 000), e as frequências de cada evento (campeão, classificado, rebaixado, etc.) são estimadas empiricamente.

Em cada simulação, para cada partida:

Para cada partida em cada simulação: 1. Calcular λ_H, λ_A via pipeline completo 2. Construir matriz P(g_H, g_A) com correção Dixon-Coles 3. Amostrar (g_H, g_A) ~ P(g_H, g_A) 4. Atualizar pontuação e saldo de gols
5 000 simulações × 380 partidas = ~1.9 milhões de placares amostrados por execução.

Para jogos eliminatórios (Copa do Mundo), o empate não existe como resultado final. Se a distribuição Poisson + DC gera empate, o vencedor é determinado por um sorteio ponderado pela razão P(H) / (P(H) + P(A)), emulando pênaltis.

Escalonamento e responsividade

Para evitar travar o navegador, o loop Monte Carlo cede o controle ao event loop do JavaScript a cada 50–100 iterações via await new Promise(r => setTimeout(r, 0)). Isso permite atualizar a barra de progresso e manter a interface responsiva durante o cálculo.

Interpretação das probabilidades

Com N = 5 000 simulações, o erro padrão de uma probabilidade de 50% é √(0.5 × 0.5 / 5000) ≈ 0.7%. Para probabilidades extremas (ex.: rebaixamento do favorito, ~2%), o erro padrão é ≈ 0.2%, suficiente para diferenciar candidatos ao rebaixamento com confiança razoável.

§ 7

Diferenças entre os apps

Característica Sassamaru Rodada Sassamaru Brasileirão Sassamaru Seleções Sassamaru Copa
Dataset Brasileirão 2003–26 Brasileirão 2003–26 Internacional 1872–26 Internacional 1872–26
Unidade de tempo Rodadas Rodadas Dias Dias
Campo neutro Não Não Sim (flag CSV) Sim (grupo/fase)
Fator descanso Não (removido) Não Não Não
Detecção de temporadas Auto (clusters) Auto (clusters) N/A N/A
Modo de saída Por partida Classificação Monte Carlo Por partida Torneio Monte Carlo
§ 8

Limitações conhecidas

Nenhum modelo é completo. As limitações mais relevantes do Sassamaru são:

Informação não modelada

O modelo não sabe que Neymar está lesionado, que um técnico foi demitido ontem, que o jogo é disputado em altitude de 3 600m, que chove forte ou que um time está concentrado em outra competição. Toda essa informação contextual é real e relevante — o modelo ignora completamente.

Empates

O modelo de Poisson bivariado tende a subestimar a probabilidade de empate em comparação com o mercado real. A correção Dixon-Coles mitiga isso parcialmente (via aumento de P(0-0) e P(1-1)), mas o problema persiste para placares maiores (2-2, 3-3).

Times com poucos dados

Times recém-promovidos ou seleções com histórico limitado no dataset têm estimativas de força pouco confiáveis. O modelo usa fallback para médias da liga, o que pode super ou subestimar esses times.

Não-estacionaridade

O futebol muda: estilos de jogo, volume de transferências, intensidade física. O modelo trata toda a história (desde 2003 / 1990) como amostras do mesmo processo, ponderando pelo decay. Isso é uma aproximação — o futebol de 2026 não é estatisticamente idêntico ao de 2003, mesmo com decay.

Independência entre gols

O modelo assume que os gols do mandante e do visitante são independentes. Na prática, o estado do jogo influencia o comportamento: um time que abre 3-0 não joga da mesma forma que em 0-0. Essa correlação dinâmica não é capturada.

Monte Carlo e o bracket da Copa

O chaveamento da Copa do Mundo 2026 para a fase eliminatória é complexo — o chaveamento real depende de quais grupos os 8 melhores terceiros colocados vieram. O simulador usa uma simplificação de pareamento sequencial, o que pode gerar matches que não seriam possíveis no torneio real.

§ 9

ToDo e próximos passos

O modelo atual é funcional e produz previsões razoáveis, mas há espaço significativo para melhoria. Os itens abaixo estão ordenados por impacto esperado na qualidade das previsões.

Modelo

Dados

Interface

Infraestrutura