Accidentes de tráfico con implicación de bicicletas en Madrid (2014-2018)

Alejandro López Martínez

Este estudio analiza los accidentes de tráfico en la ciudad de Madrid registrados por la Policía Municipal, en los que está implicada al menos una bicicleta, entre los años 2014 y 2018.

Se ha elegido R Studio para su desarrollo y el paquete rMarkdown para la creación del informe en HTML.

1. Introducción

Los datos de estudio se han obtenido a través del portal de datos abiertos del Ayuntamiento de Madrid (https://datos.madrid.es/) y forman parte de la base de datos “Accidentes de tráfico con implicación de bicicletas” de los 5 últimos años, disponible en formato .xlsx:

En un primer lugar se cargan los datos en R Studio y se procede a su adaptación y procesado. A continuación, se lleva a cabo un análisis descriptivo a través de visualizaciones gráficas de las características más destacables. Adicionalmente, se desarrolla un modelo de predicción del grado de lesividad de las personas accidententadas, en función de diferentes variables, utilizando distintas técnicas machine learning. Por último, se extraen las conclusiones más significativas del estudio.

2. Carga de datos y procesado

Se cargan los datos en formato Excel directamente a través de su link en R Studiopara cada uno de los años, desde 2014 a 2018 y se carga la librería data.table.

Se omite mostrar la carga de datos en el documento por su longitud.

A continuación se unen todos los datos con rbind creando el dataset final Bicis y se borran los dataset parciales que ya no se van a usar.

Bicis=rbind(Bicis14, Bicis15, Bicis16, Bicis17, Bicis18)
rm(Bicis14, Bicis15, Bicis16, Bicis17, Bicis18)

Se convierte al formato data.table nombrando al nuevo conjunto como BicisDT y se muestra la estructura del conjunto de datos resultante y su dimensión.

BicisDT=as.data.table(Bicis)
str(BicisDT)
## Classes 'data.table' and 'data.frame':   3661 obs. of  26 variables:
##  $ FECHA             : POSIXct, format: "2014-01-08" "2014-01-09" ...
##  $ RANGO HORARIO     : chr  "DE 17:00 A 17:59" "DE 7:00 A 7:59" "DE 10:00 A 10:59" "DE 18:00 A 18:59" ...
##  $ DIA SEMANA        : chr  "MIERCOLES" "JUEVES" "JUEVES" "SABADO" ...
##  $ DISTRITO          : chr  "USERA" "LATINA" "SAN BLAS" "CIUDAD LINEAL" ...
##  $ LUGAR ACCIDENTE   : chr  "CALLE DEL ANGELUS NUM" "AVENIDA DE LOS POBLADOS NUM" "CALLE DE EMILIO MUÑOZ NUM" "CALLE DE LOS HERMANOS GARCIA NOBLEJAS - CALLE DE MALMOE" ...
##  $ Nº                : num  3 66 21 NA 54 0 0 23 10 7 ...
##  $ Nº PARTE          : chr  "2014/334" "2014/290" "2014/251" "2014/370" ...
##  $ CPFA Granizo      : chr  "NO" "NO" "NO" "NO" ...
##  $ CPFA Hielo        : chr  "NO" "NO" "NO" "NO" ...
##  $ CPFA Lluvia       : chr  "NO" "NO" "NO" "NO" ...
##  $ CPFA Niebla       : chr  "NO" "NO" "NO" "NO" ...
##  $ CPFA Seco         : chr  "SI" "SI" "SI" "SI" ...
##  $ CPFA Nieve        : chr  "NO" "NO" "NO" "NO" ...
##  $ CPSV Mojada       : chr  "NO" "NO" "NO" "NO" ...
##  $ CPSV Aceite       : chr  "NO" "NO" "NO" "NO" ...
##  $ CPSV Barro        : chr  "NO" "NO" "NO" "NO" ...
##  $ CPSV Grava Suelta : chr  "NO" "NO" "NO" "NO" ...
##  $ CPSV Hielo        : chr  "NO" "NO" "NO" "NO" ...
##  $ CPSV Seca Y Limpia: chr  "SI" "SI" "SI" "SI" ...
##  $ Nº VICTIMAS *     : num  1 1 1 1 1 1 2 1 1 1 ...
##  $ TIPO ACCIDENTE    : chr  "COLISIÓN DOBLE" "COLISIÓN DOBLE" "ATROPELLO" "COLISIÓN DOBLE" ...
##  $ Tipo Vehiculo     : chr  "BICICLETA" "BICICLETA" "BICICLETA" "BICICLETA" ...
##  $ TIPO PERSONA      : chr  "CONDUCTOR" "CONDUCTOR" "CONDUCTOR" "CONDUCTOR" ...
##  $ SEXO              : chr  "HOMBRE" "HOMBRE" "HOMBRE" "HOMBRE" ...
##  $ LESIVIDAD         : chr  "HL" "HL" "IL" "HL" ...
##  $ Tramo Edad        : chr  "DE 18 A 20 AÑOS" "DE 45 A 49 AÑOS" "DE 30 A 34 ANOS" "DE 25 A 29 AÑOS" ...
##  - attr(*, ".internal.selfref")=<externalptr>
dim(BicisDT)
## [1] 3661   26

Son un total de 3661 observaciones agrupadas en 26 categorías. En el anexo se incluye una descripción detallada de cada una de las categorías.

2.1. Adaptación del dataset

Muchos de los campos del dataset BicisDT no aportan información relevante para este estudio y algunos de ellos requieren ser formateados con otra estructura de datos. Además existen algunas observaciones incompletas que no se considerarán tampoco en nuestro estudio.

A continuación se listan los cambios que se van a realizar en el dataset BicisDT:

  • Supresión de columnas que no se usarán en el análisis
    • LUGAR ACCIDENTE no es necesario saber la calle exacta del accidente, ya se agruparán los resultados por DISTRITO
    • Nº de calle ocurre lo mismo al ser demasiado específico para este estudio
    • Nº PARTE de la Policia no es necesario
    • De los datos meteorológicos y de estado de calzada se usará únicamente con la variable dicotómica CPSV Seca y Limpia, puesto que engloba prácticamente al resto de variables meteorológicas. Si está lloviendo por ejemplo la calzada ya no está seca y limpia
    • Nº VICTIMAS * en este tipo de accidente suele haber una única victima
    • Tipo Vehiculo en este estudio siempre es BICICLETA
    • TIPO PERSONA no aporta información relevante para el estudio
  • Conversión de cadenas de texto a formato numérico
    • RANGO HORARIO: Se tomará como referencia la hora de inicio del rango horario en formato numérico
    • Tramo Edad: Se tomará como referencia el extremo inferior del rango en formato numérico
  • Simplificación de nombres de categoría largos o con caracteres especiales
    • RANGO HORARIO se cambia por HORA
    • DIA SEMANA se cambia por DIA
    • CPSV Seca Y Limpia se cambia por CALZADA_SECA
    • TIPO ACCIDENTE se cambia por TIPO_ACC
    • Tramo Edad se cambia por EDAD
  • Creación de valores NA en las variables SEXO y LESIVIDAD donde figura el valor “NO ASIGNADO”
  • Creación de factores para variables categóricas
    • Se crea un factor en la variable DIA y se ordena por día de la semana
    • Se crea un factor LESIVIDAD y se ordena de menor a mayor lesividad
    • Se crea factores para el resto de variables DISTRITO, CALZADA_SECA, TIPO_ACC y SEXO

Se omite el codigo en R de estas transformaciones por su longitud.

Se muestra la estructura del conjunto de datos transformado BicisDT y su dimensión:

str(BicisDT)
## Classes 'data.table' and 'data.frame':   3661 obs. of  9 variables:
##  $ FECHA       : POSIXct, format: "2014-01-08" "2014-01-09" ...
##  $ HORA        : num  17 7 10 18 19 12 19 20 20 0 ...
##  $ DIA         : Factor w/ 7 levels "LUNES","MARTES",..: 3 4 4 6 1 2 2 2 2 4 ...
##  $ DISTRITO    : Factor w/ 21 levels "ARGANZUELA","BARAJAS",..: 18 10 16 7 4 3 11 3 16 4 ...
##  $ CALZADA_SECA: Factor w/ 2 levels "NO","SI": 2 2 2 2 2 1 2 2 2 2 ...
##  $ TIPO_ACC    : Factor w/ 9 levels "ATROPELLO","CAÍDA BICICLETA",..: 7 7 1 7 8 7 1 7 2 7 ...
##  $ SEXO        : Factor w/ 2 levels "HOMBRE","MUJER": 1 1 1 1 1 1 1 1 1 1 ...
##  $ LESIVIDAD   : Factor w/ 4 levels "IL","HL","HG",..: 2 2 1 2 2 2 2 2 3 2 ...
##  $ EDAD        : num  18 45 30 25 45 10 40 25 35 30 ...
##  - attr(*, ".internal.selfref")=<externalptr> 
##  - attr(*, "index")= int
dim(BicisDT)
## [1] 3661    9

En el nuevo conjunto transformado BicisDT se siguen manteniendo el total de 3661 observaciones, pero agrupadas en 9 categorías y con un formato más adecuado para facilitar su análisis.

3. Análisis descriptivo del conjunto

En esta sección se estudiará el conjunto de datos a través de diferentes análisis y visualizaciones gráficas.

3.1. Evolución temporal del número total de accidentes

En primer lugar se examinará la evolución del número de accidentes por año y su lesividad para estudiar si existe alguna tendencia. Se omiten los accidentes donde no se ha declarado la lesividad de la víctima.

Se observa que el número de accidentes se mantiene relativamente constante en el tiempo así como su lesividad, si bien crecen ligeramente entre 2015-2017 para volver a bajar levemente en 2018. Con respecto a la lesividad, los accidentes más predominantes fueron en los que las victimas resultaron heridas leves.

3.2. Análisis de los accidentes por distrito

En segundo lugar, se analizarán los accidentes ocurridos en función del distrito, para comprobar si hay zonas en las que ocurran más accidentes. Para ello se estudian los 10 distritos con mayor accidentabilidad del total de los 21 distritos que componen la ciudad de Madrid.

De la representación gráfica se desprende que el distrito Centro es donde se producen la mayor parte de accidentes en Madrid. De hecho, se producen casi más del doble de accidentes que en cualquier otro distrito del “Top 10” de distritos con más accidentes.

Por este motivo se examinan más en detalle los accidentes ocurridos en el distrito Centro, en concreto su evolución a lo largo del periodo 2014-2018.

Se manifiesta una tendencia creciente en el número de accidentes en el distrito Centro. Si se tiene en cuenta que el número de accidentes totales en Madrid se mantiene relativamente estable en el periodo estudiado, todo parece indicar que se está produciendo un incremento en la concentración de accidentes ocurridos en el distrito Centro con respecto al resto de distritos de la capital.

3.3. Estudio diario y horario

A continuación se estudiaran el total de accidentes por día de la semana, agregados para el conjunto de años 2014-2018.

Soprendentemente el día que más accidentes ocurren es el jueves. Si bien no existen demasiadas diferencias en el resto de días, si que parece que hay una ligera disminución en el número de accidentes el fin de semana y el lunes.

Con respecto a los accidentes en función de la hora del día se estudiará su distribución horaria a través de un gráfico violín combinado con un boxplot que incluye primer cuartil, mediana y tercer cuartil de la distribución estudiada.

Se observa que la mayoría de accidentes ocurren a lo largo del día y son poco frecuentes los accidentes nocturnos. En los días laborables ocurren más accidentes a mediodía y por la tarde. Por el contrario, en el fin de semana se ocasionan un mayor número de accidentes por la mañana.

Los viernes parecen seguir un patrón intermedio entre la tendencia de los días laborables L-J y la de los fines de semana.

3.4. Estudio por sexo de las personas accidentadas

Seguidamente se analizará la variable sexo de las personas accidentadas en función de su edad.

Del analisis gráfico se desprende que aproximadamente el 80% de los accidentados son varones, mientras que las mujeres representan alrededor del 20% de personas accidentadas. Con respecto a la edad, existe una mayor incidencia de accidentes en el tramo de edad de 20 a 40 años, situandose la edad media de los accidentados en 35 años aproximadamente.

A continuación se estudiará el grado de lesividad de los accidentes acontecidos en función del sexo de la víctima.

En la mayor parte de los accidentes de bicicleta acontecidos en Madrid, las victimas resultan heridas leves, tanto en el caso de hombres como mujeres. No existiendo una diferencia significativa con respecto al sexo de la persona accidentada.

También es interesante destacar que la proporción de heridos graves es semejante a la de ilesos, y que las victimas mortales representan un porcentaje muy pequeño en los accidentes registrados.

3.5. Análisis del tipo de accidentes acontecidos

En este capítulo se estudiarán los tipos de accidente en función de la lesividad de las victimas.

La representación gráfica muestra que los accidentes más comunes son las caídas de las bicicletas y las colisiones dobles, que son en las que están implicados dos vehiculos en el accidente. La mayoría de las victimas resultan heridas leves cuando suceden este tipo de accidentes. Cuando el accidente ha sido causado por una caída de ciclomotor, motocicleta o pasajero de autobus, las victimas han resultado ilesas en la totalidad de los casos registrados.

Es interesante estudiar la tipología Atropellos, que si bien a priori se podría pensar como una de las más lesivas, los registros indican que la mayoría de victimas ha resultado ilesas o heridas leves. Por último, cabe destacar también que la categoría Colisión doble es la única tipología donde se han registrado víctimas mortales.

Adicionalmente se analizará la relación entre el estado de la calzada y el tipo de accidente ocurrido.

Existen más accidentes en calzada seca que en calzada mojada puesto que en Madrid llueven pocos días al año.

En todo caso, no se puede afirmar que las tipologías de accidentes varíen significativamente en función del estado de la calzada. Tanto en calzada seca como en mojada los accidentes predominantes son caídas de bicicleta y colisiones dobles.

Por último se analizará la relación entre el estado de la calzada y la lesividad de los accidentados.

Con respecto a la lesividad, siguen predominando los heridos leves tanto en condiciones de calzada seca como en mojado. Sin embargo, si que se percibe una mayor proporción relativa de heridos graves cuando la calzada está mojada, si se compara con las condiciones de calzada seca.

4. Uso de técnicas de Machine learning

En este capítulo se van a crear modelos de predicción a través de técnicas de machine learning. En concreto se usarán algoritmos de clasificación (aprendizaje supervisado) para predecir el grado de lesividad de las victimas de un accidente de bicicleta en Madrid, en función del resto de variables estudiadas anteriormente.

Para ello, se van a realizar una serie de cambios al dataset BicisDT con el objetivo de tener variables numéricas. Este nuevo dataset se llamará BicisML. A continuación se describen las transformaciones a realizar:

Se omite el codigo en R de estas transformaciones por limitación de espacio, si bien figura en el Anexo_Codigo_R.

Se muestra la estructura del conjunto resultante que se usará los modelos de predicción BicisML y su dimensión:

str(BicisML)
## Classes 'data.table' and 'data.frame':   3580 obs. of  9 variables:
##  $ FECHA       : num  2014 2014 2014 2014 2014 ...
##  $ HORA        : num  17 7 10 18 19 12 19 20 20 0 ...
##  $ DIA         : num  3 4 4 6 1 2 2 2 2 4 ...
##  $ DISTRITO    : num  18 10 16 7 4 3 11 3 16 4 ...
##  $ CALZADA_SECA: num  2 2 2 2 2 1 2 2 2 2 ...
##  $ TIPO_ACC    : num  7 7 1 7 8 7 1 7 2 7 ...
##  $ SEXO        : num  1 1 1 1 1 1 1 1 1 1 ...
##  $ EDAD        : num  18 45 30 25 45 10 40 25 35 30 ...
##  $ LESIVIDAD   : Factor w/ 4 levels "IL","HL","HG",..: 2 2 1 2 2 2 2 2 3 2 ...
##  - attr(*, ".internal.selfref")=<externalptr>
dim(BicisML)
## [1] 3580    9

En el nuevo conjunto BicisML dispone de un total de 3580 observaciones (accidentes de los que se dispone información de todas las variables), agrupadas en 8 categorías numéricas y una cualitativa-factor, que es la LESIVIDAD que se pretende predecir con los modelos de machine learning.

En una segunda etapa de la preparación de datos se normalizarán y guardarán únicamente los valores numéricos en BicisML_norm para que las distintas variables tengan una escala común.

Tras la normalización usamos la función summary para ver el valor mínimo, primer cuartil, mediana, media, tercer cuartil y valor máximo, comprobando que se ha realizado correctamente.

summary(BicisML_norm)
##      FECHA             HORA             DIA            DISTRITO     
##  Min.   :0.0000   Min.   :0.0000   Min.   :0.0000   Min.   :0.0000  
##  1st Qu.:0.2500   1st Qu.:0.4783   1st Qu.:0.1667   1st Qu.:0.1500  
##  Median :0.5000   Median :0.6087   Median :0.5000   Median :0.4000  
##  Mean   :0.5026   Mean   :0.6182   Mean   :0.4964   Mean   :0.4225  
##  3rd Qu.:0.7500   3rd Qu.:0.8261   3rd Qu.:0.8333   3rd Qu.:0.6500  
##  Max.   :1.0000   Max.   :1.0000   Max.   :1.0000   Max.   :1.0000  
##   CALZADA_SECA       TIPO_ACC           SEXO             EDAD       
##  Min.   :0.0000   Min.   :0.0000   Min.   :0.0000   Min.   :0.0000  
##  1st Qu.:1.0000   1st Qu.:0.1250   1st Qu.:0.0000   1st Qu.:0.3378  
##  Median :1.0000   Median :0.7500   Median :0.0000   Median :0.4054  
##  Mean   :0.8964   Mean   :0.4424   Mean   :0.1911   Mean   :0.4536  
##  3rd Qu.:1.0000   3rd Qu.:0.7500   3rd Qu.:0.0000   3rd Qu.:0.6081  
##  Max.   :1.0000   Max.   :1.0000   Max.   :1.0000   Max.   :1.0000

4.1. Algoritmo KNN

El primer modelo de predicción de la lesividad en caso de accidente de bicicleta en Madrid se va a construir a partir de un algoritmo de clasificación KNN (K-Nearest Neighbors). Este modelo de clasificación utiliza la distancia euclídea como medida de referencia para encontrar los k vecinos más próximos al nuevo dato, siendo k un parametro a fijar por el usuario.

El algoritmo KNN se aplica a un conjunto de datos de entrenamiento y posteriormente se validan los resultados con un conjunto de prueba. Para ello se dividirá el conjunto de datos en dos partes: datos de entrenamiento (training) y datos de prueba (test).

En este caso se usarán las proporciones 2/3 de los datos originales para los datos de entrenamiento y 1/3 de los datos originales para los datos de prueba.

Puesto que los datos están originalmente ordenados por años, se va a fijar una semilla generadora de números aleatorios para asegurar que hay registros de accidentes de todos los años, tanto en los datos de entrenamiento como de test.

A continuación, se usará la función sample para crear una variable ind que sirva de indice y así asegurar las proporciones definidas de los datos de entrenamiento y prueba.

set.seed(1984)
ind<-sample(2, nrow(BicisML), replace=TRUE, prob=c(0.67, 0.33))

Seguidamente, se usará la variable ind para dividir finalmente el conjunto de datos en entrenamiento y prueba. En los datos de prueba y de entrenamiento no se ha incluido la variable LESIVIDAD que es el objetivo de la clasificación.

Bicis.training<-BicisML_norm[ind==1,]
Bicis.training<-as.data.frame(Bicis.training)
Bicis.test<-BicisML_norm[ind==2,]
Bicis.test<-as.data.frame(Bicis.test)

Por último, se almacena de forma separada la etiqueta de las clases que es en este caso la variable LESIVIDAD y se debe incluir también en el algoritmo KNN.

Bicis.trainlabels<-BicisML[ind==1, "LESIVIDAD"]
Bicis.trainlabels<-as.data.frame(Bicis.trainlabels)
Bicis.trainlabels<-Bicis.trainlabels[,1, drop = TRUE]

Bicis.testlabels<-BicisML[ind==2, "LESIVIDAD"]
Bicis.testlabels<-as.data.frame(Bicis.testlabels)
Bicis.testlabels<-Bicis.testlabels[,1, drop = TRUE]

A partir de este momento se puede comenzar el entrenamiento del algoritmo KNN. Para ello se activará el paquete class y la función KNN, tomando como valor de referencia a los 3 vecinos más próximos (k=3).

library("class", lib.loc="C:/Program Files/R/R-3.5.3/library")
Bicis.pred.k3<-knn(train=Bicis.training, test=Bicis.test, cl=Bicis.trainlabels, k=3)

Una vez construido el modelo, se evaluará su comportamiento. Para ello se usará la función CrossTable() de paquete gmodels y se calculará la tabla de tabulación cruzada o contingencia. En esta tabla las predicciones correctas figuran en la diagonal de la matriz y las incorrectas en el resto de posiciones.

library("gmodels", lib.loc="~/R/win-library/3.5")
CrossTable(x= Bicis.testlabels, y=Bicis.pred.k3, prop.chisq=FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Row Total |
## |           N / Col Total |
## |         N / Table Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  1141 
## 
##  
##                  | Bicis.pred.k3 
## Bicis.testlabels |        IL |        HL |        HG | Row Total | 
## -----------------|-----------|-----------|-----------|-----------|
##               IL |        17 |        79 |         0 |        96 | 
##                  |     0.177 |     0.823 |     0.000 |     0.084 | 
##                  |     0.378 |     0.074 |     0.000 |           | 
##                  |     0.015 |     0.069 |     0.000 |           | 
## -----------------|-----------|-----------|-----------|-----------|
##               HL |        23 |       894 |        26 |       943 | 
##                  |     0.024 |     0.948 |     0.028 |     0.826 | 
##                  |     0.511 |     0.839 |     0.839 |           | 
##                  |     0.020 |     0.784 |     0.023 |           | 
## -----------------|-----------|-----------|-----------|-----------|
##               HG |         5 |        92 |         4 |       101 | 
##                  |     0.050 |     0.911 |     0.040 |     0.089 | 
##                  |     0.111 |     0.086 |     0.129 |           | 
##                  |     0.004 |     0.081 |     0.004 |           | 
## -----------------|-----------|-----------|-----------|-----------|
##               MT |         0 |         0 |         1 |         1 | 
##                  |     0.000 |     0.000 |     1.000 |     0.001 | 
##                  |     0.000 |     0.000 |     0.032 |           | 
##                  |     0.000 |     0.000 |     0.001 |           | 
## -----------------|-----------|-----------|-----------|-----------|
##     Column Total |        45 |      1065 |        31 |      1141 | 
##                  |     0.039 |     0.933 |     0.027 |           | 
## -----------------|-----------|-----------|-----------|-----------|
## 
## 

Del total de 1.141 observaciones del conjunto de datos de prueba el modelo ha predecido correctamente 915 lo que supone un 80,2% de aciertos. Estos resultados indican a priori un buen comportamiento del modelo.

Sin embargo, si se estudia el detalle por desglose de las categorías de LESIVIDAD se observan resultados muy dispares:

  • Ilesos 17 predicciones correctas de 96 (17,7% de aciertos)
  • Heridos leves 894 predicciones correctas de 943 (94,8 % de aciertos)
  • Heridos graves 4 predicciones correctas de 101 (4,0% de aciertos)
  • Muertos 0 predicciones correctas de 1 (0% de aciertos)

Este desglose constata que el modelo funciona muy bien para predecir heridos leves, pero es muy impreciso en el caso de ilesos, heridos graves o muertos.

Parte del problema puede ser debido a que existen muchos más heridos leves en el dataset que la suma de ilesos, heridos graves y fallecidos, dificultando el entrenamiento del modelo para estas categorías.

A continuación se realizan distintas iteraciones del algoritmo KNN cambiando el parametro k, desde k=1 a k=7 y se analizan los resultados. Se omite el codigo en R de estas iteraciones por limitación de espacio, si bien figura en el Anexo_Codigo_R.

Al aumentar el número de vecinos próximos la precisión global del modelo parece que aumenta ligeramente (82,0% de aciertos con k=5, 81,8% con k=6 y 82,6% con k=7). Sin embargo, las diferencias de precisión en la predicción de las distintas clases se acentuan aún más, puesto que en estos modelos no consiguen predecir correctamente ningún herido grave o muerto.

Por el contrario, si se reduce el número de vecinos próximos la precisión global del modelo disminuye sustancialmente (74,1% de aciertos con k=1 y 72,5% con k=2) si bien la predicción de las distintas clases mejora, especialmente la predicción de ilesos y heridos graves, que eran las de menor precisión en el modelo original.

En el caso de k=1 el detalle de predicciones es el siguiente:

  • Ilesos 25 predicciones correctas de 96 (26,0% de aciertos)
  • Heridos leves 810 predicciones correctas de 943 (85,9 % de aciertos)
  • Heridos graves 11 predicciones correctas de 101 (11,0% de aciertos)
  • Muertos 0 predicciones correctas de 1 (0% de aciertos)
CrossTable(x= Bicis.testlabels, y=Bicis.pred.k1, prop.chisq=FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Row Total |
## |           N / Col Total |
## |         N / Table Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  1141 
## 
##  
##                  | Bicis.pred.k1 
## Bicis.testlabels |        IL |        HL |        HG |        MT | Row Total | 
## -----------------|-----------|-----------|-----------|-----------|-----------|
##               IL |        25 |        65 |         5 |         1 |        96 | 
##                  |     0.260 |     0.677 |     0.052 |     0.010 |     0.084 | 
##                  |     0.269 |     0.068 |     0.056 |     1.000 |           | 
##                  |     0.022 |     0.057 |     0.004 |     0.001 |           | 
## -----------------|-----------|-----------|-----------|-----------|-----------|
##               HL |        60 |       810 |        73 |         0 |       943 | 
##                  |     0.064 |     0.859 |     0.077 |     0.000 |     0.826 | 
##                  |     0.645 |     0.846 |     0.811 |     0.000 |           | 
##                  |     0.053 |     0.710 |     0.064 |     0.000 |           | 
## -----------------|-----------|-----------|-----------|-----------|-----------|
##               HG |         8 |        82 |        11 |         0 |       101 | 
##                  |     0.079 |     0.812 |     0.109 |     0.000 |     0.089 | 
##                  |     0.086 |     0.086 |     0.122 |     0.000 |           | 
##                  |     0.007 |     0.072 |     0.010 |     0.000 |           | 
## -----------------|-----------|-----------|-----------|-----------|-----------|
##               MT |         0 |         0 |         1 |         0 |         1 | 
##                  |     0.000 |     0.000 |     1.000 |     0.000 |     0.001 | 
##                  |     0.000 |     0.000 |     0.011 |     0.000 |           | 
##                  |     0.000 |     0.000 |     0.001 |     0.000 |           | 
## -----------------|-----------|-----------|-----------|-----------|-----------|
##     Column Total |        93 |       957 |        90 |         1 |      1141 | 
##                  |     0.082 |     0.839 |     0.079 |     0.001 |           | 
## -----------------|-----------|-----------|-----------|-----------|-----------|
## 
## 

Por estos motivos parece que el modelo con k=1 es el más equilibrado y recomendable, dentro de las opciones disponibles y teniendo en cuenta que ninguna es capaz de clasificar correctamente en las cuatro categorías de lesividad.

4.2. Random Forest

El segundo modelo de machine learning se va a desarrollar usando un algoritmo de clasificación Random Forest, que se basa en una combinación de árboles predictores, tal que cada árbol depende de los valores de un vector aleatorio probado independientemente y con la misma distribución para cada uno de estos.

En primer lugar se carga el paquete randomForest.

library("randomForest", lib.loc="~/R/win-library/3.5")
## randomForest 4.6-14
## Type rfNews() to see new features/changes/bug fixes.
## 
## Attaching package: 'randomForest'
## The following object is masked from 'package:ggplot2':
## 
##     margin

Se aprovechan la separación entre datos de entrenamiento y prueba realizada para el algoritmo KNN en el capítulo anterior y se construye un randomForest learning tree con 100 árboles.

Bicis.RF.training=cbind(Bicis.training, Bicis.trainlabels)
setnames(Bicis.RF.training, "Bicis.trainlabels", "LESIVIDAD")

Bicis.RF.model<-randomForest(formula = LESIVIDAD ~ .,data = Bicis.RF.training, ntree=100,proximity=TRUE)

Bicis.RF.model
## 
## Call:
##  randomForest(formula = LESIVIDAD ~ ., data = Bicis.RF.training,      ntree = 100, proximity = TRUE) 
##                Type of random forest: classification
##                      Number of trees: 100
## No. of variables tried at each split: 2
## 
##         OOB estimate of  error rate: 15.05%
## Confusion matrix:
##     IL   HL HG MT class.error
## IL 125   92  0  0   0.4239631
## HL  64 1947  4  0   0.0337469
## HG   4  199  0  0   1.0000000
## MT   0    4  0  0   1.0000000

El clasificador construido a partir de los datos de entrenamiento tiene un error global a priori aceptable (15,05%), sin embargo cuando se estudia el detalle de cada categoría se observan resultados muy dispersos.

Teniendo en cuenta esta situación, se prueba el modelo con los datos de test y se analizan los resultados.

RFpred<- predict(Bicis.RF.model,Bicis.test)
table(observacion=Bicis.testlabels,prediccion=RFpred)
##            prediccion
## observacion  IL  HL  HG  MT
##          IL  61  35   0   0
##          HL  35 908   0   0
##          HG   6  95   0   0
##          MT   0   1   0   0

El modelo Random Forest arroja unas conclusiones similares a las obtenidas mediante el algoritmo KNN, visto en el capítulo anterior.

  • Ilesos 61 predicciones correctas de 96 (63,5% de aciertos)
  • Heridos leves 908 predicciones correctas de 943 (96,3 % de aciertos)
  • Heridos graves 0 predicciones correctas de 101 (0% de aciertos)
  • Muertos 0 predicciones correctas de 1 (0% de aciertos)

Se puede concluir que el modelo clasifica muy bien los heridos leves y aceptablemente bien los ileso pero es incapaz de clasificar los heridos graves o muertos.

5. Conclusiones

Este estudio ha analizado los accidentes de tráfico en la ciudad de Madrid registrados por la Policía Municipal, en los que está implicada al menos una bicicleta, entre los años 2014 y 2018, obteniendose varias conclusiones destacables tanto en el análisis descriptivo como en el análisis con técnicas de machine learning.

5.1 Conclusiones análisis descriptivo

El número total de accidentes no ha variado de forma significativa en el periodo estudiado para el global de los 21 distritos de Madrid, manteniendose en la horquilla de 650 a 750 accidentes anuales.

El distrito Centro es donde ocurren más accidentes con respecto a cualquier otro distrito. En concreto, en el distrito Centro sucedieron 551 accidentes entre 2014 y 2018, mientras que el siguiente distrito con mayor número de siniestros en el mismo periodo fue Retiro con 281 accidentes, una cifra mucho menor.

Además se aprecia una tendencia en aumento del número de accidentes en el distrito Centro desde 2014 a 2018. Puesto que la cifra global de siniestros para todo Madrid se mantiene razonablemente estable, se puede concluir que se está produciendo un fenómeno de concentración de los accidentes en centro de la ciudad.

No se dispone de datos en el estudio que expliquen los motivos pero tal vez se podría considerar que están relacionados con el mayor tráfico de bicicletas en la zona centro de Madrid, el uso de bicicletas por turistas o personas poco acostumbradas a transitar en bicicleta, etc…

Con respecto a la incidencia diaria y horaria, se observa que los jueves por la tarde es el momento en el que se producen un mayor número de accidentes.

Se observa también una ligera disminución en el número de accidentes en fin de semana y lunes. Así como que en días laborables ocurren más siniestros a mediodía y por la tarde, mientras que en fin de semana se ocasionan un mayor número de accidentes por la mañana.

El perfil mayoritario de la persona accidentada es un varón de entre 25 y 35 años, resultando herido leve como consecuencia del accidente. Es interesante destacar que tan sólo un 20% de las personas accidentadas son mujeres, en una franja de edad similar y resultando también en su mayoría heridas leves.

Los tipos de accidente más comunes son las caídas de las bicicletas y las colisiones dobles. La mayoría de las victimas resultan heridas leves cuando suceden este tipo de accidentes.

Por último, al estudiar al estado de la calzada, no se puede afirmar que las tipologías de accidentes varíen significativamente en función del estado de la misma. No obstante, si que se percibe una mayor proporción relativa de heridos graves cuando la calzada está mojada si se compara con las condiciones de calzada seca.

5.2 Conclusiones Machine Learning

Se han creado dos modelos de predicción usando técnicas de machine learning, mediante aprendizaje supervisado, para predecir el grado de lesividad de las victimas de un accidente de bicicleta ocurrido en Madrid. En concreto estos modelos se han desarrollado usando los algoritmos de clasificación KNN y Random Forest, y han producido resultados similares.

Los resultados obtenidos no han sido completamente satisfactorios, puesto que los modelos sólo han sabido predecir con una alta tasa de acierto aquellos accidentes que resultan en heridos leves y algún caso de ilesos, pero no han sido capaces de predecir con acierto aquellos accidentes que resultan en heridos graves o muertos.

Es posible que parte del problema se deba a la hetereogeneidad de los datos. Existen muchos más heridos leves en el dataset que la suma de ilesos, heridos graves y fallecidos, dificultando el entrenamiento del modelo para estas últimas categorías.

En todo caso para una futura fase de estudio sería recomendable abordar el problema con otro enfoque, obteniendo más series temporales, descartando o añadiendo nuevas variables, etc… de tal forma que permitiesen obtener una predicción más acertada en general y especialmente de heridos graves y muertos.