☕ Café

¿Qué tan acertadas han sido las encuestas y los pronósticos? Un repaso por 3 ciclos electorales.

Autor/a
Afiliación

Recetas Electorales

Análisis independiente

Fecha de publicación

25 de mayo de 2026

Fecha de última modificación

22 de junio de 2026

Las Recetas Electorales han producido pronósticos para las elecciones presidenciales colombianas de 2026, 2022 y 2018. Este artículo evalúa su precisión con métricas estadísticas del paquete yardstick.

En 2026, la primera vuelta registró el mayor error sistemático de las encuestadoras colombianas en tres ciclos. Abelardo de la Espriella (43.72%) superó a Cepeda (40.92%) y quedó más de 15 puntos por encima del promedio de encuestas. Paloma Valencia fue sobreestimada en más de 13 puntos. Los modelos bayesianos, alimentados con las mismas encuestas, cometieron el mismo error.

En 2022, todos fallamos. Rodolfo Hernández fue una gran sorpresa: ningún modelo lo proyectó por encima del 25%, y obtuvo el 27.8%. Las razones son múltiples: las encuestadoras lo subestimaron sistemáticamente durante toda la campaña; su campaña viral y de bajo presupuesto era invisible a los modelos basados en datos históricos; su momentum se aceleró en las últimas dos semanas, después de que los pronósticos ya se habían realizado; y los modelos de promedio ponderado de encuestas amortiguan exactamente los cambios bruscos que caracterizan una candidatura insurgente. Es un recordatorio de que los modelos bayesianos no son inmunes a errores de medición sistemáticos en los datos que los alimentan.

En 2018, los modelos bayesianos jerárquicos fueron buenos predictores. El campo era relativamente predecible: Duque y Petro como favoritos, Fajardo como incógnita moderada, así que los modelos Simple y Mixto registraron los MAE más bajos de ese ciclo. Validación positiva para el enfoque de pooling bayesiano con encuestas colombianas.

Cada pronóstico es un vector de porcentajes de votos por candidato. Lo comparamos con los resultados reales usando estas métricas:

Métrica Fórmula Interpretación
MAE \(\frac{1}{n}\sum\|y_i - \hat{y}_i\|\) Error promedio en puntos porcentuales
RMSE \(\sqrt{\frac{1}{n}\sum(y_i - \hat{y}_i)^2}\) Penaliza más los errores grandes
Sesgo \(\frac{1}{n}\sum(\hat{y}_i - y_i)\) Sobreestimación (+) o subestimación (−) sistemática
sMAPE \(\frac{2}{n}\sum\frac{\|y_i - \hat{y}_i\|}{\|y_i\| + \|\hat{y}_i\|}\) Error relativo simétrico (adimensional)
R² \(1 - \frac{\sum(y_i - \hat{y}_i)^2}{\sum(y_i - \bar{y})^2}\) Correlación entre pronóstico y resultado
Brier \(\frac{1}{K}\sum_{k=1}^{K}(p_k - o_k)^2\) Regla de puntuación propia; \(p_k, o_k\) son proporciones normalizadas
Winkler \((u-l) + \frac{2}{\alpha}\max(l-y,0) + \frac{2}{\alpha}\max(y-u,0)\) Puntaje de intervalo al 95%; combina amplitud y penalización por fallas

Para los pronósticos con intervalos también calculamos cobertura y el puntaje de Winkler, que penaliza simultáneamente los intervalos anchos y los que no capturan el resultado real.

R² es inestable con 4–5 observaciones (candidatos) por fuente. El Brier score normaliza los pronósticos a proporciones que sumen 1, lo que lo hace comparable entre fuentes aunque los totales pronosticados difieran. MAE y RMSE siguen siendo las métricas más directamente interpretables.

Elecciones 2026

Primera vuelta

Ver código
library(ggdist)

# Índice para junio 1 — igual que J_pred en el artículo Gaussiano
j_pred_fin     <- as.numeric(lubridate::ymd("2026-05-31") - min(encuestas_raw$fecha)) + 1L
cols_gauss_fin <- paste0("p_pred[", j_pred_fin, ",", 1:6, "]")

color_map_2026 <- tibble::tibble(
  cod        = cand_codes,
  color_cand = c(colores_2026[["ic"]], colores_2026[["adle"]],
                 colores_2026[["pv"]], colores_2026[["sf"]], colores_2026[["cl"]])
)

gauss_draws_fig <- arrow::read_parquet(
  gaussiano_path,
  col_select = dplyr::all_of(cols_gauss_fin)
) |>
  purrr::set_names(c(cand_codes, "ruido")) |>
  tidyr::pivot_longer(dplyr::everything(), names_to = "cod", values_to = "prop") |>
  dplyr::filter(cod != "ruido") |>
  dplyr::left_join(candidatos_2026_df, by = "cod") |>
  dplyr::left_join(color_map_2026,     by = "cod") |>
  dplyr::group_by(cod) |>
  dplyr::mutate(candidato_m = mean(prop)) |>
  dplyr::ungroup()

