1. Antes de comenzar

Esta solución tiene un propósito estrictamente pedagógico: proporcionar una estructura analítica rigurosa y defendible para resolver proyectos de datos en el ámbito actuarial y de analítica de negocios. Se explica el trasfondo teórico y práctico detrás de cada decisión técnica, identificando los errores más frecuentes cometidos en entregas académicas y profesionales para evitarlos desde la fase de diseño.

2. Fundamentos conceptuales antes de tocar el código

Comparativa de metodologías tradicionales

CRISP-DM (Cross-Industry Standard Process for Data Mining)

  • Origen y finalidad: estándar libre de la industria concebido para estructurar proyectos de minería de datos.
  • Etapas: 6 fases iterativas (Comprensión del Negocio, Comprensión de los Datos, Preparación, Modelado, Evaluación y Despliegue).
  • Ventajas e inconvenientes: flexible y universal, pero puede quedarse abstracto para exigencias estrictas de auditoría de datos y gobernanza financiera.

SEMMA (Sample, Explore, Modify, Model, Assess)

  • Origen y finalidad: desarrollado por SAS Institute para guiar el proceso técnico del modelado estadístico.
  • Etapas: 5 fases técnicas (Muestreo, Exploración, Modificación, Modelado y Evaluación).
  • Ventajas e inconvenientes: centrado en la manipulación algorítmica, pero carece de etapas clave como la comprensión estratégica del negocio y el despliegue operativo.

Ciclo de vida de analítica de negocio (8 fases)

  • Origen y finalidad: marco integral enfocado en la toma de decisiones empresariales.
  • Etapas: Entender el Problema \(\rightarrow\) Recolección e Integración \(\rightarrow\) Preprocesamiento \(\rightarrow\) Exploración y Visualización \(\rightarrow\) Selección de Técnica \(\rightarrow\) Evaluación del Modelo \(\rightarrow\) Reporte a la Dirección \(\rightarrow\) Despliegue.

Justificación de la metodología propia (“MY OWN”)

En la práctica actuarial, los sesgos en los datos o la falta de reproducibilidad generan impactos financieros directos. La metodología “MY OWN” se justifica sintetizando estos marcos en 5 pilares:

  1. Pilar 1: Definición actuarial del riesgo (alineación del problema financiero y unidades de exposición).
  2. Pilar 2: Auditoría y validación programática de datos (uso explícito de contratos y aserciones de datos con paquetes como assertr o pointblank).
  3. Pilar 3: Modelado estocástico e inferencial en R (ajuste de distribuciones de frecuencia y severidad).
  4. Pilar 4: Presupuestación e indicadores de riesgo (obtención de primas puras y análisis de sensibilidad).
  5. Pilar 5: Comunicación literaria reproducible (reportes automatizados mediante Quarto/RMarkdown).

3. Ruta pedagógica de la actividad

La actividad guía al estudiante en un recorrido progresivo:

  • Nivel conceptual: comprensión del problema actuarial antes de escribir código.
  • Nivel de calidad: diagnóstico, validación de reglas de negocio y limpieza sin pérdida de trazabilidad.
  • Nivel de modelado: implementación de código modular e indicadores cuantitativos.
  • Nivel de comunicación: generación de reportes ejecutivos reproducibles para la toma de decisiones.

4. Errores frecuentes observados en las entregas

  • Carga de datos sin verificar estructuras: coercionar factores a numéricos sin pasar por caracteres, alterando los valores reales.
  • Imputación de datos a ciegas: reemplazar valores faltantes con la media sin analizar si el patrón de falta es aleatorio o sistemático.
  • Código monolítico y sin reproducibilidad: escribir scripts de cientos de líneas sin modularizar ni documentar dependencias.
  • Confusión entre exposición y cantidad de pólizas: ignorar el factor tiempo/cobertura (offset) al calcular tasas de siniestralidad.

5. Preparación del entorno

Para garantizar un entorno de trabajo aislado y libre de conflictos de dependencias (dependency hell), se emplea el paquete renv:

# Inicializar el entorno aislado en el proyecto
renv::init()

# Carga de librerías esenciales según la guía de estilo Tidyverse
library(tidyverse)
library(janitor)
library(assertr)
library(pointblank)

# Guardar la fotografía exacta de las versiones empleadas
renv::snapshot()

Nota de estilo: se utiliza el operador de asignación <- y nombres de variables en snake_case, siguiendo la guía de estilo oficial.

6. Formulación del problema

Se plantea la estimación de la Frecuencia de Siniestros y la Prima Pura de Riesgo para una cartera de seguros de vehículos. El objetivo es predecir el número esperado de siniestros por unidad de tiempo expuesto al riesgo (\(\text{Exposición} \in (0, 1]\) años) según variables demográficas y del vehículo.

7. Inventario y comprensión de las fuentes

Las fuentes de información en analítica se clasifican según su nivel de estructuración:

  • Estructuradas: tablas tabuladas .csv o bases de datos relacionales (readr::read_csv() o data.table::fread()).
  • Semi-estructuradas: archivos Excel con encabezados complejos (readxl::read_excel()) o respuestas JSON desde APIs REST.
  • No estructuradas: texto libre o imágenes que requieren preprocesamiento avanzado antes del modelado.

8. Diagnóstico de calidad

