Hoy, 5 de marzo de 2026, el presidente Daniel Noboa afirmó que “9 de cada 10 homicidios son personas que tienen antecedentes penales”. Esta afirmación no es menor porque se formula en un contexto de conflicto armado interno y, de ese modo, puede operar como justificación de una política contra el crimen organizado que trata al homicidio como un fenómeno social circunscrito casi exclusivamente al mundo criminal. Si esa premisa es falsa (o exagerada), entonces la política que se desprende de ella también lo es.
Este ejercicio, por tanto, intenta responder una pregunta simple: ¿cuán razonable es ese 90%?
Si nos limitamos a la base de datos pública, la respuesta directa es llanamente imposible. En los registros oficiales de homicidios para 2024, 2025 y (enero de) 2026, la variable que codifica antecedentes penales aparece sistemáticamente vacía: el 100% de los casos figura como “SIN_DATO”, una ausencia que presumiblemente será corregida o actualizada a posteriori, pero demasiado tarde para el análisis de coyuntura.
Ejemplo de registros de 2025.
Ante la restricción de datos, la alternativa inmediata es la estimación indirecta: si no es posible observar directamente si una víctima tenía antecedentes penales, podemos tratar de estimar qué probabilidad le asignaríamos en función de su perfil (edad, sexo, ocupación, hora, lugar y provincia del homicidio) tomando como referencia lo que esas mismas variables predecían en 2023, el año más reciente en que dicha variable sí se encuentra codificada. En ese año, el 21,07% de las víctimas de homicidio registró antecedentes penales (1.738 casos del universo de 8.248 casos).
En concreto, podemos entrenar una regresión logística binomial con los datos de 2023 (n = 7.791 casos, excluyendo datos faltantes), usando seis covariables categóricas para predecir la probabilidad de que una víctima registrase antecedentes penales:
Variable
Niveles
Profesión agrupada
11 niveles (10 más frecuentes + «Otras»)
Rango de edad
5 niveles (0–17, 18–29, 30–44, 45–64, 65+)
Sexo
2 niveles (Hombre, Mujer)
Hora del homicidio
4 niveles (0-5am, 6-11am, 12-17pm, 18-23pm)
Área del homicidio
2 niveles (Urbano, Rural)
Lugar del homicidio
11 niveles (10 más frecuentes + «Otros»)
Provincia del homicidio
11 niveles (10 más frecuentes + «Otras»)
Formalmente, este modelo tiene la siguiente forma:
$$\log\left(\frac{P(Y_i=1 \mid x_i)}{1-P(Y_i=1 \mid x_i)}\right) = \beta_0 + \beta_{\text{prof}(i)} + \beta_{\text{edad}(i)} + \beta_{\text{sexo}(i)} + \beta_{\text{hora}(i)} + \beta_{\text{área}(i)} + \beta_{\text{lugar}(i)} + \beta_{\text{prov}},$$
donde cada término representa el efecto estimado de la categoría correspondiente sobre la probabilidad de tener antecedentes penales.
A partir del modelo entrenado con datos de 2023, se calcula una probabilidad predicha para cada víctima de 2024 y 2025, y luego se promedia para obtener la proporción estimada de cada año. El predictor lineal para cada individuo puede escribirse como:
$$\hat{\eta}_i = \hat{\beta}_{0,2023} + \sum_{k=1}^{10} \hat{\beta}_{k,2023} \cdot I(\text{prof}_i = k) + \sum_{l=1}^{5} \hat{\gamma}_{l,2023} \cdot I(\text{edad}_i = l) + \cdots,$$
donde la probabilidad predicha para una víctima de 2024 o 2025 es:
$$\hat{P}(Y_i = 1 \mid x_i) = \frac{\exp(\hat{\eta}_{i,2023})}{1 + \exp(\hat{\eta}_{i,2023})}$$
Y la proporción estimada para el año \(t\in\{2024, 2025\}\) resulta del promedio de esas probabilidades individuales:
$$\hat{p}_t = \frac{1}{n_t} \sum_{i=1}^{n_t} \hat{P}_{2023}(Y_i = 1 \mid x_i)$$
Finalmente, para cuantificar la incertidumbre en estas estimaciones, utilicé un bootstrap con 1000 réplicas: en cada réplica \(b\), se reentrenó el modelo con una muestra aleatoria del conjunto de 2023 para recalcular \(\hat{p}_t^{(b)}\). Los intervalos de confianza al 95 % corresponden a los percentiles 2,5 y 97,5 de esa distribución empírica, sin asumir ninguna distribución específica:
$$IC_{95\%}(\hat{p}_t) = \left[ \hat{p}_t^{(0{,}025)},\; \hat{p}_t^{(0{,}975)} \right]$$
Los resultados son los siguientes:
Año
Casos
Proporción (e)
IC 95 %
2024
6.880
22,19%
[21,37% – 23,08%]
2025
8.933
21,88%
[21,05% – 22,75%]
Enero 2026
732
21,40%
[20,54% – 22,29%]
En términos absolutos, esto equivale a aproximadamente 1.527 víctimas con antecedentes en 2024 (IC: 1.470–1.588); 1.955 en 2025 (IC: 1.881–2.033); y, 157 en enero de 2026 (IC: 150–163).
Esta estimación depende de manera crítica de que la relación entre el perfil de las víctimas y la probabilidad de tener antecedentes penales (observada en 2023) se mantenga relativamente estable en el tiempo. Ante la ausencia de datos más recientes, asumir dicha estabilidad es quizás el único punto de partida razonable, sobre todo si se considera que los perfiles poblacionales no se alteran drásticamente de un año a otro.
Dicho de otro modo, lo que esta estimación captura es lo que esperaríamos en la distribución de antecedentes penales en las víctimas de homicidio si esa estructura fuese relativamente persistente. Incluso bajo condiciones similares a las de 2023, la proporción esperada de víctimas con antecedentes se sitúa en alrededor del 22%: un porcentaje ligeramente superior al 21,07% registrado en 2023, pero que dista enormemente del 90% afirmado por el presidente Noboa, cifra que implicaría una transformación cualitativa del homicidio como fenómeno social de una magnitud verdaderamente inaudita.
1. Descargar las bases de datos del Ministerio del Interior: Link.
2. Correr el siguiente código en R, haciendo los cambios necesarios en la ubicación del directorio:
# Cargar librerías
library(readxl)
library(dplyr)
library(lubridate)
library(boot)
archivo_datos <- «data/mdi_homicidios_intencionales_pm_2014_2025.xlsx»
archivo_datos_2026 <- «data/mdi_homicidiosintencionalse_pm_2026_enero_enero.xlsx»
datos <- read_excel(archivo_datos)
datos_2026 <- read_excel(archivo_datos_2026)
if («coordenada_x» %in% colnames(datos)) {
datos <- datos %>% mutate(coordenada_x = as.character(coordenada_x))
}
if («coordenada_x» %in% colnames(datos_2026)) {
datos_2026 <- datos_2026 %>% mutate(coordenada_x = as.character(coordenada_x))
}
datos <- bind_rows(datos, datos_2026)
datos <- datos %>%
mutate(
anio = year(fecha_infraccion),
edad_num = as.numeric(gsub(«,», «.», edad)),
rango_edad = case_when(
is.na(edad_num) ~ «SIN_DATO»,
edad_num < 18 ~ «0-17»,
edad_num <= 29 ~ «18-29»,
edad_num <= 44 ~ «30-44»,
edad_num <= 64 ~ «45-64»,
edad_num >= 65 ~ «65+»,
TRUE ~ «OTRO»
),
antecedentes_si = case_when(
antecedentes == «SI» ~ 1,
antecedentes == «NO» ~ 0,
TRUE ~ NAreal
),
hora_num = as.numeric(substr(hora_infraccion, 1, 2)),
bloque_horario = case_when(
is.na(hora_num) ~ «SIN_DATO»,
hora_num >= 0 & hora_num <= 5 ~ «Madrugada»,
hora_num >= 6 & hora_num <= 11 ~ «Mañana»,
hora_num >= 12 & hora_num <= 17 ~ «Tarde»,
hora_num >= 18 & hora_num <= 23 ~ «Noche»,
TRUE ~ «SIN_DATO»
)
) %>%
select(-hora_num)
datos_2023 <- datos %>% filter(anio == 2023)
datos_2024 <- datos %>% filter(anio == 2024)
datos_2025 <- datos %>% filter(anio == 2025)
datos_2026 <- datos %>% filter(anio == 2026)
top_prof <- datos_2023 %>%
count(profesion_registro_civil, sort = TRUE) %>%
slice_head(n = 10) %>% pull(profesion_registro_civil)
top_lugar <- datos_2023 %>%
count(lugar, sort = TRUE) %>%
slice_head(n = 10) %>% pull(lugar)
top_prov <- datos_2023 %>%
count(provincia, sort = TRUE) %>%
slice_head(n = 10) %>% pull(provincia)
agrupar_prof <- function(x) ifelse(x %in% top_prof, x, «OTRAS»)
agrupar_lugar <- function(x) ifelse(x %in% top_lugar, x, «OTROS»)
agrupar_prov <- function(x) ifelse(x %in% top_prov, x, «OTRAS»)
datos_2023 <- datos_2023 %>% mutate(prof_agrupada = agrupar_prof(profesion_registro_civil),
lugar_agrupado = agrupar_lugar(lugar),
prov_agrupada = agrupar_prov(provincia))
datos_2024 <- datos_2024 %>% mutate(prof_agrupada = agrupar_prof(profesion_registro_civil),
lugar_agrupado = agrupar_lugar(lugar),
prov_agrupada = agrupar_prov(provincia))
datos_2025 <- datos_2025 %>% mutate(prof_agrupada = agrupar_prof(profesion_registro_civil),
lugar_agrupado = agrupar_lugar(lugar),
prov_agrupada = agrupar_prov(provincia))
datos_2026 <- datos_2026 %>% mutate(prof_agrupada = agrupar_prof(profesion_registro_civil),
lugar_agrupado = agrupar_lugar(lugar),
prov_agrupada = agrupar_prov(provincia))
niveles_edad <- c(«0-17», «18-29», «30-44», «45-64», «65+»)
niveles_bloque <- c(«Madrugada», «Mañana», «Tarde», «Noche»)
niveles_sexo <- c(«HOMBRE», «MUJER»)
niveles_area <- c(«URBANO», «RURAL»)
para_modelo <- function(df) {
df %>%
filter(rango_edad %in% niveles_edad,
bloque_horario %in% niveles_bloque,
sexo %in% niveles_sexo) %>%
mutate(
rango_edad = factor(rango_edad, levels = niveles_edad),
bloque_horario = factor(bloque_horario, levels = niveles_bloque),
sexo = factor(sexo, levels = niveles_sexo),
area_hecho = factor(area_hecho, levels = niveles_area),
prof_agrupada = factor(prof_agrupada),
lugar_agrupado = factor(lugar_agrupado),
prov_agrupada = factor(prov_agrupada)
)
}
datos_2023_m <- para_modelo(datos_2023) %>% filter(!is.na(antecedentes_si))
datos_2024_m <- para_modelo(datos_2024)
datos_2025_m <- para_modelo(datos_2025)
datos_2026_m <- para_modelo(datos_2026)
cat(«\nTamaños muestrales:\n»)
cat(«2023:», nrow(datos_2023_m), «\n2024:», nrow(datos_2024_m),
«\n2025:», nrow(datos_2025_m), «\n2026:», nrow(datos_2026_m), «\n»)
boot_fun <- function(data, indices) {
d <- data[indices, ]
m <- tryCatch(
glm(antecedentes_si ~ prof_agrupada + rango_edad + sexo + area_hecho +
lugar_agrupado + prov_agrupada + bloque_horario,
data = d, family = binomial),
error = function(e) NULL
)
if (is.null(m)) return(c(NA, NA, NA))
c(mean(predict(m, datos_2024_m, type = «response»)),
mean(predict(m, datos_2025_m, type = «response»)),
mean(predict(m, datos_2026_m, type = «response»)))
}
set.seed(0123)
boot_res <- boot(datos_2023_m, boot_fun, R = 1000)
prop <- colMeans(boot_res$t, na.rm = TRUE)
ic <- apply(boot_res$t, 2, quantile, probs = c(0.025, 0.975), na.rm = TRUE)
n <- c(nrow(datos_2024_m), nrow(datos_2025_m), nrow(datos_2026_m))
cat(«\n— Estimaciones de proporción de antecedentes (SI) —\n»)
for (i in 1:3) {
año <- c(2024,2025,2026)[i]
cat(«\nAño», año, «:\n»)
cat(» Proporción estimada:», round(prop[i], 4), «\n»)
cat(» IC 95%:», round(ic[1,i], 4), «-«, round(ic[2,i], 4), «\n»)
cat(» N° esperado:», round(prop[i] n[i], 1), «\n»)
cat(» IC del número:», round(ic[1,i] n[i], 1), «-«, round(ic[2,i] * n[i], 1), «\n»)
}
Estados Unidos y Venezuela «acordaron restablecer relaciones diplomáticas y consulares», según un comunicado del Departamento…
Después de haber sido vicepresidente de Santos, se metió a la baraja de los presidenciables,…
El proceso judicial que rodea a la excongresista Aida Merlano volvió a sacudir a la…
El lapicero, que ha pasado pruebas de la Registraduría, se llama PinPoint, creado hace 60…
El rodrigato no es una reforma. No es una transición. No es una conversión democrática.…
El 5 de febrero, Jorge Rodríguez condujo la primera discusión de la Ley de Amnistía…