nombre_orden_2026 <- gauss_draws_fig |>
  dplyr::distinct(cod, candidato_m, nombre) |>
  dplyr::arrange(candidato_m) |>
  dplyr::pull(nombre)

# Probabilidad que el modelo asignaba al resultado real (que ADLE ganara la 1a vuelta)
gauss_wide_fig <- arrow::read_parquet(
  gaussiano_path, col_select = dplyr::all_of(cols_gauss_fin)
) |>
  purrr::set_names(c(cand_codes, "ruido"))
prob_adle_1v <- mean(
  gauss_wide_fig[["adle"]] == do.call(pmax, gauss_wide_fig[cand_codes])
)

gauss_draws_fig |>
  dplyr::mutate(nombre = factor(nombre, levels = nombre_orden_2026)) |>
  ggplot2::ggplot(ggplot2::aes(x = prop, y = nombre)) +
  ggdist::stat_dist_slabinterval(
    ggplot2::aes(
      fill      = color_cand,
      fill_ramp = ggplot2::after_stat(level)
    ),
    .width         = c(0.5, 0.8, 0.95, 0.99),
    interval_alpha = 0.95,
    show.legend    = c(fill = FALSE, fill_ramp = TRUE, size = FALSE)
  ) +
  ggdist::stat_pointinterval(
    ggplot2::aes(
      label = scales::percent(candidato_m, accuracy = 0.1),
      color = oscurecer(color_cand)
    ),
    geom       = "label",
    .width     = 0,
    vjust      = 2.1,
    size       = 2.7,
    fontface   = "bold",
    fill       = "white",
    label.size = 0.4
  ) +
  {
    res_fig <- resultados_2026 |>
      dplyr::rename(nombre = candidato) |>
      dplyr::left_join(
        dplyr::left_join(candidatos_2026_df, color_map_2026, by = "cod") |>
          dplyr::select(nombre, color_cand),
        by = "nombre"
      ) |>
      dplyr::mutate(
        nombre    = factor(nombre, levels = nombre_orden_2026),
        y_num     = as.numeric(factor(nombre, levels = nombre_orden_2026)),
        resultado = resultado / 100
      )
    list(
      ggplot2::geom_segment(
        data = res_fig,
        ggplot2::aes(
          x = resultado, xend = resultado,
          y = y_num - 0.4, yend = y_num + 0.4,
          color = color_cand
        ),
        linewidth = 2.5, inherit.aes = FALSE
      ),
      ggplot2::geom_label(
        data = res_fig,
        ggplot2::aes(
          x     = resultado,
          y     = y_num + 0.42,
          label = scales::percent(resultado, accuracy = 0.1),
          fill  = color_cand
        ),
        color         = "white",
        size          = 2.7,
        fontface      = "bold",
        vjust         = 0,
        label.size    = 0,
        label.padding = ggplot2::unit(0.2, "lines"),
        inherit.aes   = FALSE
      ),
      ggplot2::scale_color_identity(guide = "none")
    )
  } +
  ggplot2::scale_x_continuous(
    labels = scales::percent_format(accuracy = 1),
    expand = expansion(mult = c(0.05, 0.15))
  ) +
  ggplot2::scale_fill_identity(na.translate = FALSE) +
  ggdist::scale_fill_ramp_discrete(
    name   = "Intervalo creíble",
    range  = c(0.25, 1),
    breaks = c(0.5, 0.8, 0.95, 0.99),
    labels = c("50%", "80%", "95%", "99%"),
    na.translate = FALSE
  ) +
  ggplot2::labs(
    x        = "Distribución posterior, % votos primera vuelta 2026 (Gaussiano, 31 mayo)",
    y        = NULL,
    title    = "Modelo Gaussiano vs resultado — primera vuelta 2026",
    subtitle = paste0(
      "El modelo asignaba ", round(100 * prob_adle_1v),
      "% de probabilidad a que ganara Abelardo de la Espriella (lo que ocurrió)"
    ),
    caption  = "Intervalos creíbles: 50%, 80%, 95%, 99%. Línea vertical: resultado real 31 de mayo."
  ) +
  theme_recetas(base_size = 16) +
  ggplot2::theme(
    panel.grid.major.y = ggplot2::element_blank(),
    panel.grid.minor   = ggplot2::element_blank(),
    legend.position    = "bottom"
  )