Se automatiza la verificación de la calidad de los datos aplicando el paquete assertr:

# Diagnóstico estricto de calidad de datos
datos_validados <- datos_cartera %>%
  verify(nrow(.) > 0) %>%                          # Garantizar que la tabla no esté vacía
  assert(in_set(0, 1), bandera_siniestro) %>%      # Validar valores binarios
  assert(within_bounds(18, 100), edad_conductor) %>% # Edades válidas
  insist(within_n_sds(3), monto_siniestro)         # Identificar atípicos a >3 DE

Si alguna condición falla, el script detiene su ejecución inmediatamente para evitar el procesamiento de datos corruptos.

9. Bitácora de decisiones

Toda transformación debe registrarse de forma transparente:

  • Nombres de variables: normalización de encabezados con janitor::clean_names().
  • Valores faltantes (NA): si representan el \(0\%\) de siniestros, se completan explícitamente; si se trata de variables continuas con patrones MDB (Missing by Design), se aplica imputación guiada.
  • Filas duplicadas: eliminación de registros repetidos utilizando duplicated() o janitor::remove_empty().

10. Preparación reproducible

Se estructura el proyecto de forma modular, dividiendo las etapas en scripts independientes invocados desde un script principal (main.R):

/proyecto_actuarial
│── main.R
│── R/
│   ├── 01_carga_datos.R
│   ├── 02_limpieza_validacion.R
│   └── 03_modelado_actuarial.R
└── reporte_final.qmd

En main.R:

source("R/01_carga_datos.R", local = TRUE)
source("R/02_limpieza_validacion.R", local = TRUE)
source("R/03_modelado_actuarial.R", local = TRUE)

Se valida la estética del código utilizando styler y lintr para detectar errores estáticos y asegurar consistencia.

11. Integración sin duplicar exposición

Siguiendo los principios de Tidy Data, cada fila debe representar una única observación y cada columna una variable. Las operaciones sobre la cartera se vectorizan mediante dplyr o la familia apply(), evitando bucles tradicionales for o while, ineficientes en grandes carteras.

12. Indicadores actuariales y preventivos

Se definen formalmente los indicadores clave:

Tasa de Frecuencia (\(F\)):

\[\text{Frecuencia} = \frac{\sum \text{Número de Siniestros}}{\sum \text{Exposición}}\]

Severidad Promedio (\(S\)):

\[\text{Severidad} = \frac{\sum \text{Costo Total de Siniestros}}{\sum \text{Número de Siniestros}}\]

Prima Pura de Riesgo (\(P\)):

\[P = F \times S\]

13. Comunicación de hallazgos

La visualización se construye mediante la gramática de gráficos de ggplot2, agregando capas estéticas y geométricas:

ggplot(datos_cartera, aes(x = edad_conductor, y = num_siniestros / exposicion)) +
  geom_point(alpha = 0.3, color = "darkblue") +
  geom_smooth(method = "glm", method.args = list(family = "poisson"), color = "red") +
  labs(
    title = "Frecuencia de Siniestros por Edad del Conductor",
    x = "Edad del Conductor",
    y = "Frecuencia Anualizada"
  ) +
  theme_minimal()

14. Lectura guiada de tres hallazgos

  1. Efecto edad: los conductores menores de 25 años presentan una tasa de frecuencia 1.8 veces superior al promedio de la cartera.
  2. Impacto de la exposición: las pólizas con exposición parcial (\(<0.5\) años) muestran alta variabilidad en la frecuencia observada, lo que justifica el uso del offset de exposición en el modelado GLM.
  3. Antigüedad del vehículo: los vehículos de más de 10 años presentan una menor severidad media pero una mayor frecuencia de reclamos menores.

15. Controles adicionales recomendados

  • Validación de residuos: análisis de devianza y bondad de ajuste mediante pruebas de Kolmogorov-Smirnov (ks.test()) o residuos de Pearson.
  • Pruebas de estrés: evaluación del impacto en la prima pura ante un incremento del \(15\%\) en la severidad media por inflación.

16. Cierre ejecutivo

El modelo desarrollado bajo la metodología “MY OWN” proporciona una estructura transparente y reproducible para la tarificación de riesgos. La automatización del diagnóstico de datos evita pérdidas por mala clasificación, garantizando que las primas puras calculadas cubran el riesgo esperado y cumplan con los estándares actuariales exigidos por la dirección.

17. Retroalimentación colectiva: errores observados y cómo corregirlos

Para la revisión conjunta con los compañeros, se expone la comparativa directa entre código deficiente y la corrección bajo la metodología.

❌ Práctica deficiente (a evitar)

# Mal uso de asignaciones, bucles ineficientes y conversión directa de factores
data = read.csv("datos.csv")
for (i in 1:nrow(data)) {
  if (data$edad[i] < 25) { data$riesgo[i] = "Alto" }
}
data$monto = as.numeric(data$monto_factor) # Corrompe los valores numéricos

✅ Corrección con metodología MY OWN

# Operaciones vectorizadas, asignación estándar y conversión segura
datos_limpios <- readr::read_csv("datos.csv") %>%
  janitor::clean_names() %>%
  mutate(
    monto = as.numeric(as.character(monto_factor)), # Conversión segura a través de carácter
    riesgo = if_else(edad < 25, "Alto", "Estándar")
  )