Ya van 24 partidos de la fase de grupos. Capturé todos los resultados reales hasta hoy desde football-data.org, reentrené el modelo bayesiano con esos datos, y volví a simular el torneo completo (500 mil veces sobre la GPU) condicionando a lo que ya ocurrió. Aquí está el panorama actualizado: cómo le ha ido al modelo, qué viene —en orden cronológico para que sea fácil de seguir— y cómo quedaron las probabilidades de campeón.
Qué se actualizó en este refresh:
- 24 resultados reales rellenados en el dataset (jornadas del 11 al 17 de junio).
- Posterior bayesiano reentrenado (Poisson jerárquico con ataque/defensa por selección + altitud de sede).
- Predicciones de los 48 partidos restantes regeneradas.
- Simulación del torneo completo recalculada: los partidos jugados quedan fijos a su marcador, solo se simula lo que falta.
¿Cómo le ha ido al modelo?
Sobre los 24 partidos jugados, el favorito del modelo acertó 14 de 24 (58.3%), con una log-loss de 0.918. La fase de grupos de un Mundial es brutal para cualquier pronosticador: muchos empates inesperados (España 0-0 Cabo Verde, Arabia 1-1 Uruguay, Bélgica 1-1 Egipto) y favoritos que tropiezan. Aun así, los grandes batacazos esperados se cumplieron: Argentina, Francia, Inglaterra y Alemania ganaron con solvencia.
Resultados ya jugados (orden cronológico)
| Fecha | Partido | Resultado | Pick del modelo | |
|---|---|---|---|---|
| 11 jun | México vs Sudáfrica | 2-0 | México (56%) | ✅ |
| 11 jun | Corea del Sur vs Rep. Checa | 2-1 | Corea del Sur (48%) | ✅ |
| 12 jun | Canadá vs Bosnia | 1-1 | Canadá (58%) | ❌ |
| 12 jun | EE.UU. vs Paraguay | 4-1 | EE.UU. (44%) | ✅ |
| 13 jun | Australia vs Turquía | 2-0 | Australia (52%) | ✅ |
| 13 jun | Brasil vs Marruecos | 1-1 | Brasil (35%) | ❌ |
| 13 jun | Haití vs Escocia | 0-1 | Escocia (50%) | ✅ |
| 13 jun | Qatar vs Suiza | 1-1 | Suiza (65%) | ❌ |
| 14 jun | Alemania vs Curazao | 7-1 | Alemania (88%) | ✅ |
| 14 jun | Costa de Marfil vs Ecuador | 1-0 | Empate (38%) | ❌ |
| 14 jun | P. Bajos vs Japón | 2-2 | Japón (41%) | ❌ |
| 14 jun | Suecia vs Túnez | 5-1 | Suecia (46%) | ✅ |
| 15 jun | Bélgica vs Egipto | 1-1 | Bélgica (44%) | ❌ |
| 15 jun | Irán vs Nueva Zelanda | 2-2 | Irán (44%) | ❌ |
| 15 jun | Arabia Saudí vs Uruguay | 1-1 | Uruguay (52%) | ❌ |
| 15 jun | España vs Cabo Verde | 0-0 | España (72%) | ❌ |
| 16 jun | Argentina vs Argelia | 3-0 | Argentina (68%) | ✅ |
| 16 jun | Austria vs Jordania | 3-1 | Austria (52%) | ✅ |
| 16 jun | Francia vs Senegal | 3-1 | Francia (53%) | ✅ |
| 16 jun | Irak vs Noruega | 1-4 | Noruega (65%) | ✅ |
| 17 jun | Inglaterra vs Croacia | 4-2 | Inglaterra (56%) | ✅ |
| 17 jun | Ghana vs Panamá | 1-0 | Ghana (37%) | ✅ |
| 17 jun | Portugal vs RD Congo | 1-1 | Portugal (55%) | ❌ |
| 17 jun | Uzbekistán vs Colombia | 1-3 | Colombia (62%) | ✅ |
La racha del 16 y 17 de junio fue casi perfecta (8 de 9): las potencias por fin jugaron y el modelo brilla cuando hay diferencia clara de nivel. Donde sufre es en los duelos parejos del medio de la tabla, justo donde el fútbol es más impredecible.
¿Quién levanta la copa? (odds actualizadas)
Con los 24 resultados fijados y el resto simulado, así quedan las probabilidades de ser campeón del mundo. Argentina se despega (14.8%) tras su 3-0 a Argelia; España se mantiene segunda pese al tropiezo con Cabo Verde (su grupo sigue siendo accesible). Inglaterra sube fuerte tras el 4-2 a Croacia.
@d3
const data = [{"t":"Argentina","v":14.8},{"t":"España","v":10.9},{"t":"Inglaterra","v":7.3},{"t":"Brasil","v":6.3},{"t":"Francia","v":6.0},{"t":"Colombia","v":5.9},{"t":"Alemania","v":5.7},{"t":"Marruecos","v":4.9},{"t":"Portugal","v":4.5},{"t":"Japón","v":3.5},{"t":"Australia","v":3.4},{"t":"Noruega","v":2.9},{"t":"P. Bajos","v":2.6},{"t":"Uruguay","v":2.4},{"t":"México","v":2.1},{"t":"Bélgica","v":2.0}];
const W = container.clientWidth || 1000;
const m = {top:8,right:64,left:120,bottom:28};
const rowH = 30, H = data.length*rowH + m.top + m.bottom;
const svg = d3.select(container).append('svg').attr('width',W).attr('height',H)
.attr('font-family','JetBrains Mono, system-ui, sans-serif');
const x = d3.scaleLinear().domain([0, d3.max(data,d=>d.v)*1.08]).range([m.left, W-m.right]);
const y = d3.scaleBand().domain(data.map(d=>d.t)).range([m.top, H-m.bottom]).padding(0.45);
const color = d3.scaleSequential(d3.interpolateTurbo).domain([d3.max(data,d=>d.v)*1.25, 0]);
svg.append('g').attr('transform',`translate(0,${H-m.bottom})`)
.call(d3.axisBottom(x).ticks(6).tickFormat(d=>d+'%'))
.call(g=>g.select('.domain').remove())
.call(g=>g.selectAll('.tick line').attr('stroke','#33332e'))
.attr('color','#9a9a8e').attr('font-size','11px');
const row = svg.selectAll('g.row').data(data).join('g');
row.append('line').attr('x1',x(0)).attr('x2',d=>x(d.v))
.attr('y1',d=>y(d.t)+y.bandwidth()/2).attr('y2',d=>y(d.t)+y.bandwidth()/2)
.attr('stroke',d=>color(d.v)).attr('stroke-width',3).attr('opacity',0.5);
row.append('circle').attr('cx',d=>x(d.v)).attr('cy',d=>y(d.t)+y.bandwidth()/2)
.attr('r',7).attr('fill',d=>color(d.v));
row.append('text').attr('x',m.left-10).attr('y',d=>y(d.t)+y.bandwidth()/2)
.attr('dy','0.35em').attr('text-anchor','end').attr('font-size','13px')
.attr('fill','#d4d4c8').text(d=>d.t);
row.append('text').attr('x',d=>x(d.v)+12).attr('y',d=>y(d.t)+y.bandwidth()/2)
.attr('dy','0.35em').attr('font-size','12px').attr('font-weight','600')
.attr('fill',d=>color(d.v)).text(d=>d.v.toFixed(1)+'%');
El camino a la gloria
Cada celda es la probabilidad de alcanzar esa ronda, de izquierda (octavos) a derecha (campeón). Pasa el cursor para el valor exacto.
@plotly
{"data": [{"type": "heatmap", "z": [[46.8,23.2,10.4,4.7,2.0],[56.3,26.8,11.5,5.0,2.1],[34.4,19.3,10.3,5.0,2.4],[42.2,22.1,11.6,5.6,2.6],[54.9,26.6,13.6,6.4,2.9],[59.8,32.9,15.3,7.4,3.4],[45.1,24.9,13.7,7.0,3.5],[52.1,29.6,16.6,8.8,4.5],[53.3,30.5,17.5,9.4,4.9],[62.7,39.9,21.9,11.7,5.7],[65.5,39.9,21.1,11.3,5.9],[64.4,35.8,20.7,11.1,6.0],[57.9,34.7,20.9,11.8,6.3],[65.0,39.5,22.9,12.7,7.3],[59.5,41.0,28.6,18.1,10.9],[68.5,51.5,35.5,22.7,14.8]], "x": ["Octavos","Cuartos","Semis","Final","Campeón"], "y": ["Bélgica","México","Uruguay","P. Bajos","Noruega","Australia","Japón","Portugal","Marruecos","Alemania","Colombia","Francia","Brasil","Inglaterra","España","Argentina"], "colorscale": "YlGnBu", "zmin": 0, "zmax": 75, "xgap": 2, "ygap": 2, "hovertemplate": "%{y} — %{x}: %{z:.1f}%<extra></extra>", "colorbar": {"ticksuffix": "%", "outlinewidth": 0, "tickfont": {"color": "#d4d4c8"}, "thickness": 14}}], "layout": {"height": 520, "margin": {"l": 110, "r": 20, "t": 30, "b": 30}, "paper_bgcolor": "rgba(0,0,0,0)", "plot_bgcolor": "rgba(0,0,0,0)", "font": {"family": "JetBrains Mono, system-ui, sans-serif", "size": 12, "color": "#d4d4c8"}, "xaxis": {"side": "top", "tickfont": {"color": "#d4d4c8"}, "fixedrange": true}, "yaxis": {"tickfont": {"color": "#d4d4c8"}, "fixedrange": true}}}
Tabla completa (top 24)
| # | Selección | Gr | Octavos | Cuartos | Semis | Final | Campeón |
|---|---|---|---|---|---|---|---|
| 1 | Argentina | J | 68% | 52% | 36% | 23% | 14.8% |
| 2 | España | H | 60% | 41% | 29% | 18% | 10.9% |
| 3 | Inglaterra | L | 65% | 40% | 23% | 13% | 7.3% |
| 4 | Brasil | C | 58% | 35% | 21% | 12% | 6.3% |
| 5 | Francia | I | 64% | 36% | 21% | 11% | 6.0% |
| 6 | Colombia | K | 66% | 40% | 21% | 11% | 5.9% |
| 7 | Alemania | E | 63% | 40% | 22% | 12% | 5.7% |
| 8 | Marruecos | C | 53% | 30% | 18% | 9% | 4.9% |
| 9 | Portugal | K | 52% | 30% | 17% | 9% | 4.5% |
| 10 | Japón | F | 45% | 25% | 14% | 7% | 3.5% |
| 11 | Australia | D | 60% | 33% | 15% | 7% | 3.4% |
| 12 | Noruega | I | 55% | 27% | 14% | 6% | 2.9% |
| 13 | P. Bajos | F | 42% | 22% | 12% | 6% | 2.6% |
| 14 | Uruguay | H | 34% | 19% | 10% | 5% | 2.4% |
| 15 | México | A | 56% | 27% | 12% | 5% | 2.1% |
| 16 | Bélgica | G | 47% | 23% | 10% | 5% | 2.0% |
| 17 | Suiza | B | 47% | 20% | 9% | 4% | 1.5% |
| 18 | Ecuador | E | 33% | 16% | 7% | 3% | 1.4% |
| 19 | EE.UU. | D | 51% | 24% | 9% | 4% | 1.3% |
| 20 | Corea | A | 51% | 22% | 8% | 3% | 1.3% |
| 21 | Austria | J | 38% | 17% | 8% | 3% | 1.1% |
| 22 | C. Marfil | E | 42% | 18% | 7% | 3% | 1.0% |
| 23 | Croacia | L | 30% | 13% | 6% | 2% | 0.9% |
| 24 | Canadá | B | 38% | 14% | 6% | 2% | 0.8% |
¿Quién pasa de grupos?
Con 48 equipos y 32 plazas (12 primeros, 12 segundos, 8 mejores terceros), los punteros de cada grupo ya casi tienen el boleto. Probabilidad de avanzar a la ronda de 32:
@vega-lite
{"$schema": "https://vega.github.io/schema/vega-lite/v5.json", "width": "container", "height": 460, "background": "transparent", "data": {"values": [{"team": "Argentina", "p": 99.8}, {"team": "Alemania", "p": 99.7}, {"team": "Inglaterra", "p": 99.6}, {"team": "Francia", "p": 99.2}, {"team": "México", "p": 98.6}, {"team": "Australia", "p": 98.3}, {"team": "Colombia", "p": 97.7}, {"team": "Noruega", "p": 97.5}, {"team": "EE.UU.", "p": 97.3}, {"team": "C. Marfil", "p": 96.3}, {"team": "Corea", "p": 95.6}, {"team": "Brasil", "p": 94.4}, {"team": "Austria", "p": 93.5}, {"team": "Suecia", "p": 92.8}, {"team": "Marruecos", "p": 91.9}, {"team": "España", "p": 90.3}, {"team": "Japón", "p": 88.6}, {"team": "P. Bajos", "p": 87.8}, {"team": "Suiza", "p": 84.5}, {"team": "Escocia", "p": 80.7}]}, "mark": {"type": "bar", "cornerRadiusEnd": 3}, "encoding": {"y": {"field": "team", "type": "nominal", "sort": "-x", "title": null, "axis": {"labelFontSize": 12, "labelColor": "#d4d4c8"}}, "x": {"field": "p", "type": "quantitative", "title": "Probabilidad de avanzar (%)", "scale": {"domain": [0, 100]}, "axis": {"labelColor": "#d4d4c8", "titleColor": "#d4d4c8", "gridColor": "#2a2a26"}}, "color": {"field": "p", "type": "quantitative", "scale": {"scheme": "tealblues"}, "legend": null}, "tooltip": [{"field": "team", "title": "Selección"}, {"field": "p", "title": "% avanza"}]}, "config": {"view": {"stroke": null}, "background": "transparent", "axis": {"domainColor": "#2a2a26"}}}
Lo que viene — predicciones día por día
Los 48 partidos restantes de la fase de grupos, en orden cronológico. Columnas: probabilidades L / E / V (local / empate / visitante, %), marcador más probable y el favorito del modelo. Sede neutral, así que "local" es solo el primer equipo del fixture.
18 jun
| Grupo | Partido | L / E / V | Marcador | Favorito |
|---|---|---|---|---|
| B | Canadá vs Qatar | 58 / 22 / 20 | 2-1 | Canadá |
| A | Rep. Checa vs Sudáfrica | 42 / 28 / 30 | 1-1 | Rep. Checa |
| A | México vs Corea del Sur | 41 / 31 / 28 | 1-1 | México |
| B | Suiza vs Bosnia | 65 / 22 / 14 | 2-1 | Suiza |
19 jun
| Grupo | Partido | L / E / V | Marcador | Favorito |
|---|---|---|---|---|
| C | Brasil vs Haití | 77 / 15 / 8 | 2-1 | Brasil |
| C | Escocia vs Marruecos | 16 / 29 / 54 | 1-1 | Marruecos |
| D | Turquía vs Paraguay | 39 / 27 / 34 | 1-1 | Turquía |
| D | EE.UU. vs Australia | 28 / 28 / 44 | 1-1 | Australia |
20 jun
| Grupo | Partido | L / E / V | Marcador | Favorito |
|---|---|---|---|---|
| E | Ecuador vs Curazao | 67 / 23 / 10 | 2-0 | Ecuador |
| E | Alemania vs Costa de Marfil | 54 / 25 / 21 | 2-1 | Alemania |
| F | P. Bajos vs Suecia | 57 / 20 / 22 | 2-1 | P. Bajos |
| F | Túnez vs Japón | 14 / 24 / 62 | 1-2 | Japón |
21 jun
| Grupo | Partido | L / E / V | Marcador | Favorito |
|---|---|---|---|---|
| G | Bélgica vs Irán | 46 / 26 / 28 | 1-1 | Bélgica |
| G | Nueva Zelanda vs Egipto | 32 / 30 / 38 | 1-1 | Egipto |
| H | España vs Arabia Saudí | 71 / 20 / 9 | 2-0 | España |
| H | Uruguay vs Cabo Verde | 53 / 31 / 15 | 1-0 | Uruguay |
22 jun
| Grupo | Partido | L / E / V | Marcador | Favorito |
|---|---|---|---|---|
| J | Argentina vs Austria | 63 / 23 / 14 | 2-1 | Argentina |
| I | Francia vs Irak | 69 / 20 / 11 | 2-1 | Francia |
| J | Jordania vs Argelia | 28 / 25 / 47 | 1-2 | Argelia |
| I | Noruega vs Senegal | 46 / 24 / 30 | 2-1 | Noruega |
23 jun
| Grupo | Partido | L / E / V | Marcador | Favorito |
|---|---|---|---|---|
| K | Colombia vs RD Congo | 56 / 28 / 16 | 1-1 | Colombia |
| L | Inglaterra vs Ghana | 69 / 20 / 11 | 2-1 | Inglaterra |
| L | Panamá vs Croacia | 21 / 23 / 56 | 1-2 | Croacia |
| K | Portugal vs Uzbekistán | 59 / 24 / 17 | 2-1 | Portugal |
24 jun
| Grupo | Partido | L / E / V | Marcador | Favorito |
|---|---|---|---|---|
| B | Bosnia vs Qatar | 33 / 26 / 41 | 1-1 | Qatar |
| A | Rep. Checa vs México | 17 / 28 / 55 | 1-1 | México |
| C | Marruecos vs Haití | 70 / 20 / 10 | 2-1 | Marruecos |
| C | Escocia vs Brasil | 15 / 24 / 62 | 1-2 | Brasil |
| A | Sudáfrica vs Corea del Sur | 20 / 26 / 54 | 1-2 | Corea del Sur |
| B | Suiza vs Canadá | 42 / 27 / 31 | 1-1 | Suiza |
25 jun
| Grupo | Partido | L / E / V | Marcador | Favorito |
|---|---|---|---|---|
| E | Curazao vs Costa de Marfil | 13 / 22 / 64 | 1-2 | Costa de Marfil |
| E | Ecuador vs Alemania | 26 / 29 / 45 | 1-1 | Alemania |
| F | Japón vs Suecia | 59 / 21 / 20 | 2-1 | Japón |
| D | Paraguay vs Australia | 20 / 30 / 50 | 1-1 | Australia |
| F | Túnez vs P. Bajos | 16 / 22 / 62 | 1-2 | P. Bajos |
| D | Turquía vs EE.UU. | 31 / 24 / 45 | 1-2 | EE.UU. |
26 jun
| Grupo | Partido | L / E / V | Marcador | Favorito |
|---|---|---|---|---|
| H | Cabo Verde vs Arabia Saudí | 31 / 36 / 33 | 1-1 | Empate |
| G | Egipto vs Irán | 32 / 31 / 37 | 1-1 | Irán |
| G | Nueva Zelanda vs Bélgica | 24 / 23 / 53 | 1-2 | Bélgica |
| I | Noruega vs Francia | 29 / 24 / 47 | 1-2 | Francia |
| I | Senegal vs Irak | 53 / 26 / 20 | 1-1 | Senegal |
| H | Uruguay vs España | 21 / 32 / 47 | 1-1 | España |
27 jun
| Grupo | Partido | L / E / V | Marcador | Favorito |
|---|---|---|---|---|
| J | Argelia vs Austria | 32 / 27 / 41 | 1-1 | Austria |
| K | Colombia vs Portugal | 38 / 26 / 37 | 1-1 | Colombia |
| L | Croacia vs Ghana | 53 / 25 / 22 | 2-1 | Croacia |
| K | RD Congo vs Uzbekistán | 33 / 36 / 31 | 1-1 | Empate |
| J | Jordania vs Argentina | 7 / 16 / 77 | 1-2 | Argentina |
| L | Panamá vs Inglaterra | 10 / 18 / 72 | 1-2 | Inglaterra |
Cómo se hizo
Pipeline reproducible vía el CLI del proyecto: captura automática de resultados (football-data.org), reentrenamiento del posterior bayesiano jerárquico (numpyro/NUTS, ~10 s) y simulación del torneo completo en PyTorch/CUDA sobre una RTX 4080 (500 mil torneos en pocos segundos). Cada simulación toma una muestra distinta del posterior, así que la incertidumbre del modelo viaja hasta el resultado final; los desempates de grupo siguen el reglamento FIFA y los empates en eliminatorias se resuelven por penales (50/50). Los partidos jugados quedan fijos a su marcador real.
Disclaimer
Esto es un ejercicio de modelado estadístico, no consejo de apuestas. Las probabilidades reflejan el modelo y los resultados ya ocurridos, no certezas. El fútbol, afortunadamente, se juega.