1
Calculamos el índice temporal del 31 de mayo y los nombres de columna p_pred[j,k] del modelo Gaussiano para esa fecha.
2
Asociamos a cada candidato su color de marca.
3
Leemos del parquet del Gaussiano las muestras posteriores de esa fecha, las pasamos a formato largo y calculamos la media posterior por candidato.
4
Ordenamos los candidatos por su media posterior.
5
Construimos el gráfico base (proporción posterior en X, candidato en Y).
6
Capa principal: distribuciones posteriores como slabs con intervalos creíbles (50/80/95/99%).
7
Etiqueta con la media posterior de cada candidato.
8
Bloque que superpone el resultado real (segmento vertical + etiqueta) sobre cada candidato.
9
Escalas: eje X en porcentaje con margen para etiquetas.
10
Títulos y nota de fuente.
11
Tema de marca sin rejilla horizontal y leyenda abajo.
Figura 1: Distribución posterior del modelo Gaussiano — primera vuelta 2026
Ver código
calcular_metricas(datos_2026) |>
  tabla_metricas(titulo = "Pronósticos 2026")
1
Calculamos las métricas de precisión (error frente al resultado real) de los pronósticos de 2026 y las formateamos como tabla.
Tabla 1: Métricas de precisión — Primera vuelta 2026
Pronósticos 2026
Fuente MAE RMSE sMAPE R² Sesgo Brier Cobertura Amplitud Winkler
La Silla Vacía 6.01 8.03 47.9% 0.849 -1.15 0.00623 NA NA NA
Gaussiano 7.08 9.91 53.7% 0.752 -1.81 0.00956 40% 9.4 142.4
Encuestas 7.44 10.33 55.8% 0.729 -2.07 0.01038 NA NA NA
Cazuela 7.72 11.15 61.1% 0.715 -3.78 0.01082 20% 4.6 222.2
MAE/RMSE: puntos porcentuales (p.p.), menor es mejor.  Sesgo: sobreestimación (+) o subestimación (−) promedio.  sMAPE: error porcentual simétrico, menor es mejor.  R²: 1 = pronóstico perfecto.  Brier: regla de puntuación propia sobre proporciones normalizadas, menor es mejor.  Winkler: puntaje de intervalo al 95%, menor es mejor.  Cobertura: % candidatos dentro del intervalo predicho.  Amplitud: ancho promedio del intervalo (p.p.).

Encuestadoras

El resultado de la primera vuelta de 2026 registró el mayor error sistemático de las encuestadoras colombianas en tres ciclos. Abelardo de la Espriella obtuvo 43.72% cuando ninguna casa lo proyectaba por encima del 35%. Paloma Valencia fue sobreestimada en más de 13 puntos: las encuestas le daban entre 16% y 22%, y obtuvo 6.92%. La tabla compara la última encuesta de cada casa con los modelos de Recetas Electorales.

Ver código
calcular_metricas(datos_2026_todos) |>
  tabla_metricas(titulo = "Encuestadoras y modelos — 2026")
1
Calculamos el ranking de precisión combinando encuestadoras y modelos de 2026 en una sola tabla.
Tabla 2: Ranking de precisión — encuestadoras y modelos, primera vuelta 2026
Encuestadoras y modelos — 2026
Fuente MAE RMSE sMAPE R² Sesgo Brier Cobertura Amplitud Winkler
AtlasIntel 3.65 4.78 24% 0.960 -0.79 0.00202 NA NA NA
Invamer 5.20 6.57 48.7% 0.882 -0.39 0.00453 NA NA NA
La Silla Vacía 6.01 8.03 47.9% 0.849 -1.15 0.00623 NA NA NA
Gaussiano 7.08 9.91 53.7% 0.752 -1.81 0.00956 40% 9.4 142.4
Guarumo 7.29 9.98 46.4% 0.740 -1.15 0.01012 NA NA NA
CELAG 7.40 11.88 50.5% 0.637 -3.39 0.01454 NA NA NA
Encuestas 7.44 10.33 55.8% 0.729 -2.07 0.01038 NA NA NA
CNC 7.49 11.39 60.5% 0.720 -4.59 0.01074 NA NA NA
GAD3 7.61 10.83 64% 0.767 -4.35 0.00887 NA NA NA
Cazuela 7.72 11.15 61.1% 0.715 -3.78 0.01082 20% 4.6 222.2
Tempo 8.93 12.74 49% 0.547 -0.83 0.01737 NA NA NA
Genesis Crea 10.09 13.22 70.4% 0.519 -1.63 0.01827 NA NA NA
Corp. Miguel Maldonado Manjarrez 10.85 14.67 68.4% 0.409 -1.51 0.02329 NA NA NA
MAE/RMSE: puntos porcentuales (p.p.), menor es mejor.  Sesgo: sobreestimación (+) o subestimación (−) promedio.  sMAPE: error porcentual simétrico, menor es mejor.  R²: 1 = pronóstico perfecto.  Brier: regla de puntuación propia sobre proporciones normalizadas, menor es mejor.  Winkler: puntaje de intervalo al 95%, menor es mejor.  Cobertura: % candidatos dentro del intervalo predicho.  Amplitud: ancho promedio del intervalo (p.p.).
Ver código
plot_cafe(
  encuestadoras_2026_largo,
  resultados_2026,
  candidatos_2026_df$nombre,
  "Última encuesta vs resultado — encuestadoras 2026",
  colores_2026_nombres
)
1
Graficamos la última encuesta de cada casa frente al resultado real con el helper plot_cafe().
Figura 2: Última encuesta por casa vs resultado real — primera vuelta 2026

