library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.0.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(readxl)
library(caret)
## Loading required package: lattice
##
## Attaching package: 'caret'
##
## The following object is masked from 'package:purrr':
##
## lift
library(car)
## Loading required package: carData
##
## Attaching package: 'car'
##
## The following object is masked from 'package:dplyr':
##
## recode
##
## The following object is masked from 'package:purrr':
##
## some
library(randomForest) # Random Forest
## randomForest 4.7-1.2
## Type rfNews() to see new features/changes/bug fixes.
##
## Attaching package: 'randomForest'
##
## The following object is masked from 'package:dplyr':
##
## combine
##
## The following object is masked from 'package:ggplot2':
##
## margin
library(ggplot2)
library(GGally)
## Registered S3 method overwritten by 'GGally':
## method from
## +.gg ggplot2
Cargamos los datos generados desde ArcGIS:
vias <- read_excel("C:/Users/tomas/Documents/ArcGIS/Projects/Caso 1 Seguridad Vial/EstadoMallaVial__Ciclorruta.xlsx")
# Verificar estructura
glimpse(vias)
## Rows: 100,466
## Columns: 32
## $ OBJECTID <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, …
## $ PK_ID_CALZ <dbl> 355295, 445592, 160549, 24124340, 527859, 361350, 35885…
## $ CIV <dbl> 7002011, 19002553, 10004728, 13002745, 10000001, 700443…
## $ LOCEST <dbl> 7, 19, 10, 13, 10, 7, 7, 5, 11, 8, 5, 7, 8, 11, 4, 6, 3…
## $ SUPERFEST <dbl> 2, 3, 2, 1, 2, 3, 2, 1, 2, 6, 6, 1, 1, 1, 1, 2, 2, 2, 2…
## $ KMCAINDEST <dbl> 0.033, 0.035, 0.100, 0.068, 0.059, 0.053, 0.031, 0.041,…
## $ TIPOMALLAE <chr> "Local", "Local", "Intermedia", "Troncal", "Arterial", …
## $ INDEST <dbl> 81, 88, 90, 97, 85, 92, 94, 93, 74, 100, 0, 84, 89, 94,…
## $ ESTAASHTO <chr> "SATISFACTORIO", "BUENO", "BUENO", "BUENO", "SATISFACTO…
## $ HAY_SINIESTROS <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ AASHTO_BUE <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0…
## $ SINIESTROS <dbl> 2, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 3, 2, 3, 1, 4, 1, 1, 1…
## $ ESTRATO_First <dbl> 2, 1, 3, 4, 3, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 3, 3, 3, 3…
## $ ZAT <dbl> 560, 623, 185, 335, 841, 947, 550, 735, 115, 414, 746, …
## $ mean_V_REF <dbl> 773511.95, 119442.20, 1233204.23, 1797302.25, 1657157.5…
## $ mean_Denpob <dbl> 523.98940, 247.70615, 471.66883, 323.41839, 487.31143, …
## $ mean_Denemp <dbl> 22.8759290, 7.0974177, 137.7956290, 161.3095746, 138.06…
## $ mean_ESTRATO <dbl> 1.8369474, 0.8586321, 2.3637646, 3.6675438, 2.9763595, …
## $ Tipo <chr> "Residential", "Zona verde o humedal", "Residential", "…
## $ Ancho <dbl> 7.072055, NA, 7.520000, 13.270000, 6.150000, 6.730000, …
## $ Carriles <dbl> 2, NA, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, …
## $ SITP <dbl> 0, NA, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, …
## $ Velocidad <dbl> 7.363636, NA, 11.925000, 43.920000, 17.200000, 17.55000…
## $ Flujo <dbl> 674.8853, NA, 2308.3819, 8863.3385, 3513.0228, 1810.787…
## $ Ancho_corr <dbl> 0.9092420, NA, 2.7398611, 17.7127806, 2.5168989, 0.9921…
## $ Pres_anden <dbl> 0, NA, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, …
## $ N_Arboles <dbl> 0, NA, 1, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, …
## $ N_Semaforo <dbl> 0, NA, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, …
## $ RUTAS_SITP <dbl> 1, 1, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 12,…
## $ CICLORRUTA <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ Shape_Length <dbl> 104.77610, 53.08657, 117.60992, 136.62554, 73.59672, 12…
## $ Shape_Area <dbl> -114.08796, -123.66252, -350.72188, -238.87473, -204.88…
Reducimos la base al conjunto de variables clave:
vias_modelo <- vias %>%
dplyr::select(
CIV,
HAY_SINIESTROS, # variable dependiente binaria
TIPOMALLAE,
AASHTO_BUE,
ESTRATO_First,
mean_V_REF,
mean_Denpob,
mean_Denemp,
Tipo,
Ancho,
Carriles,
Velocidad,
Pres_anden,
N_Arboles,
N_Semaforo,
RUTAS_SITP,
CICLORRUTA
)
summary(vias_modelo)
## CIV HAY_SINIESTROS TIPOMALLAE AASHTO_BUE
## Min. : 0 Min. :0.00000 Length:100466 Min. :0.0000
## 1st Qu.: 6001724 1st Qu.:0.00000 Class :character 1st Qu.:0.0000
## Median : 10001068 Median :0.00000 Mode :character Median :1.0000
## Mean : 9885856 Mean :0.07911 Mean :0.7195
## 3rd Qu.: 13002190 3rd Qu.:0.00000 3rd Qu.:1.0000
## Max. :100119153 Max. :1.00000 Max. :1.0000
##
## ESTRATO_First mean_V_REF mean_Denpob mean_Denemp
## Min. :0.000 Min. : 0 Min. : 0.0 Min. : 0.00
## 1st Qu.:1.000 1st Qu.: 578680 1st Qu.:213.0 1st Qu.: 20.66
## Median :2.000 Median : 975825 Median :340.5 Median : 38.92
## Mean :2.204 Mean :1078947 Mean :354.1 Mean : 64.16
## 3rd Qu.:3.000 3rd Qu.:1376343 3rd Qu.:476.6 3rd Qu.: 72.90
## Max. :6.000 Max. :7411032 Max. :965.2 Max. :1005.31
## NA's :112 NA's :44 NA's :44 NA's :44
## Tipo Ancho Carriles Velocidad
## Length:100466 Min. : 1.950 Min. :1.000 Min. : 0.9634
## Class :character 1st Qu.: 5.770 1st Qu.:2.000 1st Qu.:11.3684
## Mode :character Median : 6.890 Median :2.000 Median :14.7951
## Mean : 6.983 Mean :2.038 Mean :16.2867
## 3rd Qu.: 7.710 3rd Qu.:2.000 3rd Qu.:19.0800
## Max. :26.330 Max. :5.000 Max. :69.5172
## NA's :2116 NA's :2116 NA's :2116
## Pres_anden N_Arboles N_Semaforo RUTAS_SITP
## Min. :0.0000 Min. : 0.000 Min. :0.000 Min. : 1.000
## 1st Qu.:0.0000 1st Qu.: 0.000 1st Qu.:0.000 1st Qu.: 1.000
## Median :1.0000 Median : 0.000 Median :0.000 Median : 1.000
## Mean :0.6344 Mean : 3.057 Mean :0.039 Mean : 3.963
## 3rd Qu.:1.0000 3rd Qu.: 3.000 3rd Qu.:0.000 3rd Qu.: 1.000
## Max. :1.0000 Max. :297.000 Max. :3.000 Max. :107.000
## NA's :2116 NA's :2116 NA's :2116
## CICLORRUTA
## Min. :0.0000
## 1st Qu.:0.0000
## Median :0.0000
## Mean :0.1538
## 3rd Qu.:0.0000
## Max. :1.0000
##
Convertimos variables categóricas adecuadamente y manejamos valores faltantes:
vias_modelo <- vias_modelo %>%
mutate(
HAY_SINIESTROS = factor(HAY_SINIESTROS, levels = c(0,1)),
TIPOMALLAE = factor(TIPOMALLAE),
AASHTO_BUE = factor(AASHTO_BUE),
ESTRATO_First = factor(ESTRATO_First),
Tipo = factor(Tipo),
Pres_anden = factor(Pres_anden),
CICLORRUTA = factor(CICLORRUTA)
) %>%
drop_na()
# Confirmar estructura
str(vias_modelo)
## tibble [96,700 × 17] (S3: tbl_df/tbl/data.frame)
## $ CIV : num [1:96700] 7.0e+06 1.0e+07 1.3e+07 1.0e+07 7.0e+06 ...
## $ HAY_SINIESTROS: Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ...
## $ TIPOMALLAE : Factor w/ 4 levels "Arterial","Intermedia",..: 3 2 4 1 3 3 3 3 3 3 ...
## $ AASHTO_BUE : Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ...
## $ ESTRATO_First : Factor w/ 7 levels "0","1","2","3",..: 3 4 5 4 3 3 3 3 3 3 ...
## $ mean_V_REF : num [1:96700] 773512 1233204 1797302 1657158 544439 ...
## $ mean_Denpob : num [1:96700] 524 471.7 323.4 487.3 99.3 ...
## $ mean_Denemp : num [1:96700] 22.88 137.8 161.31 138.06 3.68 ...
## $ Tipo : Factor w/ 8 levels "Comercial","Extracción del Suelo",..: 5 5 5 5 6 5 5 5 5 5 ...
## $ Ancho : num [1:96700] 7.07 7.52 13.27 6.15 6.73 ...
## $ Carriles : num [1:96700] 2 2 3 2 2 2 2 2 2 2 ...
## $ Velocidad : num [1:96700] 7.36 11.93 43.92 17.2 17.55 ...
## $ Pres_anden : Factor w/ 2 levels "0","1": 1 2 2 2 1 1 2 1 1 1 ...
## $ N_Arboles : num [1:96700] 0 1 0 0 0 5 0 0 0 0 ...
## $ N_Semaforo : num [1:96700] 0 1 0 0 0 0 0 0 0 0 ...
## $ RUTAS_SITP : num [1:96700] 1 3 4 1 1 1 1 1 1 1 ...
## $ CICLORRUTA : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
Se estimó un modelo de regresión logística (logit) para evaluar la
probabilidad de ocurrencia de siniestros viales en segmentos de vía
(CIV) en Bogotá. La variable dependiente es HAY_SINIESTROS,
binaria (1 si hubo al menos un siniestro, 0 si no hubo).
La base usada fue amplia, incluyendo inicialmente 100,466 observaciones, de las cuales quedaron 96,700 luego de limpiar datos faltantes.
Creamos variables dummy con referencia explícita para evitar multicolinealidad, estas serán las categorías base frente a las que las demás se compararán en el modelo:
vias_modelo <- vias_modelo %>%
mutate(
TIPOMALLAE = relevel(TIPOMALLAE, ref = "Local"),
ESTRATO_First = relevel(ESTRATO_First, ref = "1"),
Tipo = relevel(Tipo, ref = "Residential")
)
Separamos la base en entrenamiento (70%) y prueba (30%):
set.seed(123)
index <- createDataPartition(vias_modelo$HAY_SINIESTROS, p = 0.7, list = FALSE)
train <- vias_modelo[index, ]
test <- vias_modelo[-index, ]
Estimamos el modelo usando glm:
modelo_logit <- glm(HAY_SINIESTROS ~
TIPOMALLAE + AASHTO_BUE + ESTRATO_First + mean_V_REF +
mean_Denpob + mean_Denemp + Tipo + Ancho + Carriles +
Velocidad + Pres_anden + N_Arboles + N_Semaforo +
RUTAS_SITP + CICLORRUTA,
data = train, family = binomial(link = "logit"))
# Resultados
summary(modelo_logit)
##
## Call:
## glm(formula = HAY_SINIESTROS ~ TIPOMALLAE + AASHTO_BUE + ESTRATO_First +
## mean_V_REF + mean_Denpob + mean_Denemp + Tipo + Ancho + Carriles +
## Velocidad + Pres_anden + N_Arboles + N_Semaforo + RUTAS_SITP +
## CICLORRUTA, family = binomial(link = "logit"), data = train)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -4.807e+00 1.409e-01 -34.126 < 2e-16 ***
## TIPOMALLAEArterial 9.708e-01 5.185e-02 18.725 < 2e-16 ***
## TIPOMALLAEIntermedia 8.719e-03 4.632e-02 0.188 0.850687
## TIPOMALLAETroncal 1.639e+00 5.922e-02 27.684 < 2e-16 ***
## AASHTO_BUE1 1.611e-01 4.026e-02 4.002 6.27e-05 ***
## ESTRATO_First0 1.508e+00 1.263e-01 11.940 < 2e-16 ***
## ESTRATO_First2 1.291e+00 1.228e-01 10.518 < 2e-16 ***
## ESTRATO_First3 1.612e+00 1.239e-01 13.014 < 2e-16 ***
## ESTRATO_First4 1.367e+00 1.341e-01 10.190 < 2e-16 ***
## ESTRATO_First5 1.179e+00 1.551e-01 7.606 2.83e-14 ***
## ESTRATO_First6 1.158e+00 1.771e-01 6.538 6.23e-11 ***
## mean_V_REF -6.011e-08 3.182e-08 -1.889 0.058863 .
## mean_Denpob -3.081e-04 9.803e-05 -3.143 0.001671 **
## mean_Denemp -2.413e-04 2.123e-04 -1.137 0.255629
## TipoComercial 3.060e-02 5.393e-02 0.567 0.570468
## TipoExtracción del Suelo -2.267e-01 6.061e-01 -0.374 0.708384
## TipoIndustrial 5.083e-01 6.909e-02 7.356 1.89e-13 ***
## TipoOficial 2.273e-01 8.453e-02 2.689 0.007161 **
## TipoSin Construir 5.407e-01 6.461e-02 8.369 < 2e-16 ***
## TipoZona Histórica -3.036e-02 1.292e-01 -0.235 0.814144
## TipoZona verde o humedal -4.230e-02 1.180e-01 -0.359 0.719968
## Ancho 4.166e-02 8.919e-03 4.671 3.00e-06 ***
## Carriles -1.417e-01 3.942e-02 -3.593 0.000326 ***
## Velocidad 6.107e-03 1.765e-03 3.460 0.000540 ***
## Pres_anden1 2.086e-01 4.550e-02 4.585 4.54e-06 ***
## N_Arboles 3.849e-03 2.050e-03 1.878 0.060390 .
## N_Semaforo 2.141e-01 5.579e-02 3.837 0.000124 ***
## RUTAS_SITP 2.999e-02 1.345e-03 22.292 < 2e-16 ***
## CICLORRUTA1 4.237e-01 3.567e-02 11.880 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 38026 on 67690 degrees of freedom
## Residual deviance: 31440 on 67662 degrees of freedom
## AIC: 31498
##
## Number of Fisher Scoring iterations: 7
El resumen del modelo indica cuáles variables explican significativamente la probabilidad de ocurrencia de siniestros (con un nivel de significancia del 5% o menor):
Tipo de vía: Vía Troncal y Arterial son altamente significativas (p < 0.001) comparadas con la categoría referencia (“Local”). Esto implica que la probabilidad de siniestro es mayor en vías Troncales (exp(1.639) ≈ 5.15 veces más probable / +415%) y en menor medida en vías Arteriales (+164%). Esto puede estar relacionado con las velocidades, nível de exposicición y conflictos En cambio, las vías intermedias no mostraron significancia estadística.
Estado de la vía según AASHTO (AASHTO_BUE): Un buen estado de la vía está asociado significativamente (coeficiente positivo, 0.161 / +17%) con mayor probabilidad de siniestro, sugiriendo que las vías en buen estado concentran más siniestros posiblemente por una mayor exposición al riesgo (mayor flujo, mayor velocidad, etc.).
Estrato socioeconómico: Todas las categorías de estrato fueron significativas frente al estrato 1 (base). Los estratos más altos (especialmente estratos 3 - +401% - y 4 - +292% -) están fuertemente asociados con mayor ocurrencia de siniestros, posiblemente por mayor flujo vehicular y cobertura de la ciudad.
Valor promedio de predios: Marginalmente significativo (p ~ 0.059). El efecto es levemente negativo, a medida que sube el valor predial, disminuyen mínimamente las probabilidades de siniestro. Sin embargo, la magnitud es muy pequeña (-0.0000006).
Densidad poblacional: Aunque pequeña, la relación es estadísticamente significativa (p=0.0017) y de signo negativo. Para cada unidad adicional (p.ej. 1 habitante/ha más), las odds se reducen un 0.03%.
Uso del suelo: Destacan tres tipos de uso de suelo:
Características físicas y operativas de la vía:
Mayor Ancho de vía aumentó significativamente la probabilidad de siniestros (coeficiente positivo), cada metro adicional de ancho se asocia con +4% en las probabilidades de siniestro. Más Carriles está sorprendentemente asociado negativamente (menos probabilidad de siniestro), -13% de probabilidad por cada carril adicional. Podría indicar que vías con más carriles tienen mejor segregación del tráfico o mejores condiciones de cicloinfraestructura, reduciendo interacciones y siniestros.
Mayor Velocidad incrementa significativamente la probabilidad de siniestros, cada km/h adicional implica un 0.6% más en las probabilidades de un siniestro.
Presencia de andén (acera) no resultó significativa.
Presencia de semáforos se asoció significativamente a mayor probabilidad de siniestros (probablemente por concentración en intersecciones conflictivas), cada semáforo extra incrementa en 24% las probabilidades de un siniestro.
Rutas SITP (transporte público): Mayor número de rutas del SITP incrementa significativamente la probabilidad de accidentes, por cada ruta adicional del SITP, las probabilidades suben un 3%, indicando zonas con más interacción entre usuarios vulnerables (peatones, ciclistas, usuarios de transporte público).
Presencia de ciclorrutas: El efecto positivo es muy significativo; vías con ciclorrutas cercanas tienen un +53% de probabilidad considerablemente mayor de presentar siniestros. Esto posiblemente refleja mayor exposición o interacción entre ciclistas y otros vehículos, especialmente en intersecciones.
Evaluamos la presencia de multicolinealidad con el Factor de Inflación de la Varianza (VIF):
vif(modelo_logit)
## GVIF Df GVIF^(1/(2*Df))
## TIPOMALLAE 2.717433 3 1.181299
## AASHTO_BUE 1.067754 1 1.033322
## ESTRATO_First 2.981210 6 1.095299
## mean_V_REF 2.571141 1 1.603478
## mean_Denpob 1.574454 1 1.254772
## mean_Denemp 1.927230 1 1.388247
## Tipo 2.014305 7 1.051292
## Ancho 1.897708 1 1.377573
## Carriles 1.824602 1 1.350778
## Velocidad 1.581749 1 1.257676
## Pres_anden 1.326337 1 1.151667
## N_Arboles 1.063566 1 1.031293
## N_Semaforo 1.110772 1 1.053932
## RUTAS_SITP 1.560169 1 1.249067
## CICLORRUTA 1.188641 1 1.090248
El diagnóstico VIF muestra valores menores a 5 para todas las variables. Esto indica ausencia de multicolinealidad preocupante. Las variables pueden mantenerse en el modelo sin ajustes adicionales.
Evaluamos la capacidad predictiva del modelo en la base de test:
test$predicciones_prob <- predict(modelo_logit, newdata = test, type = "response")
test$predicciones_bin <- ifelse(test$predicciones_prob > 0.5, 1, 0)
# Matriz de confusión
confusionMatrix(as.factor(test$predicciones_bin), test$HAY_SINIESTROS, positive = "1")
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 26531 2140
## 1 133 205
##
## Accuracy : 0.9216
## 95% CI : (0.9185, 0.9247)
## No Information Rate : 0.9192
## P-Value [Acc > NIR] : 0.06126
##
## Kappa : 0.1352
##
## Mcnemar's Test P-Value : < 2e-16
##
## Sensitivity : 0.087420
## Specificity : 0.995012
## Pos Pred Value : 0.606509
## Neg Pred Value : 0.925360
## Prevalence : 0.080837
## Detection Rate : 0.007067
## Detection Prevalence : 0.011652
## Balanced Accuracy : 0.541216
##
## 'Positive' Class : 1
##
El modelo Random Forest es un método de aprendizaje de máquina basado en árboles de decisión. Es útil cuando hay relaciones no lineales en los datos y cuando se busca una alta precisión predictiva. El modelo Random Forest es un algoritmo de aprendizaje supervisado que se basa en la construcción de múltiples árboles de decisión y la combinación de sus predicciones para mejorar la precisión y reducir el sobreajuste.
set.seed(123) # Asegurar reproducibilidad
rf_model <- randomForest(
HAY_SINIESTROS ~ TIPOMALLAE + AASHTO_BUE + ESTRATO_First + mean_V_REF +
mean_Denpob + mean_Denemp + Tipo + Ancho + Carriles +
Velocidad + Pres_anden + N_Arboles + N_Semaforo +
RUTAS_SITP + CICLORRUTA,
data = vias_modelo,
ntree = 500,
importance = TRUE,
na.action = na.omit
)
print(rf_model)
##
## Call:
## randomForest(formula = HAY_SINIESTROS ~ TIPOMALLAE + AASHTO_BUE + ESTRATO_First + mean_V_REF + mean_Denpob + mean_Denemp + Tipo + Ancho + Carriles + Velocidad + Pres_anden + N_Arboles + N_Semaforo + RUTAS_SITP + CICLORRUTA, data = vias_modelo, ntree = 500, importance = TRUE, na.action = na.omit)
## Type of random forest: classification
## Number of trees: 500
## No. of variables tried at each split: 3
##
## OOB estimate of error rate: 7.64%
## Confusion matrix:
## 0 1 class.error
## 0 87813 1068 0.01201607
## 1 6318 1501 0.80803172
varImpPlot(rf_model) # Importancia de las variables
# Supongamos que estas son tus variables significativas (continuas y categóricas):
cont_vars <- c("Ancho", "Velocidad", "RUTAS_SITP") # Ejemplo
cat_vars <- c("TIPOMALLAE", "AASHTO_BUE", "ESTRATO_First", "CICLORRUTA") # Ejemplo
# 1) Para variables continuas: Boxplot o violin plot por valor de HAY_SINIESTROS
for (var in cont_vars) {
p <- ggplot(vias_modelo, aes_string(x = "HAY_SINIESTROS", y = var, fill = "HAY_SINIESTROS")) +
geom_boxplot() +
labs(title = paste("Distribución de", var, "según HAY_SINIESTROS")) +
theme_minimal()
print(p)
}
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
# 2) Para variables categóricas: Barras agrupadas o barras apiladas
for (var in cat_vars) {
p <- ggplot(vias_modelo, aes_string(x = var, fill = "HAY_SINIESTROS")) +
geom_bar(position = "fill") + # 'fill' para ver proporciones
labs(y = "Proporción", title = paste("Distribución de HAY_SINIESTROS por", var)) +
theme_minimal()
print(p)
}
df_significativas <- vias_modelo %>%
dplyr::select(
HAY_SINIESTROS,
TIPOMALLAE,
AASHTO_BUE,
ESTRATO_First,
Ancho,
Velocidad,
RUTAS_SITP,
CICLORRUTA
)
ggpairs(
df_significativas,
aes(color = HAY_SINIESTROS),
upper = list(continuous = "points", combo = "box", discrete = "ratio"),
lower = list(continuous = "smooth", combo = "facetdensity", discrete = "facetbar")
)
ggplot(vias_modelo, aes(x = Velocidad, fill = HAY_SINIESTROS)) +
geom_histogram(bins = 30, alpha = 0.7) +
facet_wrap(~ HAY_SINIESTROS, scales = "free_y") +
labs(title = "Distribución de Velocidad según Siniestros") +
theme_minimal()
ggplot(vias_modelo, aes(x = mean_Denpob, fill = HAY_SINIESTROS)) +
geom_histogram(bins = 30, alpha = 0.7) +
facet_wrap(~ HAY_SINIESTROS, scales = "free_y") +
labs(title = "Distribución de densidad poblacional según Siniestros") +
theme_minimal()
ggplot(vias_modelo, aes(x = mean_Denemp, fill = HAY_SINIESTROS)) +
geom_histogram(bins = 30, alpha = 0.7) +
facet_wrap(~ HAY_SINIESTROS, scales = "free_y") +
labs(title = "Distribución de densidad de empleos generados según Siniestros") +
theme_minimal()
El modelo logit actual revela factores clave en la ocurrencia de siniestros en Bogotá, con fuerte influencia del tipo de vía, infraestructura ciclística y características socioeconómicas del entorno. La calidad del modelo es aceptable para entender patrones globales, aunque es mejorable si se buscan predicciones más precisas sobre siniestros individuales. Se recomienda considerar métodos alternativos como Random Forest o modelos espaciales para complementar análisis predictivos futuros.