La tarificación de seguros de automóvil ha dependido tradicionalmente de un conjunto establecido de factores de riesgo, como la edad del conductor, el tipo de vehículo, el historial de siniestralidad y la ubicación geográfica general, a menudo definida por códigos postales o divisiones administrativas amplias. Sin embargo, la industria aseguradora está experimentando una transformación significativa impulsada por la disponibilidad de grandes volúmenes de datos y avances en la capacidad analítica. Existe un reconocimiento creciente de que el riesgo no es homogéneo dentro de estas grandes zonas geográficas y que factores de localización mucho más granulares pueden influir significativamente en la probabilidad y severidad de los siniestros. Los actuarios ahora tienen acceso a “vastas cantidades de información que pueden aprovecharse para impulsar una tarificación más precisa, una mejor evaluación de riesgos y mejores conocimientos del cliente”. Este cambio hacia la utilización de “big data” y fuentes de datos alternativas está redefiniendo la ciencia actuarial y abriendo nuevas vías para la diferenciación de riesgos.
Esta evolución es particularmente pertinente para los seguros de automóvil, donde la ubicación del vehículo, tanto cuando está estacionado (lugar de pernocta) como durante su uso, está intrínsecamente ligada a la exposición a diversos peligros como accidentes de tráfico, robos o vandalismo. La capacidad de incorporar datos geoespaciales detallados en los modelos de tarificación promete una evaluación del riesgo más matizada y, en última instancia, primas más justas y competitivas. La transición de zonas de tarificación amplias a microzonas basadas en características específicas del entorno local representa un avance sustancial en la precisión de la tarificación.
OpenStreetMap (OSM) emerge como un recurso geoespacial de particular interés en este contexto. OSM es un proyecto global, colaborativo y de código abierto dedicado a crear un mapa del mundo editable y gratuito. Su base de datos contiene una enorme cantidad de información geográfica, que incluye redes de carreteras, edificios, usos del suelo y puntos de interés (POIs), aportada y mantenida por una comunidad de voluntarios. En mercados emergentes como Venezuela, donde los datos geoespaciales comerciales pueden ser prohibitivamente caros, estar desactualizados o ser simplemente inaccesibles para muchas aseguradoras, OSM ofrece una alternativa valiosa y de bajo costo. La riqueza de la información disponible en OSM, que puede incluir “características de las edificaciones como tipo de construcción, número de niveles, material de construcción, etc.”, lo convierte en una herramienta “poderosa para el análisis y modelado de la exposición”.
Sin embargo, la naturaleza colaborativa y voluntaria de OSM también implica una variabilidad inherente en la calidad y completitud de sus datos. Se advierte que “puede haber variación de un lugar a otro en la calidad y completitud de estos datos”. Esta variabilidad es una consideración crítica que debe abordarse al utilizar OSM para aplicaciones analíticas como la tarificación de seguros. La densidad y precisión de los datos pueden diferir significativamente entre áreas urbanas y rurales, o incluso entre diferentes barrios dentro de una misma ciudad. Esta característica de OSM no disminuye su potencial, pero sí subraya la necesidad de procesos de validación y un entendimiento claro de las limitaciones de los datos en cualquier análisis. La combinación de OSM, una fuente de datos abierta y gratuita, con R, un lenguaje de programación de código abierto, tiene el potencial de democratizar el acceso a técnicas sofisticadas de evaluación de riesgos geoespaciales. Tradicionalmente, las herramientas analíticas y los datos geoespaciales pueden representar una barrera de costo significativa. Al aprovechar OSM y R, se reduce considerablemente esta barrera de entrada, lo cual es especialmente valioso para aseguradoras más pequeñas o nuevos actores en mercados con recursos limitados como Venezuela. No obstante, esta dependencia de OSM introduce una nueva dimensión de riesgo en los modelos actuariales: el “riesgo de calidad de los datos”. Este es distinto del riesgo de modelo o del riesgo de parámetro y requiere una gestión cuidadosa. Si los datos de OSM para una zona específica en Venezuela son deficientes, cualquier factor de riesgo derivado de ellos será poco fiable, lo que se traduce en un riesgo operativo o de modelo específico: el riesgo de tarificación incorrecta debido a imprecisiones en los datos geoespaciales fundamentales. Esto podría implicar la necesidad de que las aseguradoras inviertan en validar o mejorar los datos locales de OSM, o en desarrollar métodos para cuantificar la incertidumbre derivada de la calidad de dichos datos.
Uno de los principales desafíos al desarrollar modelos de tarificación de seguros, especialmente en ciertos mercados, es la dificultad para obtener conjuntos de datos de siniestros históricos completos, detallados y públicamente disponibles. La información sobre pólizas y siniestros suele ser propietaria y altamente sensible. En el contexto venezolano, acceder a un conjunto de datos de este tipo para un estudio público es improbable. Para superar este obstáculo y aun así poder demostrar la metodología de integración de datos geoespaciales en la tarificación, la simulación de datos se presenta como un enfoque pragmático y efectivo. La simulación permite crear un conjunto de datos sintético que, si bien no replica perfectamente la realidad, puede diseñarse para poseer características y distribuciones estadísticamente plausibles, similares a las que se encontrarían en una cartera de seguros real.
El objetivo de la simulación no es predecir con exactitud el mercado venezolano, sino construir un entorno de datos controlados donde se puedan desarrollar, probar e ilustrar las técnicas de ingeniería de características geoespaciales y modelado predictivo. Al simular información de pólizas, vehículos, conductores y siniestros, se puede crear una base sobre la cual superponer y evaluar el valor predictivo de los factores de riesgo derivados de OSM.
El objetivo principal de este estudio de caso es demostrar un flujo de trabajo práctico y reproducible para la tarificación de seguros de automóvil en Venezuela, integrando características geoespaciales derivadas de OpenStreetMap con datos de pólizas y siniestros simulados, utilizando R como herramienta principal de análisis. Se busca ilustrar cómo los datos de OSM pueden ser procesados, transformados en indicadores de riesgo cuantificables y luego incorporados en modelos actuariales estándar, como los Modelos Lineales Generalizados (GLM), para mejorar la segmentación del riesgo.
El alcance de este estudio es metodológico. Se centrará en los aspectos técnicos de la adquisición de datos, la ingeniería de características, el análisis exploratorio de datos (EDA), la construcción del modelo y la interpretación de resultados. Se proporcionarán fragmentos de código R ilustrativos y se discutirán los resultados generados en cada etapa. Es importante destacar que este estudio no pretende ser un análisis exhaustivo del mercado de seguros venezolano ni producir una tarifa lista para su implementación comercial inmediata. Más bien, busca ofrecer una guía detallada y fundamentada sobre cómo se pueden aprovechar fuentes de datos geoespaciales abiertas y herramientas de código abierto para avanzar hacia una tarificación más granular y basada en datos. Las conclusiones sobre el poder predictivo de ciertas características de OSM estarán condicionadas por la naturaleza de los datos de siniestros simulados.
osmdata para la Recuperación de Datos
de OSMPara interactuar con la vasta base de datos de OpenStreetMap y
extraer la información geoespacial necesaria, se utilizará el paquete de
R osmdata. Esta herramienta simplifica enormemente el
proceso de descarga y estructuración de datos de OSM. Permite a los
usuarios construir consultas complejas para obtener datos como redes
viales, huellas de edificios, puntos de interés (POIs), entre otros, y
los convierte directamente en objetos del paquete sf
(Simple Features), el estándar para el análisis de datos geoespaciales
en R.
El primer paso práctico implica la selección de una región específica dentro de Venezuela. Para este ejemplo, se utilizará Caracas.
El código R para esta etapa implicaría el uso de funciones de
osmdata como opq para definir el área de
interés (bounding box) y add_osm_feature para especificar
las características a descargar. Luego, osmdata_sf
convierte los datos descargados a objetos sf.
Salida Inicial: El resultado de esta etapa serían varios
objetos sf: uno para la red vial, y otros para las
diferentes categorías de características extraídas (polígonos de
edificios, puntos o polígonos de POIs).
Los datos crudos de OSM a menudo requieren una limpieza y preparación. Los pasos comunes incluyen: * Verificación y manejo de geometrías faltantes o inválidas. * Asegurar un Sistema de Coordenadas de Referencia (CRS) consistente, usualmente reproyectando a un CRS proyectado adecuado para mediciones de distancia y área (p.ej., una zona UTM apropiada para la región venezolana seleccionada, como UTM zona 20N, EPSG:32620). * Filtrado de datos irrelevantes o selección de atributos específicos de interés.
Salida Inicial: Objetos sf limpios y
proyectados, listos para la ingeniería de características.
Tabla 1: Descripción de las Capas Clave de Datos de OpenStreetMap Utilizadas
| Tipo de Elemento OSM | Etiquetas Clave de OSM Utilizadas (Ejemplos) | Descripción de los Datos | Relevancia Potencial para el Riesgo de Seguro de Automóvil |
|---|---|---|---|
highway |
highway=primary, motorway,
residential |
Red de carreteras, clasificadas por tipo y jerarquía. | Indica volumen de tráfico, límites de velocidad, complejidad de la red, conectividad. |
building |
building=yes, commercial,
residential |
Huellas de edificios, a veces con tipo de uso. | Densidad urbana, tipo de entorno (residencial, comercial), que puede correlacionar con riesgo de robo o vandalismo. |
amenity |
amenity=bar, school,
hospital |
Puntos de Interés (POIs) de diversos tipos. | Proximidad a bares (riesgo de conducción bajo influencia), escuelas (zonas peatonales), hospitales (posibles zonas de accidentes previos o mayor tráfico). |
junction |
(Derivado de la red vial) | Intersecciones de carreteras. | Puntos de conflicto potencial, mayor riesgo de colisión. La complejidad de la intersección puede ser un factor. |
landuse |
landuse=commercial,
industrial, retail |
Uso del suelo predominante en áreas. | Caracterización general del entorno, que puede influir en patrones de tráfico y tipos de riesgo. |
La falta de datos públicos de siniestros en Venezuela hace necesaria la simulación. El objetivo es crear un conjunto de datos plausible que refleje las características de una cartera de seguros de automóvil, utilizando distribuciones estadísticas razonables.
La cartera simulada incluirá información de la póliza, vehículo, conductor, ubicación de pernocta (coordenadas) y datos de siniestros (frecuencia y severidad).
dplyr y
sfLa generación se realizaría en R usando dplyr para la
manipulación de datos y las funciones base de R para la generación de
números aleatorios a partir de distribuciones como Poisson (para
frecuencia) y Gamma (para severidad).
Salida Inicial: Un objeto sf conteniendo la
cartera de seguros simulada, con cada fila representando una póliza y
columnas para todas las características.
Para añadir realismo, la propensión a siniestros (el parámetro \({\lambda}\) de la distribución de Poisson) variará en función de características simuladas como la edad del conductor. La severidad promedio también puede estar correlacionada con el valor del vehículo, utilizando distribuciones sesgadas como Gamma o Lognormal.
Tabla 2: Estructura de los Datos Simulados de la Cartera de Seguros
| Nombre del Campo | Tipo de Dato | Descripción/Ejemplo | Lógica de Simulación (Ejemplos) |
|---|---|---|---|
PolicyID |
Cadena | Identificador único de póliza (p.ej., VENPOL00001) | Secuencial o aleatorio único |
DriverAge |
Entero | Edad del conductor en años (p.ej., 35) | runif(n, 20, 75) o
truncnorm |
VehicleAge |
Entero | Antigüedad del vehículo en años (p.ej., 8) | rpois(n, lambda=7) + 1 |
VehicleValue |
Numérico | Valor del vehículo en una unidad monetaria (p.ej., 5000) | rlnorm(n, meanlog=8, sdlog=0.5) |
geometry |
Geometría sf |
Punto (lat, lon) del lugar de pernocta | Aleatorio dentro de los límites de la región de estudio. |
ClaimCount |
Entero | Número de siniestros en el período de la póliza (p.ej., 0, 1, 2) | rpois(n, lambda), donde \({\lambda}\) depende de
DriverAge. |
TotalClaimAmount |
Numérico | Monto total de los siniestros incurridos (p.ej., 0, 1250.75) | Si ClaimCount > 0, suma de sorteos de
rgamma(n, shape=2, scale=500). |
VehicleType |
Factor | Tipo de vehículo (p.ej., Sedán, SUV, Camioneta) | Muestreo aleatorio de una lista predefinida con probabilidades. |
CoverageType |
Factor | Tipo de cobertura (p.ej., Responsabilidad Civil, Todo Riesgo) | Muestreo aleatorio de una lista predefinida. |
Esta etapa se enfoca en crear variables predictivas cuantificando el entorno de riesgo alrededor de cada póliza usando los datos de OSM.
El objetivo es transformar los elementos de OSM en métricas numéricas que sirvan como indicadores de riesgo. Ejemplos incluyen: densidad de la red vial, complejidad de intersecciones, proximidad a POIs específicos (bares, escuelas), y densidad de edificios.
sfLa implementación se realizaría en R, aprovechando las capacidades
del paquete sf. * Operaciones de buffer:
st_buffer para crear zonas de influencia. *
Intersecciones espaciales y conteos:
st_intersects y st_length para contar
elementos y calcular longitudes dentro de los buffers. *
Cálculos de distancia: st_distance para
calcular la distancia al elemento más cercano.
Salida: El sf data frame de la cartera ahora
incluirá nuevas columnas, cada una representando una característica
geoespacial derivada de OSM.
El proceso de cálculo de características por póliza ya vincula los
datos. Si las características se calcularan por zonas, se usaría
st_join para asignarlas a cada póliza.
Se deben aplicar estrategias para manejar valores NA
(imputación). Variables sesgadas pueden requerir transformaciones (log,
raíz cuadrada) para estabilizar la varianza, lo que puede beneficiar a
los GLM. También se debe revisar la multicolinealidad entre las nuevas
características.
Salida: Un sf data frame unificado y
preprocesado, listo para el EDA y el modelado.
Tabla 3: Resumen de las Características Diseñadas (Geoespaciales y Otras)
| Nombre de la Característica | Descripción | Fuente | Unidad de Medida (Ejemplo) |
|---|---|---|---|
RoadDensity_500m |
Longitud total de carreteras (en metros) dentro de un buffer de 500m. | OSM | metros |
DistToNearestBar |
Distancia (en metros) al bar o local nocturno más cercano. | OSM | metros |
IntersectionCount_1km |
Número de intersecciones de carreteras dentro de un buffer de 1km. | OSM | conteo |
BuildingDensity_250m |
Porcentaje del área dentro de un buffer de 250m ocupada por edificios. | OSM | porcentaje (%) |
POICount_School_500m |
Número de escuelas dentro de un buffer de 500m. | OSM | conteo |
DriverAge |
Edad del conductor. | Simulada | años |
VehicleAge |
Antigüedad del vehículo. | Simulada | años |
VehicleValue |
Valor estimado del vehículo. | Simulada | unidad monetaria |
ClaimCount (Objetivo) |
Número de siniestros durante el período de la póliza. | Simulada | conteo |
TotalClaimAmount (Objetivo) |
Monto total de los siniestros (si
ClaimCount > 0). |
Simulada | unidad monetaria |
El EDA es fundamental para comprender los datos, identificar patrones y verificar relaciones entre las características y las variables objetivo.
leaflet para Mapeo InteractivoPara la visualización geoespacial, el paquete de R
leaflet es una excelente opción. Permite crear mapas
interactivos y superponer datos como marcadores, polígonos coloreados
(mapas coropléticos) y mapas de calor.
Se utilizaría leaflet para generar mapas interactivos de
la región, visualizando la distribución espacial de las características
de OSM. Por ejemplo, un mapa de calor mostrando la concentración de
siniestros.
Salida: Mapas interactivos que permiten explorar visualmente la distribución espacial de los factores de riesgo.
Superponer las ubicaciones de los siniestros simulados sobre los mapas de características de OSM permite una inspección visual preliminar de posibles correlaciones.
Se calcularán estadísticas descriptivas y se visualizarán las
distribuciones de las variables clave mediante histogramas y gráficos de
densidad usando ggplot2.
Se explorarán las relaciones entre cada predictora y las variables objetivo (frecuencia y severidad) mediante gráficos y pruebas estadísticas.
Se generará una matriz de correlación de todas las predictoras para
detectar posible multicolinealidad. Se pueden calcular los Factores de
Inflación de la Varianza (VIF) con el paquete car.
Se procede al desarrollo del modelo predictivo que relaciona las características con la frecuencia y severidad de los siniestros.
Los GLM son el estándar en la industria aseguradora por su interpretabilidad, robustez y capacidad para manejar respuestas no normales.
Es práctica común modelar la frecuencia y la severidad por separado. La prima pura se calcula como: \({Prima Pura = Frecuencia \times Severidad}\). * Modelo de Frecuencia: GLM de Poisson con enlace logarítmico. * Modelo de Severidad: GLM Gamma con enlace logarítmico.
offset.glm() para la Implementación de
GLMLa función base glm() de R es la herramienta estándar
para ajustar GLMs.
Se especificará la fórmula del modelo utilizando la sintaxis de R:
respuesta ~ predictor1 + predictor2 + ... + offset(log(exposicion)).
El proceso de modelado incluirá: 1. División de datos: Separar los datos en conjuntos de entrenamiento y prueba. 2. Ajuste del modelo de frecuencia: Ajustar un GLM de Poisson. 3. Ajuste del modelo de severidad: Ajustar un GLM Gamma sobre los siniestros con costo positivo.
Salida: Dos objetos de modelo glm entrenados:
uno para frecuencia y otro para severidad.
Se evalúa el rendimiento del modelo, se interpretan los resultados y se construye una estructura de tarifas ilustrativa.
Se utilizarán métricas como la Devianza, el AIC (Criterio de Información de Akaike) y se analizarán los residuos para evaluar la bondad de ajuste.
La evaluación más importante se realiza en el conjunto de prueba. Gráficos de Ganancia (Lift Charts) son muy útiles para evaluar la capacidad del modelo para diferenciar el riesgo.
Se utilizarán las salidas de los objetos glm y paquetes
como ggplot2 para generar los gráficos de validación.
Salida: Tablas resumiendo las métricas y gráficos de diagnóstico y validación.
Se examinarán los coeficientes estimados (\({\beta}\)), su signo, magnitud y significancia estadística (valor p). La exponenciación de los coeficientes (\(e^{\beta_k}\)) proporciona la “Razón de Tasas” (Rate Ratio), que es fácil de interpretar.
Se identifican las características con un impacto estadísticamente significativo en la frecuencia y/o severidad.
Tabla 4: Coeficientes del Modelo GLM y Significancia (Ejemplo para Frecuencia)
| Característica | Estimación (\({\beta}\)) | Error Est. | Valor z | Pr(> | z |
|---|---|---|---|---|---|
| (Intercept) | -3.50 | 0.15 | -23.33 | <0.001 | 0.030 |
DriverAge |
-0.02 | 0.005 | -4.00 | <0.001 | 0.980 |
VehicleAge |
0.05 | 0.01 | 5.00 | <0.001 | 1.051 |
RoadDensity_500m |
0.0002 | 0.00005 | 4.00 | <0.001 | 1.0002 |
DistToNearestBar |
-0.001 | 0.0003 | -3.33 | <0.001 | 0.999 |
| (Otras) | … | … | … | … | … |
\({Predicción~Prima~Pura = Predicción~Frecuencia \times Predicción~Severidad}\).
Los coeficientes del modelo se utilizan para derivar factores de tarificación relativos a un perfil base.
Se puede escribir una función en R que tome perfiles hipotéticos y calcule la prima pura para cada uno, mostrando el impacto de las variables geoespaciales.
Salida: Una tabla mostrando las primas puras para diferentes perfiles.
Tabla 5: Diferenciales de Tarifa Ilustrativos
| Perfil de Referencia Prima Pura Base: \(P_0\) | |||
|---|---|---|---|
| Factor de Riesgo | Nivel 1 | Nivel 2 | Nivel 3 |
| Relatividad | Relatividad | Relatividad | |
| Banda de Edad | Joven (1.50 x \(P_0\)) | Medio (1.00 x \(P_0\)) | Mayor (0.90 x \(P_0\)) |
| Densidad Vial (OSM) | Baja (0.92 x \(P_0\)) | Media (1.00 x \(P_0\)) | Alta (1.15 x \(P_0\)) |
| Proximidad a Bares (OSM) | Lejos (0.95 x \(P_0\)) | Moderada (1.00 x \(P_0\)) | Cerca (1.10 x \(P_0\)) |
La calidad variable de OSM es una preocupación clave. Se pueden aplicar estrategias como enfocarse en centros urbanos o desarrollar indicadores de completitud de datos.
Los resultados dependen críticamente del realismo de la simulación. La validación con datos reales es indispensable para una aplicación comercial.
El uso de características geoespaciales conlleva el riesgo de introducir sesgos. Las características de OSM podrían correlacionarse con variables socioeconómicas, llevando a una tarificación que podría ser percibida como injusta (redlining).
Se demostró una metodología completa para la tarificación de seguros de automóvil integrando datos de OSM en R. Los resultados ilustran el potencial de las características geoespaciales para una segmentación de riesgo más granular.
Este documento presenta un flujo de trabajo completo para el análisis de riesgos en una cartera de seguros de automóviles. Compara un enfoque de tarificación tradicional con un modelo avanzado que utiliza datos geoespaciales de OpenStreetMap (OSM) y de comportamiento del conductor (telemática) para construir modelos más precisos y justos.
El análisis se centra en Caracas, Venezuela, y abarca desde la adquisición de datos y simulación de la cartera, hasta la ingeniería de características, el modelado y, finalmente, una comparación directa entre ambos enfoques de tarificación.
Primero, instalamos (si es necesario) y cargamos todas las librerías que se utilizarán a lo largo del análisis.
# Lista de paquetes requeridos
packages <- c("osmdata", "sf", "dplyr", "ggplot2", "leaflet", "leaflet.extras", "htmlwidgets", "viridis", "broom", "scales", "knitr")
# Instalar paquetes que no estén ya instalados
installed_packages <- packages %in% rownames(installed.packages())
if (any(installed_packages == FALSE)) {
install.packages(packages[!installed_packages])
}
# Cargar todas las librerías
invisible(lapply(packages, library, character.only = TRUE))
# Configurar tema para los gráficos de ggplot2
theme_set(theme_bw())En esta sección, descargamos los datos geoespaciales que servirán de base para nuestro análisis. Para garantizar que el código se pueda ejecutar siempre, definimos el área de interés (bounding box) de Caracas manualmente.
Descargamos tres tipos de datos: 1. Red Vial
(highway): Calles, avenidas y autopistas. 2.
Puntos de Interés (amenity): Bares, pubs,
discotecas y escuelas. 3. Huellas de Edificios
(building): Polígonos que representan las
construcciones.
place_name <- "Caracas, Venezuela"
bb <- matrix(c(-67.1, 10.3, -66.7, 10.6), nrow = 2, ncol = 2,
dimnames = list(c("x", "y"), c("min", "max")))
# CRS proyectado para Venezuela (UTM Zone 20N)
crs_utm <- st_crs(32620)
# 1. Red vial
q_roads <- opq(bbox = bb) %>% add_osm_feature(key = "highway")
osm_roads <- osmdata_sf(q_roads)
roads_sf <- osm_roads$osm_lines %>% st_transform(crs_utm)
# 2. Puntos de Interés (POIs)
q_pois <- opq(bbox = bb) %>% add_osm_feature(key = "amenity", value = c("bar", "pub", "nightclub", "school", "kindergarten"))
osm_pois <- osmdata_sf(q_pois)
pois_sf <- bind_rows(
osm_pois$osm_points %>% select(osm_id, amenity),
st_centroid(osm_pois$osm_polygons) %>% select(osm_id, amenity)
) %>%
st_transform(crs_utm)
# 3. Huellas de edificios
q_buildings <- opq(bbox = bb) %>% add_osm_feature(key = "building")
osm_buildings <- osmdata_sf(q_buildings)
buildings_sf <- osm_buildings$osm_polygons %>% st_transform(crs_utm)
cat(sprintf("Datos de OSM obtenidos:\n- Tramos viales: %d\n- POIs: %d\n- Edificios: %d\n",
nrow(roads_sf), nrow(pois_sf), nrow(buildings_sf)))## Datos de OSM obtenidos:
## - Tramos viales: 35520
## - POIs: 4060
## - Edificios: 39189
El siguiente mapa muestra los datos que hemos descargado, dándonos una idea de la estructura urbana de la zona de estudio.
ggplot() +
geom_sf(data = roads_sf, color = "grey50", alpha = 0.5, linewidth = 0.2) +
geom_sf(data = buildings_sf, fill = "khaki", color = NA) +
geom_sf(data = pois_sf, aes(color = amenity), size = 2, alpha = 0.8) +
scale_color_viridis_d(name = "Tipo de POI") +
labs(title = "Datos de OpenStreetMap para Caracas",
subtitle = "Vialidad, Edificios y Puntos de Interés",
caption = "Datos © Contribuidores de OpenStreetMap") +
theme_minimal()Simulamos una cartera con 10,000 pólizas. Incluimos características del conductor, del vehículo y una simulación detallada del comportamiento de manejo basada en factores telemáticos.
# Parámetros
num_policies <- 10000
set.seed(42)
# Límites UTM
bb_poly <- st_polygon(list(matrix(
c(-67.1, 10.3, -66.7, 10.3, -66.7, 10.6, -67.1, 10.6, -67.1, 10.3),
ncol = 2, byrow = TRUE
)))
bb_sfc_wgs84 <- st_sfc(bb_poly, crs = 4326)
bbox_utm <- st_bbox(st_transform(bb_sfc_wgs84, crs = crs_utm))
# --- SIMULACIÓN DETALLADA DE COMPORTAMIENTO ---
portfolio_df <- tibble(
PolicyID = paste0("VENPOL", sprintf("%05d", 1:num_policies)),
DriverAge = as.integer(runif(num_policies, 18, 75)),
VehicleAge = rpois(num_policies, lambda = 7) + 1,
VehicleValue = round(rlnorm(num_policies, meanlog = log(10000), sdlog = 0.5)),
AnnualMileage = as.integer(runif(num_policies, 5000, 30000)),
# 1. Simular eventos de riesgo individuales
HardBrakingEvents = rpois(num_policies, lambda = 3),
SpeedingEvents = rpois(num_policies, lambda = 5),
SharpTurnEvents = rpois(num_policies, lambda = 2),
NightDrivingPct = runif(num_policies, 0, 0.4), # % de manejo nocturno
Garaging_X_UTM = runif(num_policies, bbox_utm["xmin"], bbox_utm["xmax"]),
Garaging_Y_UTM = runif(num_policies, bbox_utm["ymin"], bbox_utm["ymax"]),
Exposure = 1
)
# 2. Calcular el puntaje de comportamiento (DrivingBehaviorScore)
# Comienza en 100 y se restan puntos por cada evento de riesgo.
portfolio_df <- portfolio_df %>%
mutate(
DrivingBehaviorScore = pmax(0, 100 -
(HardBrakingEvents * 3) -
(SpeedingEvents * 2) -
(SharpTurnEvents * 4) -
(NightDrivingPct * 50))
)
# 3. Simulación de siniestros, influenciada por el comportamiento
base_lambda <- 0.03
age_factor <- case_when(
portfolio_df$DriverAge < 25 ~ 1.5,
portfolio_df$DriverAge > 60 ~ 0.8,
TRUE ~ 1.0
)
# El factor de riesgo se basa ahora en el puntaje calculado
# Un puntaje más bajo (peor comportamiento) resulta en un factor de riesgo más alto
behavior_factor <- (100 - portfolio_df$DrivingBehaviorScore) / 40 + 0.5
policy_lambda <- base_lambda * age_factor * behavior_factor
portfolio_df$ClaimCount <- rpois(num_policies, lambda = policy_lambda)
mean_severity <- 1500
portfolio_df$TotalClaimAmount <- sapply(portfolio_df$ClaimCount, function(n_claims) {
if (n_claims == 0) return(0)
sum(rgamma(n_claims, shape = 2, scale = mean_severity / 2))
})
# Convertir a objeto espacial 'sf'
portfolio_sf <- st_as_sf(portfolio_df, coords = c("Garaging_X_UTM", "Garaging_Y_UTM"), crs = crs_utm, remove = FALSE)Visualizamos las distribuciones de las características clave de nuestra cartera.
p_age <- ggplot(portfolio_sf, aes(x = DriverAge)) +
geom_histogram(bins = 30, fill = "#0072B2", color = "white") +
labs(title = "Distribución de Edad del Conductor", x = "Edad", y = "Frecuencia")
p_score <- ggplot(portfolio_sf, aes(x = DrivingBehaviorScore)) +
geom_histogram(bins = 30, fill = "#D55E00", color = "white") +
labs(title = "Distribución del Puntaje de Manejo", x = "Puntaje (0-100)", y = "Frecuencia")
print(p_age)Este paso se mantiene igual: enriquecemos la cartera con variables del entorno físico para cada póliza.
calculate_features <- function(policy_geom, buffer_radius = 500) {
policy_sfc <- st_sfc(policy_geom, crs = crs_utm)
buffer_geom <- st_buffer(policy_sfc, dist = buffer_radius)
roads_intersect <- st_intersection(roads_sf, buffer_geom)
road_density <- if (nrow(roads_intersect) > 0) sum(st_length(roads_intersect)) else 0
bars_sf <- pois_sf %>% filter(amenity %in% c("bar", "pub", "nightclub"))
bar_count <- if (nrow(bars_sf) > 0) nrow(st_filter(bars_sf, buffer_geom)) else 0
schools_sf <- pois_sf %>% filter(amenity %in% c("school", "kindergarten"))
dist_school <- if (nrow(schools_sf) > 0) min(st_distance(policy_sfc, schools_sf)) else 99999
buffer_area <- st_area(buffer_geom)
buildings_intersect <- st_intersection(buildings_sf, buffer_geom)
building_density_pct <- if (nrow(buildings_intersect) > 0) (sum(st_area(buildings_intersect)) / buffer_area) * 100 else 0
return(list(RoadDensity_500m = as.numeric(road_density), BarCount_500m = bar_count, DistToNearestSchool_m = as.numeric(dist_school), BuildingDensity_500m_pct = as.numeric(building_density_pct)))
}
sample_indices <- sample(1:nrow(portfolio_sf), 1000)
feature_list <- lapply(portfolio_sf$geometry[sample_indices], calculate_features)
features_df <- do.call(rbind, lapply(feature_list, data.frame))
portfolio_sample <- portfolio_sf[sample_indices,] %>% bind_cols(features_df)El mapa interactivo nos permite explorar los patrones espaciales de la cartera.
portfolio_wgs84 <- st_transform(portfolio_sf, crs = 4326)
claims_locations <- portfolio_wgs84 %>% filter(ClaimCount > 0)
leaflet(claims_locations) %>%
addProviderTiles(providers$CartoDB.Positron, group = "Mapa Base") %>%
addHeatmap(
intensity = ~ClaimCount,
blur = 20, max = 0.05, radius = 15,
group = "Mapa de Calor de Siniestros"
) %>%
addCircleMarkers(
data = portfolio_wgs84 %>% sample_n(500),
radius = ~ifelse(ClaimCount > 0, 5, 2),
color = ~ifelse(ClaimCount > 0, "red", "blue"),
stroke = FALSE, fillOpacity = 0.6,
popup = ~paste("<b>ID Póliza:</b>", PolicyID, "<br>",
"<b>Puntaje Manejo:</b>", round(DrivingBehaviorScore), "<br>",
"<b>Siniestros:</b>", ClaimCount),
group = "Pólizas Individuales"
) %>%
addLayersControl(
overlayGroups = c("Mapa de Calor de Siniestros", "Pólizas Individuales"),
options = layersControlOptions(collapsed = FALSE)
) %>%
addLegend(position = "bottomright", colors = c("blue", "red"), labels = c("Sin Siniestro", "Con Siniestro"), title = "Leyenda de Pólizas")Construimos y comparamos dos tipos de modelos de frecuencia: 1. Modelo Telemático: Utiliza todas las variables disponibles, incluyendo las telemáticas y geoespaciales. 2. Modelo Tradicional: Utiliza únicamente variables demográficas y del vehículo.
# Preparar datos y dividir
model_data <- st_drop_geometry(portfolio_sample)
set.seed(123)
split <- sample.int(n = nrow(model_data), size = floor(.7 * nrow(model_data)), replace = FALSE)
train_data <- model_data[split, ]
test_data <- model_data[-split, ]
# 1. Modelo de Frecuencia Telemático (Avanzado)
formula_freq_telematics <- as.formula(
"ClaimCount ~ DriverAge + VehicleAge + VehicleValue + AnnualMileage + HardBrakingEvents + SpeedingEvents + SharpTurnEvents + NightDrivingPct + RoadDensity_500m + BuildingDensity_500m_pct + offset(log(Exposure))"
)
glm_freq_telematics <- glm(formula_freq_telematics, data = train_data, family = poisson(link = "log"))
# 2. Modelo de Frecuencia Tradicional (Básico)
formula_freq_traditional <- as.formula(
"ClaimCount ~ DriverAge + VehicleAge + VehicleValue + offset(log(Exposure))"
)
glm_freq_traditional <- glm(formula_freq_traditional, data = train_data, family = poisson(link = "log"))
# 3. Modelo de Severidad (común para ambos enfoques)
train_data_sev <- train_data %>% filter(TotalClaimAmount > 0)
glm_sev <- NULL
if (nrow(train_data_sev) > 10) {
formula_sev <- as.formula(
"TotalClaimAmount ~ VehicleAge + VehicleValue + RoadDensity_500m + BuildingDensity_500m_pct"
)
glm_sev <- glm(formula_sev, data = train_data_sev, family = Gamma(link = "log"))
}El gráfico de coeficientes nos permite ver el impacto específico de cada comportamiento de manejo.
if (!is.null(glm_freq_telematics)) {
p_freq_coeffs <- tidy(glm_freq_telematics, conf.int = TRUE) %>%
filter(term != "(Intercept)") %>%
ggplot(aes(x = estimate, y = reorder(term, estimate))) +
geom_point(size = 3, color = "#0072B2") +
geom_errorbarh(aes(xmin = conf.low, xmax = conf.high), height = 0.2, color = "#0072B2") +
geom_vline(xintercept = 0, linetype = "dashed") +
labs(title = "Coeficientes del Modelo de Frecuencia Telemático",
x = "Estimación del Coeficiente (Escala Log)", y = "Variable Predictora")
print(p_freq_coeffs)
}Interpretación: Se espera que las variables como
HardBrakingEvents y SpeedingEvents tengan
coeficientes positivos, indicando que un mayor número de estos eventos
aumenta la frecuencia de siniestros.
Calculamos la prima pura para cada póliza en el conjunto de prueba utilizando tanto el modelo tradicional como el telemático.
# --- Predicciones de ambos modelos ---
# Severidad predicha (común para ambos)
if (!is.null(glm_sev)) {
test_data$PredictedSeverity <- predict(glm_sev, newdata = test_data, type = "response")
} else {
# Si el modelo de severidad no converge, usar la media
test_data$PredictedSeverity <- mean(train_data_sev$TotalClaimAmount, na.rm = TRUE)
}
# 1. Prima Pura Telemática
test_data$PredictedFrequency_Telematic <- predict(glm_freq_telematics, newdata = test_data, type = "response")
test_data$PurePremium_Telematic <- test_data$PredictedFrequency_Telematic * test_data$PredictedSeverity
# 2. Prima Pura Tradicional
test_data$PredictedFrequency_Traditional <- predict(glm_freq_traditional, newdata = test_data, type = "response")
test_data$PurePremium_Traditional <- test_data$PredictedFrequency_Traditional * test_data$PredictedSeverity
# Prima Pura Real (para comparación)
test_data$PurePremium_Actual <- test_data$TotalClaimAmount / test_data$ExposureAhora comparamos directamente las primas generadas por ambos modelos para entender el impacto de la telemática.
La siguiente tabla muestra una selección de pólizas. Se puede
observar cómo la Prima Telemática es más baja que la
Prima Tradicional para conductores con un buen puntaje
de manejo (DrivingBehaviorScore alto), y más alta para
conductores con un puntaje bajo.
comparison_df <- test_data %>%
select(PolicyID, DrivingBehaviorScore, PurePremium_Traditional, PurePremium_Telematic) %>%
arrange(DrivingBehaviorScore) %>%
head(10) # Mostrar 10 ejemplos
kable(comparison_df,
col.names = c("ID Póliza", "Puntaje de Manejo", "Prima Tradicional ($)", "Prima Telemática ($)"),
digits = 2,
caption = "Comparación de Primas Puras para Pólizas Seleccionadas")| ID Póliza | Puntaje de Manejo | Prima Tradicional (\()| Prima Telemática (\)) | |
|---|---|---|---|
| VENPOL07915 | 23.32 | 84.24 | 307.77 |
| VENPOL03193 | 28.17 | 130.58 | 414.59 |
| VENPOL07410 | 32.38 | 37.72 | 75.13 |
| VENPOL08290 | 34.28 | 64.14 | 149.89 |
| VENPOL00446 | 36.77 | 80.34 | 71.39 |
| VENPOL03428 | 36.83 | 24.15 | 204.49 |
| VENPOL01700 | 39.88 | 56.83 | 38.17 |
| VENPOL00334 | 40.53 | 49.92 | 212.10 |
| VENPOL01902 | 40.56 | 60.89 | 222.88 |
| VENPOL03037 | 41.46 | 42.63 | 62.66 |
Este gráfico de dispersión visualiza la diferencia entre los dos modelos: - Eje X: Prima calculada con el modelo tradicional. - Eje Y: Prima calculada con el modelo telemático. - Línea diagonal (y=x): Representa el punto donde ambas primas son iguales.
Los puntos debajo de la línea son conductores “buenos” que obtienen un descuento con la telemática. Los puntos encima son conductores “riesgosos” que reciben un recargo. El color de los puntos indica el puntaje de manejo, confirmando que los conductores seguros (verdes) se benefician más.
ggplot(test_data, aes(x = PurePremium_Traditional, y = PurePremium_Telematic)) +
geom_point(aes(color = DrivingBehaviorScore), alpha = 0.7) +
geom_abline(intercept = 0, slope = 1, color = "red", linetype = "dashed", linewidth = 1) +
scale_color_viridis(name = "Puntaje de Manejo") +
scale_x_continuous(labels = dollar_format()) +
scale_y_continuous(labels = dollar_format()) +
labs(title = "Comparación de Primas: Modelo Tradicional vs. Telemático",
x = "Prima Pura Tradicional",
y = "Prima Pura Telemática",
caption = "Puntos debajo de la línea roja pagan menos con telemática.") +
coord_cartesian(xlim = c(0, max(test_data$PurePremium_Traditional, na.rm = TRUE)),
ylim = c(0, max(test_data$PurePremium_Telematic, na.rm = TRUE)))Este análisis demuestra que, si bien un modelo tradicional puede establecer una base de tarificación, la incorporación de datos telemáticos y geoespaciales permite una segmentación del riesgo mucho más precisa.
El modelo avanzado no solo predice mejor el riesgo general, sino que también crea un sistema de precios más justos: recompensa a los conductores seguros con primas más bajas y asigna el costo real del riesgo a aquellos con hábitos de manejo peligrosos. Este enfoque no solo es más equitativo, sino que también incentiva una conducción más segura, beneficiando tanto a la aseguradora como a la sociedad en su conjunto.