Segunda vuelta

ImportanteResultado oficial — 21 de junio de 2026

Abelardo de la Espriella ganó la segunda vuelta con 49.66% de los votos frente a 48.70% de Iván Cepeda (voto en blanco: 1.63%). La diferencia fue de solo 0.96 puntos.

La tabla y la gráfica comparan la última encuesta de cada casa en la ventana de segunda vuelta (desde el 31 de mayo), su media, y los modelos del Postre, frente al resultado oficial. Todos los pronósticos se expresan como la share entre los dos finalistas (ADLE + IC = 100%). La encuesta de CELAG del 14 de junio se muestra como referencia, pero se excluye de la Media encuestas y de todos los modelos.

Ver código
calcular_metricas_2v(datos_2026_2v) |>
  tabla_metricas_2v(titulo = "Segunda vuelta 2026")
1
Calculamos las métricas de precisión de la segunda vuelta (MAE, RMSE, sesgo, cobertura, Winkler) frente al resultado oficial.
Tabla 3: Métricas de precisión — Segunda vuelta 2026
Segunda vuelta 2026
Fuente MAE RMSE Sesgo Cobertura Amplitud Winkler
CELAG 1.17 1.17 0 NA NA NA
CNC 1.60 1.60 0 NA NA NA
Postre distancia 2.51 2.51 0 100% 6.0 6.0
Postre logístico 2.58 2.58 0 100% 6.3 6.3
Media encuestas 2.89 2.89 0 NA NA NA
CB Global Data 2.90 2.90 0 NA NA NA
Meta-análisis brms 3.01 3.01 0 0% 3.5 50.8
Ajiaco2 (2da vuelta) 3.12 3.12 0 0% 5.2 24.4
Guarumo 3.41 3.41 0 NA NA NA
AtlasIntel 3.64 3.64 0 NA NA NA
MAE/RMSE: puntos porcentuales (p.p.), menor es mejor.  Sesgo: sobreestimación (+) o subestimación (−) promedio.  R², sMAPE y Brier omitidos (solo 2 candidatos por fuente).  Winkler: puntaje de intervalo al 95%, menor es mejor.  Cobertura: % candidatos dentro del intervalo predicho.  Amplitud: ancho promedio del intervalo (p.p.).
Ver código
plot_cafe(
  datos_2026_2v,
  resultados_2026_2v,
  c("Abelardo de la Espriella", "Iván Cepeda"),
  "Pronósticos vs resultado — Segunda vuelta 2026",
  colores_2026_nombres
)
1
Graficamos la share pronosticada de cada finalista por fuente frente al resultado real (línea punteada).
Figura 3: Pronósticos vs resultado real — Segunda vuelta 2026

Elecciones 2022

Primera vuelta

Cuatro candidatos, ocho pronósticos. Rodolfo Hernández fue la gran sorpresa: ningún modelo lo proyectó por encima del 25% y obtuvo 27.8%.

Ver código
calcular_metricas(datos_2022) |>
  tabla_metricas(titulo = "Pronósticos 2022")
1
Calculamos las métricas de precisión de los pronósticos de la primera vuelta de 2022 y las formateamos como tabla.
Tabla 4: Métricas de precisión — Primera vuelta 2022
Pronósticos 2022
Fuente MAE RMSE sMAPE R² Sesgo Brier Cobertura Amplitud Winkler
Encuestas 2.49 2.95 21.8% 0.960 0.26 0.00099 100% 21.2 21.2
La Silla Vacia 2.72 4.01 14.9% 0.918 -1.61 0.00154 NA NA NA
@calc_electoral 2.90 3.36 16.8% 0.936 0.14 0.00122 100% 14.2 14.2
@JorgeGalindo El Pais 3.78 5.17 23% 0.852 -1.17 0.00298 NA NA NA
@PoliticaConDato 5.01 5.96 35% 0.785 0.07 0.00390 50% 8.1 49.0
Ajiaco 5.47 7.43 35.4% 0.735 -3.36 0.00501 75% 13.2 81.4
@ColombiaRisk 6.99 8.52 41.9% 0.734 -5.31 0.00542 NA NA NA
Mixto 2022 7.01 9.35 46% 0.567 -3.78 0.00910 50% 7.0 185.4
Simple 2022 7.34 9.48 48.2% 0.541 -3.46 0.00952 50% 6.0 196.0
MAE/RMSE: puntos porcentuales (p.p.), menor es mejor.  Sesgo: sobreestimación (+) o subestimación (−) promedio.  sMAPE: error porcentual simétrico, menor es mejor.  R²: 1 = pronóstico perfecto.  Brier: regla de puntuación propia sobre proporciones normalizadas, menor es mejor.  Winkler: puntaje de intervalo al 95%, menor es mejor.  Cobertura: % candidatos dentro del intervalo predicho.  Amplitud: ancho promedio del intervalo (p.p.).
Ver código
plot_cafe(datos_2022, resultados_2022, candidatos_2022,
          "Pronósticos vs resultado — 2022", colores_2022)
1
Graficamos cada pronóstico de 2022 frente al resultado real con el helper plot_cafe().
Figura 4: Pronósticos vs resultado real — Primera vuelta 2022

Encuestadoras

El error de 2022 fue Rodolfo Hernández: obtuvo 27.82% cuando ninguna encuestadora lo proyectaba por encima del 18%. Petro y Gutierrez fueron estimados con mayor precisión. Fajardo fue sobreestimado por casi todas las casas.

Ver código
calcular_metricas(datos_2022_todos) |>
  tabla_metricas(titulo = "Encuestadoras y modelos — 2022")
1
Calculamos el ranking de precisión combinando encuestadoras y modelos de 2022 en una sola tabla.
Tabla 5: Ranking de precisión — encuestadoras y modelos, primera vuelta 2022
Encuestadoras y modelos — 2022
Fuente MAE RMSE sMAPE R² Sesgo Brier Cobertura Amplitud Winkler
La Silla Vacia 2.72 4.01 14.9% 0.918 -1.61 0.00154 NA NA NA
@calc_electoral 2.90 3.36 16.8% 0.936 0.14 0.00122 100% 14.2 14.2
AtlasIntel 3.58 4.25 27.7% 0.897 0.37 0.00201 NA NA NA
@JorgeGalindo El Pais 3.78 5.17 23% 0.852 -1.17 0.00298 NA NA NA
CNC 3.93 5.01 16% 0.951 -3.93 0.00098 NA NA NA
Guarumo 4.20 5.28 16.6% 0.837 -0.53 0.00310 NA NA NA
CELAG 4.25 4.90 19.1% 0.895 -1.23 0.00292 NA NA NA
@PoliticaConDato 5.01 5.96 35% 0.785 0.07 0.00390 50% 8.1 49.0
Mosqueteros 5.22 6.65 30.6% 0.785 -1.38 0.00521 NA NA NA
YanHaas 5.37 8.15 35.8% 0.707 -3.86 0.00725 NA NA NA
Ajiaco 5.47 7.43 35.4% 0.735 -3.36 0.00501 75% 13.2 81.4
Invamer 5.78 7.46 33.1% 0.729 -1.18 0.00652 NA NA NA
MassiveCaller 5.85 7.91 30.9% 0.698 -3.28 0.00670 NA NA NA
TYSE 6.07 8.74 35.9% 0.701 -5.11 0.00731 NA NA NA
@ColombiaRisk 6.99 8.52 41.9% 0.734 -5.31 0.00542 NA NA NA
Mixto 2022 7.01 9.35 46% 0.567 -3.78 0.00910 50% 7.0 185.4
Simple 2022 7.34 9.48 48.2% 0.541 -3.46 0.00952 50% 6.0 196.0
MAE/RMSE: puntos porcentuales (p.p.), menor es mejor.  Sesgo: sobreestimación (+) o subestimación (−) promedio.  sMAPE: error porcentual simétrico, menor es mejor.  R²: 1 = pronóstico perfecto.  Brier: regla de puntuación propia sobre proporciones normalizadas, menor es mejor.  Winkler: puntaje de intervalo al 95%, menor es mejor.  Cobertura: % candidatos dentro del intervalo predicho.  Amplitud: ancho promedio del intervalo (p.p.).
Ver código
plot_cafe(
  encuestadoras_2022_largo,
  resultados_2022,
  candidatos_2022_df$nombre,
  "Última encuesta vs resultado — encuestadoras 2022",
  colores_2022
)
1
Graficamos la última encuesta de cada casa de 2022 frente al resultado real con plot_cafe().
Figura 5: Última encuesta por casa vs resultado real — primera vuelta 2022

Segunda vuelta

Dos candidatos, encuestas profundamente divididas: las telefónicas favorecían a Hernández, las presenciales a Petro. El promedio general no capturó bien la diferencia. El Postre 2022 —modelo logístico jerárquico— estimó a Petro en 45.2% y a Hernández en 47.4%, subestimando a Petro, que ganó con 50.44%.

Ver código
calcular_metricas_2v(datos_2022_2v) |>
  tabla_metricas_2v(titulo = "Segunda vuelta 2022")
1
Calculamos las métricas de precisión específicas de la segunda vuelta (dos candidatos) de 2022.
Tabla 6: Métricas de precisión — Segunda vuelta 2022
Segunda vuelta 2022
Fuente MAE RMSE Sesgo Cobertura Amplitud Winkler
GAD3 1.96 2.40 -1.38 NA NA NA
Invamer 2.06 2.38 -1.17 NA NA NA
Guarumo 2.41 2.86 -1.52 NA NA NA
Postre 2022 2.66 3.71 -2.57 50% 14.5 31.2
Media encuestas 2.80 3.15 -2.80 NA NA NA
AtlasIntel 2.91 2.92 -0.02 NA NA NA
MassiveCaller 3.96 4.12 1.12 NA NA NA
Mosqueteros 4.62 5.03 -4.62 NA NA NA
CNC 5.93 5.94 -5.93 NA NA NA
YanHaas 8.88 9.52 -8.88 NA NA NA
MAE/RMSE: puntos porcentuales (p.p.), menor es mejor.  Sesgo: sobreestimación (+) o subestimación (−) promedio.  R², sMAPE y Brier omitidos (solo 2 candidatos por fuente).  Winkler: puntaje de intervalo al 95%, menor es mejor.  Cobertura: % candidatos dentro del intervalo predicho.  Amplitud: ancho promedio del intervalo (p.p.).
Ver código
plot_cafe(
  datos_2022_2v, resultados_2022_2v,
  c("Gustavo Petro", "Rodolfo Hernández"),
  "Pronósticos vs resultado — Segunda vuelta 2022",
  colores_2022
)
1
Graficamos los pronósticos de segunda vuelta 2022 frente al resultado real con plot_cafe().
Figura 6: Pronósticos vs resultado real — Segunda vuelta 2022

Elecciones 2018

Primera vuelta

Cinco candidatos, seis pronósticos. Las recetas bayesianas Simple y Mixto fueron las más precisas; todos fallaron en anticipar la votación de Sergio Fajardo.

Ver código
calcular_metricas(datos_2018) |>
  tabla_metricas(titulo = "Pronósticos 2018")
1
Calculamos las métricas de precisión de los pronósticos de la primera vuelta de 2018 y las formateamos como tabla.
Tabla 7: Métricas de precisión — Primera vuelta 2018
Pronósticos 2018
Fuente MAE RMSE sMAPE R² Sesgo Brier Cobertura Amplitud Winkler
Simple 2.84 4.71 21.6% 0.895 -1.85 0.00229 60% 5.1 72.0
Mixto 2.87 4.78 21.8% 0.894 -2.01 0.00230 80% 6.2 65.8
El Pais 3.23 4.06 25.3% 0.913 -0.80 0.00163 NA NA NA
18 Encuestas 3.29 5.04 23.4% 0.886 -2.26 0.00227 NA NA NA
Cifras y Conceptos 6.44 7.49 47% 0.691 -0.40 0.00588 0% 2.6 209.0
ANIF 9.84 11.14 64.3% 0.311 -0.63 0.01315 NA NA NA
MAE/RMSE: puntos porcentuales (p.p.), menor es mejor.  Sesgo: sobreestimación (+) o subestimación (−) promedio.  sMAPE: error porcentual simétrico, menor es mejor.  R²: 1 = pronóstico perfecto.  Brier: regla de puntuación propia sobre proporciones normalizadas, menor es mejor.  Winkler: puntaje de intervalo al 95%, menor es mejor.  Cobertura: % candidatos dentro del intervalo predicho.  Amplitud: ancho promedio del intervalo (p.p.).
Ver código
plot_cafe(datos_2018, resultados_2018, candidatos_2018,
          "Pronósticos vs resultado — 2018", colores_2018)
1
Graficamos cada pronóstico de 2018 frente al resultado real con el helper plot_cafe().
Figura 7: Pronósticos vs resultado real — Primera vuelta 2018

Encuestadoras

El error más notable de 2018 fue la subestimación de Sergio Fajardo, que obtuvo 23.73% cuando la mayoría de casas lo proyectaba entre 10% y 17%. Duque y Petro fueron estimados con mayor precisión; Vargas Lleras fue sobreestimado por varias casas.

Ver código
calcular_metricas(datos_2018_todos) |>
  tabla_metricas(titulo = "Encuestadoras y modelos — 2018")
1
Calculamos el ranking de precisión combinando encuestadoras y modelos de 2018 en una sola tabla.
Tabla 8: Ranking de precisión — encuestadoras y modelos, primera vuelta 2018
Encuestadoras y modelos — 2018
Fuente MAE RMSE sMAPE R² Sesgo Brier Cobertura Amplitud Winkler
CNC 2.03 3.18 20.9% 0.954 -1.26 0.00086 NA NA NA
Guarumo 2.82 3.92 19.6% 0.926 -1.24 0.00139 NA NA NA
Simple 2.84 4.71 21.6% 0.895 -1.85 0.00229 60% 5.1 72.0
Mixto 2.87 4.78 21.8% 0.894 -2.01 0.00230 80% 6.2 65.8
Invamer 3.01 4.02 15.4% 0.928 -0.30 0.00179 NA NA NA
18 Encuestas 3.29 5.04 23.4% 0.886 -2.26 0.00227 NA NA NA
YanHaas 3.40 4.80 24.6% 0.912 -2.66 0.00181 NA NA NA
Datexco 3.66 4.77 17.5% 0.884 -0.96 0.00251 NA NA NA
CELAG 4.30 5.37 25% 0.862 -2.08 0.00291 NA NA NA
Cifras & Conceptos 4.90 5.79 34.6% 0.859 -2.16 0.00269 NA NA NA
MAE/RMSE: puntos porcentuales (p.p.), menor es mejor.  Sesgo: sobreestimación (+) o subestimación (−) promedio.  sMAPE: error porcentual simétrico, menor es mejor.  R²: 1 = pronóstico perfecto.  Brier: regla de puntuación propia sobre proporciones normalizadas, menor es mejor.  Winkler: puntaje de intervalo al 95%, menor es mejor.  Cobertura: % candidatos dentro del intervalo predicho.  Amplitud: ancho promedio del intervalo (p.p.).
Ver código
plot_cafe(
  encuestadoras_2018_largo,
  resultados_2018,
  candidatos_2018_df$nombre,
  "Última encuesta vs resultado — encuestadoras 2018",
  colores_2018
)
1
Graficamos la última encuesta de cada casa de 2018 frente al resultado real con plot_cafe().
Figura 8: Última encuesta por casa vs resultado real — primera vuelta 2018

Segunda vuelta

Duque superó casi todas las encuestas; Petro fue subestimado por la mayoría. El Plato Mixto, con su intervalo demasiado grande de 46–57%, cubrió el resultado de Duque (53.98%) aunque el punto central quedó corto.

Ver código
calcular_metricas_2v(datos_2018_2v) |>
  tabla_metricas_2v(titulo = "Segunda vuelta 2018")
1
Calculamos las métricas de precisión específicas de la segunda vuelta (dos candidatos) de 2018.
Tabla 9: Métricas de precisión — Segunda vuelta 2018
Segunda vuelta 2018
Fuente MAE RMSE Sesgo Cobertura Amplitud Winkler
CNC 3.39 3.42 -3.39 NA NA NA
Guarumo 3.64 4.24 -3.64 NA NA NA
Invamer 3.87 3.92 -0.64 NA NA NA
Plato Mixto 3.89 4.00 -3.89 50% 9 25.2
Media encuestas 4.05 4.13 -4.05 NA NA NA
Datexco 4.69 5.62 -4.69 NA NA NA
YanHaas 4.89 5.70 -4.89 NA NA NA
Cifras & Conceptos 7.05 7.23 -7.05 NA NA NA
MAE/RMSE: puntos porcentuales (p.p.), menor es mejor.  Sesgo: sobreestimación (+) o subestimación (−) promedio.  R², sMAPE y Brier omitidos (solo 2 candidatos por fuente).  Winkler: puntaje de intervalo al 95%, menor es mejor.  Cobertura: % candidatos dentro del intervalo predicho.  Amplitud: ancho promedio del intervalo (p.p.).
Ver código
plot_cafe(
  datos_2018_2v, resultados_2018_2v,
  c("Iván Duque", "Gustavo Petro"),
  "Pronósticos vs resultado — Segunda vuelta 2018",
  colores_2018
)
1
Graficamos los pronósticos de segunda vuelta 2018 frente al resultado real con plot_cafe().
Figura 9: Pronósticos vs resultado real — Segunda vuelta 2018

Comparación entre elecciones

Ver código
tbl_data <- dplyr::bind_rows(
  datos_2018_todos, datos_2022_todos, datos_2026_todos
) |>
  dplyr::group_by(eleccion, fuente) |>
  yardstick::mae(truth = resultado, estimate = pronostico) |>
  dplyr::arrange(eleccion, .estimate) |>
  dplyr::group_by(eleccion) |>
  dplyr::mutate(
    rango   = dplyr::row_number(),
    mae_fmt = round(.estimate, 2)
  ) |>
  dplyr::ungroup()

grupos <- tbl_data |>
  dplyr::group_by(eleccion) |>
  dplyr::summarise(n = dplyr::n(), .groups = "drop") |>
  dplyr::mutate(end = cumsum(n), start = end - n + 1)

tbl_comp <- tbl_data |>
  dplyr::select(Elección = eleccion, Fuente = fuente, MAE = mae_fmt, `#` = rango) |>
  knitr::kable(format = "html", caption = "Ranking por MAE") |>
  kableExtra::kable_styling(full_width = TRUE, font_size = 13) |>
  kableExtra::row_spec(0, bold = TRUE, background = "#FF4900", color = "white")

for (i in seq_len(nrow(grupos))) {
  tbl_comp <- kableExtra::group_rows(tbl_comp, grupos$eleccion[i], grupos$start[i], grupos$end[i])
}

knitr::asis_output(paste0(
  as.character(tbl_comp),
  '<div style="font-size:0.82em;margin-top:4px;padding:4px 0;border-top:1px solid #e0e0e0;line-height:1.7;">',
  'MAE: error absoluto promedio en puntos porcentuales, menor es mejor.',
  '</div>'
))
1
Combinamos los pronósticos de las tres elecciones, calculamos el MAE por fuente y elección, y los rankeamos.
2
Calculamos el tamaño de cada grupo (elección) para agrupar las filas de la tabla.
3
Construimos la tabla HTML con estilo de marca.
4
Insertamos los encabezados de grupo (una sección por elección) recorriendo grupos.
5
Emitimos la tabla con una nota explicativa del MAE al pie.
Tabla 10: Mejores pronósticos por elección — MAE (p.p.)
Ranking por MAE
Elección Fuente MAE #
2018
2018 CNC 2.03 1
2018 Guarumo 2.82 2
2018 Simple 2.84 3
2018 Mixto 2.87 4
2018 Invamer 3.01 5
2018 18 Encuestas 3.29 6
2018 YanHaas 3.40 7
2018 Datexco 3.66 8
2018 CELAG 4.30 9
2018 Cifras & Conceptos 4.90 10
2022
2022 La Silla Vacia 2.72 1
2022 @calc_electoral 2.90 2
2022 AtlasIntel 3.58 3
2022 @JorgeGalindo El Pais 3.78 4
2022 CNC 3.93 5
2022 Guarumo 4.20 6
2022 CELAG 4.25 7
2022 @PoliticaConDato 5.01 8
2022 Mosqueteros 5.22 9
2022 YanHaas 5.37 10
2022 Ajiaco 5.47 11
2022 Invamer 5.78 12
2022 MassiveCaller 5.85 13
2022 TYSE 6.07 14
2022 @ColombiaRisk 6.99 15
2022 Mixto 2022 7.01 16
2022 Simple 2022 7.34 17
2026
2026 AtlasIntel 3.65 1
2026 Invamer 5.20 2
2026 La Silla Vacía 6.01 3
2026 Gaussiano 7.08 4
2026 Guarumo 7.29 5
2026 CELAG 7.40 6
2026 Encuestas 7.44 7
2026 CNC 7.49 8
2026 GAD3 7.61 9
2026 Cazuela 7.72 10
2026 Tempo 8.93 11
2026 Genesis Crea 10.09 12
2026 Corp. Miguel Maldonado Manjarrez 10.85 13
MAE: error absoluto promedio en puntos porcentuales, menor es mejor.
Ver código
err_comp |>
  dplyr::filter(vuelta == "1ra vuelta") |>
  plot_error_comp("Error por pronóstico — primera vuelta")
1
Filtramos la primera vuelta y graficamos el error de cada pronóstico, con un panel por elección.
Figura 10: Error absoluto por pronóstico — primeras vueltas (2018, 2022, 2026)
Ver código
err_comp |>
  dplyr::filter(vuelta == "2da vuelta") |>
  plot_error_comp("Error por pronóstico — segunda vuelta")
1
Filtramos la segunda vuelta y graficamos el error de cada pronóstico, con un panel por elección.
Figura 11: Error absoluto por pronóstico — segundas vueltas (2018, 2022, 2026)

Cómo citar

BibTeX
@online{recetas_electorales,
  author = {{Recetas Electorales}},
  url = {https://recetas-electorales.netlify.app/elecciones/2026-colombia/2026-05-30-cafe/2026-cafe.html},
  langid = {es}
}
Por favor, cita este trabajo como:
Recetas Electorales. n.d. https://recetas-electorales.netlify.app/elecciones/2026-colombia/2026-05-30-cafe/2026-cafe.html.