Agregación de Riesgos y Modelo Colectivo

🎯 Introducción al Modelo Colectivo de Riesgo

El Modelo Colectivo de Riesgo representa una construcción matemática sofisticada que captura la esencia estocástica del negocio asegurador mediante la descomposición de la siniestralidad total en dos dimensiones fundamentales de incertidumbre:

S = X₁ + X₂ + … + X_N

Esta formulación aparentemente simple encierra una profunda complejidad probabilística que revolucionó la práctica actuarial moderna.

🔍 Desglose Anatómico del Modelo

Variable de Conteo (N) - La Incertidumbre de Frecuencia:

Naturaleza: Variable aleatoria discreta no-negativa

Interpretación: Representa el número estocástico de eventos claim en un período

Característica clave: Modela la impredecibilidad en la ocurrencia de siniestros

Ejemplos prácticos:

Número de accidentes automovilísticos en una flota

Cantidad de reclamaciones médicas en una póliza colectiva

Frecuencia de daños por fenómenos naturales

Variables de Monto (X_i) - La Incertidumbre de Severidad: Naturaleza: Variables aleatorias continuas positivas

Interpretación: Cuantifican el impacto económico individual de cada siniestro

Característica clave: Capturan la variabilidad extrema en los montos de pérdida

Ejemplos prácticos:

Costo de reparación de un vehículo accidentado

Gastos médicos de una hospitalización

Valor de indemnización por fallecimiento

⚡ La Sinergia Estocástica La verdadera potencia del modelo reside en la interacción probabilística entre estos dos componentes:

Propagación de la Incertidumbre:

Incertidumbre en N → Multiplica → Incertidumbre en X_i Cada fuente de variabilidad amplifica a la otra, creando una distribución agregada con propiedades emergentes complejas.

Ejemplo Ilustrativo: Consideremos una cartera de seguros de automóviles:

N ~ Poisson(λ): Número esperado de accidentes = 100

X_i ~ Gamma(α, β): Costo promedio por accidente = $5,000

Resultado: S no es simplemente 100 × $5,000 = $500,000

Realidad: S tiene una distribución con cola pesada debido a la combinación no lineal de ambas incertidumbres

🎲 Fundamentos Axiomáticos del Modelo Axioma de Independencia Crítica: text N ⫫ X_i para todo i La frecuencia de siniestros es estadísticamente independiente de la severidad individual.

Axioma de Intercambiabilidad:

X_i ~ F_X para todo i Todos los montos de siniestros provienen de la misma distribución subyacente.

Axioma de Independencia Mutua:

X_i ⫫ X_j para i ≠ j Los montos de siniestros individuales son mutuamente independientes.

🌉 Puente entre Teoría y Práctica Interpretación Actuarial: El modelo colectivo sirve como traductor matemático que convierte:

Datos históricos → en → Distribuciones probabilísticas

Experiencia observada → en → Proyecciones futuras

Intuición profesional → en → Cuantificación rigurosa

Ventaja Conceptual Clave: Permite separar el análisis en dos problemas manejables:

Modelado de frecuencia: ¿Cuántos siniestros ocurrirán?

Modelado de severidad: ¿Qué tan costosos serán?

📊 Representación Matemática Completa Función de Distribución Acumulada:

P(S ≤ s) = Σ_{n=0}^∞ P(N = n) × P(X₁ + … + X_n ≤ s) Función Generadora de Momentos:

M_S(t) = M_N(ln M_X(t)) Donde la MGF de S se expresa en términos de las MGF de N y X.

🎯 Relevancia en el Contexto Actual Para la Era de los Grandes Datos: Escalabilidad: Maneja carteras de millones de pólizas

Flexibilidad: Se adapta a diferentes líneas de negocio

Integración: Permite incorporar variables explicativas

En el Marco Regulatorio Moderno:

Solvencia II: Base para el cálculo de capital económico

IFRS 17: Fundamenta la medición de pasivos técnicos

Gestión de Riesgos: Soporte cuantitativo para decision-making



1. Conceptos Fundamentales

Estructura básica del modelo: S = X₁ + X₂ + … + X_N, donde S es la pérdida agregada, N el número de siniestros (variable aleatoria) y X_i los montos individuales. Supone independencia entre frecuencia y severidad.

cat("MODELO COLECTIVO DE RIESGO\n\n")
## MODELO COLECTIVO DE RIESGO
cat("Estructura básica: S = X₁ + X₂ + ... + X_N\n")
## Estructura básica: S = X₁ + X₂ + ... + X_N
cat("Donde:\n")
## Donde:
cat("• S: Pérdida agregada total\n")
## • S: Pérdida agregada total
cat("• N: Número de siniestros (variable aleatoria)\n")
## • N: Número de siniestros (variable aleatoria)
cat("• X_i: Monto del i-ésimo siniestro (variables i.i.d.)\n")
## • X_i: Monto del i-ésimo siniestro (variables i.i.d.)
cat("• Supuestos: N independiente de X_i, X_i i.i.d.\n\n")
## • Supuestos: N independiente de X_i, X_i i.i.d.
cat("APLICACIONES EN SEGUROS:\n")
## APLICACIONES EN SEGUROS:
cat("• Cálculo de primas puras para carteras\n")
## • Cálculo de primas puras para carteras
cat("• Determinación de reservas técnicas\n")
## • Determinación de reservas técnicas
cat("• Evaluación de solvencia y capital económico\n")
## • Evaluación de solvencia y capital económico
cat("• Diseño de estructuras de reaseguro\n")
## • Diseño de estructuras de reaseguro

2. Momentos de la Distribución Agregada

Cálculo de medidas estadísticas clave: media E[S] = E[N]·E[X], varianza Var[S] = E[N]·Var[X] + Var[N]·(E[X])². Fundamentales para determinar primas puras y márgenes de seguridad.

# Función para calcular momentos del modelo colectivo
calcular_momentos_colectivo <- function(E_N, Var_N, E_X, Var_X) {
  E_S <- E_N * E_X
  Var_S <- E_N * Var_X + Var_N * E_X^2
  CV_S <- sqrt(Var_S) / E_S  # Coeficiente de variación
  
  return(list(
    Media = E_S,
    Varianza = Var_S,
    Desviacion = sqrt(Var_S),
    Coef_Variacion = CV_S
  ))
}

# Ejemplo numérico
E_N <- 50     # Esperanza del número de siniestros
Var_N <- 60   # Varianza del número de siniestros  
E_X <- 1000000  # Esperanza del monto de siniestros ($1M)
Var_X <- 250000000000  # Varianza del monto ($500K desviación)

momentos <- calcular_momentos_colectivo(E_N, Var_N, E_X, Var_X)

cat("MOMENTOS DEL MODELO COLECTIVO - EJEMPLO:\n")
## MOMENTOS DEL MODELO COLECTIVO - EJEMPLO:
cat("Media de S: $", format(momentos$Media, big.mark = ","), "\n")
## Media de S: $ 5e+07
cat("Varianza de S: $", format(momentos$Varianza, big.mark = ","), "\n")
## Varianza de S: $ 7.25e+13
cat("Desviación estándar: $", format(momentos$Desviacion, big.mark = ","), "\n")
## Desviación estándar: $ 8,514,693
cat("Coeficiente de variación: ", round(momentos$Coef_Variacion, 3), "\n")
## Coeficiente de variación:  0.17

💻 Implementación del Modelo Colectivo

Aplicación práctica mediante simulación Monte Carlo, combinando distribuciones para frecuencia (Poisson, Binomial Negativa) y severidad (Gamma, Lognormal).



1. Simulación del Modelo Colectivo

Técnica computacional que genera miles de escenarios posibles de pérdidas agregadas mediante muestreo aleatorio, permitiendo estimar la distribución completa de pérdidas.

# Función para simular el modelo colectivo
library(kableExtra)
simular_modelo_colectivo <- function(n_simulaciones, parametros_N, parametros_X, tipo_N = "poisson", tipo_X = "gamma") {
  
  resultados <- numeric(n_simulaciones)
  
  for(i in 1:n_simulaciones) {
    # Simular número de siniestros
    if(tipo_N == "poisson") {
      n_siniestros <- rpois(1, parametros_N$lambda)
    } else if(tipo_N == "binomial_negativa") {
      n_siniestros <- rnbinom(1, size = parametros_N$r, prob = parametros_N$p)
    }
    
    # Simular montos de siniestros
    if(n_siniestros > 0) {
      if(tipo_X == "gamma") {
        montos <- rgamma(n_siniestros, shape = parametros_X$shape, rate = parametros_X$rate)
      } else if(tipo_X == "lognormal") {
        montos <- rlnorm(n_siniestros, meanlog = parametros_X$meanlog, sdlog = parametros_X$sdlog)
      }
      resultados[i] <- sum(montos)
    } else {
      resultados[i] <- 0
    }
  }
  
  return(resultados)
}

# Parámetros de ejemplo
param_N <- list(lambda = 100)  # Poisson con lambda = 100
param_X <- list(shape = 2, rate = 1/500000)  # Gamma con media 1,000,000

# Simulación
set.seed(123)
simulaciones <- simular_modelo_colectivo(10000, param_N, param_X)

# Resumen de resultados
resumen_simulacion <- data.frame(
  Metrica = c("Media simulada", "Desviación estándar", "Mínimo", "Máximo", 
              "Percentil 95%", "Percentil 99%"),
  Valor = c(
    format(mean(simulaciones), big.mark = ",", scientific = FALSE),
    format(sd(simulaciones), big.mark = ",", scientific = FALSE),
    format(min(simulaciones), big.mark = ",", scientific = FALSE),
    format(max(simulaciones), big.mark = ",", scientific = FALSE),
    format(quantile(simulaciones, 0.95), big.mark = ",", scientific = FALSE),
    format(quantile(simulaciones, 0.99), big.mark = ",", scientific = FALSE)
  )
)

kable(resumen_simulacion, row.names=FALSE)
Metrica Valor
Media simulada 99,947,542
Desviación estándar 12,326,232
Mínimo 51,009,126
Máximo 148,335,927
Percentil 95% 120,553,080
Percentil 99% 130,257,599

2. Visualización de Resultados

Representación gráfica de distribuciones de pérdidas mediante histogramas y curvas de densidad, facilitando el análisis visual de riesgos y la comunicación de resultados.

# Asegurar que ggplot2 esté cargado
library(ggplot2)
library(kableExtra)

# Parámetros realistas para seguros de automóviles
param_autos_N <- list(lambda = 0.08)  # 8% de siniestralidad anual
param_autos_X <- list(shape = 1.5, rate = 1/500000)  # Severidad con media $750K

# Simular para una cartera de 1,000 vehículos
set.seed(456)
cartera_autos <- simular_modelo_colectivo(5000, param_autos_N, param_autos_X)

# Análisis de resultados - CORREGIDO
primas_autos <- data.frame(
  Concepto = c("Prima pura por vehículo", "Desviación estándar", 
               "VaR 95% por vehículo", "TVaR 95% por vehículo",
               "Coeficiente de variación"),
  Valor = c(
    paste("$", format(round(mean(cartera_autos)), big.mark = ",")),
    paste("$", format(round(sd(cartera_autos)), big.mark = ",")),
    paste("$", format(round(quantile(cartera_autos, 0.95)), big.mark = ",")),
    paste("$", format(round(mean(cartera_autos[cartera_autos > quantile(cartera_autos, 0.95)])), big.mark = ",")),
    paste(round(sd(cartera_autos)/mean(cartera_autos), 3))
  )
)

kable(primas_autos, caption = "Análisis de Cartera - Seguros de Automóviles")
Análisis de Cartera - Seguros de Automóviles
Concepto Valor
Prima pura por vehículo $ 59,594
Desviación estándar $ 272,707
VaR 95% por vehículo $ 395,444
TVaR 95% por vehículo $ 1,093,580
Coeficiente de variación 4.576

📈 Aproximaciones Analíticas

Métodos matemáticos para estimar la distribución de pérdidas agregadas sin simulación, útiles para cálculos rápidos y validación de modelos.



1. Aproximación Normal

Utiliza el Teorema del Límite Central para aproximar la distribución agregada como Normal. Simple pero poco precisa para colas pesadas típicas en seguros.

# Asegurar que ggplot2 esté cargado
library(ggplot2)

# Función para aproximación normal
aproximacion_normal <- function(E_S, SD_S) {
  x_vals <- seq(E_S - 3*SD_S, E_S + 3*SD_S, length.out = 1000)
  dens_norm <- dnorm(x_vals, mean = E_S, sd = SD_S)
  
  return(data.frame(x = x_vals, densidad = dens_norm))
}

# Cálculo usando momentos teóricos
E_S_teorico <- param_N$lambda * (param_X$shape / param_X$rate)
Var_S_teorico <- param_N$lambda * (param_X$shape / param_X$rate^2)
SD_S_teorico <- sqrt(Var_S_teorico)

# Aproximación normal
aprox_norm <- aproximacion_normal(E_S_teorico, SD_S_teorico)

# Recrear df_simulaciones si no existe
if(!exists("df_simulaciones")) {
  df_simulaciones <- data.frame(Perdida_Agregada = simulaciones)
}

# Comparación con simulación - CORREGIDO
ggplot() +
  geom_histogram(data = df_simulaciones, aes(x = Perdida_Agregada, y = after_stat(density)), 
                 bins = 50, fill = "lightblue", alpha = 0.5) +
  geom_line(data = aprox_norm, aes(x = x, y = densidad), color = "red", size = 1) +
  labs(title = "Comparación: Simulación vs Aproximación Normal",
       subtitle = "Modelo Colectivo - Poisson-Gamma",
       x = "Pérdida Agregada",
       y = "Densidad") +
  scale_x_continuous(labels = function(x) paste0("$", format(x/1e6, digits = 1), "M")) +
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

2. Aproximación Gamma Desplazada (Gamma Translated)

Método más preciso que ajusta una distribución Gamma desplazada, capturando mejor la asimetría de las distribuciones de pérdidas en seguros.

# Función para aproximación Gamma Translated
aproximacion_gamma_translated <- function(E_S, Var_S) {
  # Parámetros de la distribución Gamma
  alpha <- (2 * E_S^2) / Var_S
  beta <- E_S / Var_S
  c <- 0  # En Gamma translated, c = E_S - alpha/beta
  
  x_vals <- seq(0, E_S + 4*sqrt(Var_S), length.out = 1000)
  dens_gamma <- dgamma(x_vals - c, shape = alpha, rate = beta)
  
  return(data.frame(x = x_vals, densidad = dens_gamma))
}

# Aproximación Gamma
aprox_gamma <- aproximacion_gamma_translated(E_S_teorico, Var_S_teorico)

# Gráfico comparativo
ggplot() +
  geom_histogram(data = df_simulaciones, aes(x = Perdida_Agregada, y = ..density..), 
                 bins = 50, fill = "lightblue", alpha = 0.3) +
  geom_line(data = aprox_norm, aes(x = x, y = densidad), color = "red", size = 1, linetype = "dashed") +
  geom_line(data = aprox_gamma, aes(x = x, y = densidad), color = "darkgreen", size = 1) +
  labs(title = "Comparación de Aproximaciones Analíticas",
       subtitle = "Normal (rojo) vs Gamma Translated (verde)",
       x = "Pérdida Agregada (USD)",
       y = "Densidad") +
  scale_x_continuous(labels = scales::dollar) +
  theme_minimal() +
  theme(legend.position = "top")
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.


🚘 Aplicación en Seguros de Automóviles

mplementación del modelo para calcular primas de automóviles, considerando frecuencia de accidentes (λ ≈ 8%) y severidad de daños (distribución Gamma).



1. Cartera de Seguros de Auto

Análisis completo de una cartera típica: cálculo de prima pura, medición de riesgo (VaR, TVaR) y evaluación de variabilidad (coeficiente de variación).

library(kableExtra)
# Parámetros realistas para seguros de automóviles
param_autos_N <- list(lambda = 0.08)  # 8% de siniestralidad anual
param_autos_X <- list(shape = 1.5, rate = 1/500000)  # Severidad con media $750K

# Simular para una cartera de 1,000 vehículos
set.seed(456)
cartera_autos <- simular_modelo_colectivo(5000, param_autos_N, param_autos_X)

# Análisis de resultados
primas_autos <- data.frame(
  Concepto = c("Prima pura por vehículo", "Desviación estándar", 
               "VaR 95% por vehículo", "TVaR 95% por vehículo",
               "Coeficiente de variación"),
  Valor = c(
    paste("$", format(mean(cartera_autos), big.mark = ",")),
    paste("$", format(sd(cartera_autos), big.mark = ",")),
    paste("$", format(quantile(cartera_autos, 0.95), big.mark = ",")),
    paste("$", format(mean(cartera_autos[cartera_autos > quantile(cartera_autos, 0.95)]), 
                      big.mark = ",")),
    paste(round(sd(cartera_autos)/mean(cartera_autos), 3))
  )
)

kable(primas_autos, caption = "Análisis de Cartera - Seguros de Automóviles")
Análisis de Cartera - Seguros de Automóviles
Concepto Valor
Prima pura por vehículo $ 59,593.53
Desviación estándar $ 272,706.8
VaR 95% por vehículo $ 395,444.1
TVaR 95% por vehículo $ 1,093,580
Coeficiente de variación 4.576

2. Análisis de Sensibilidad

Estudio de cómo cambian los resultados al variar parámetros clave (tasa de siniestralidad, forma de la severidad), crucial para entender la robustez del modelo.

library(ggplot2)
# Función para análisis de sensibilidad
analisis_sensibilidad <- function(lambda_values, shape_values, n_sim = 1000) {
  resultados <- expand.grid(lambda = lambda_values, shape = shape_values)
  resultados$prima_pura <- NA
  resultados$var_95 <- NA
  
  for(i in 1:nrow(resultados)) {
    param_N_temp <- list(lambda = resultados$lambda[i])
    param_X_temp <- list(shape = resultados$shape[i], rate = 1/500000)
    
    simul_temp <- simular_modelo_colectivo(n_sim, param_N_temp, param_X_temp)
    resultados$prima_pura[i] <- mean(simul_temp)
    resultados$var_95[i] <- quantile(simul_temp, 0.95)
  }
  
  return(resultados)
}

# Valores para análisis de sensibilidad
lambda_vals <- c(0.05, 0.08, 0.12)  # Diferentes tasas de siniestralidad
shape_vals <- c(1.2, 1.5, 2.0)      # Diferentes formas de la severidad

sensibilidad <- analisis_sensibilidad(lambda_vals, shape_vals)

# Gráfico de sensibilidad
ggplot(sensibilidad, aes(x = factor(lambda), y = prima_pura, fill = factor(shape))) +
  geom_col(position = "dodge") +
  labs(title = "Análisis de Sensibilidad - Prima Pura",
       subtitle = "Efecto de lambda (frecuencia) y shape (severidad)",
       x = "Lambda (Tasa de siniestralidad)",
       y = "Prima Pura Esperada (USD)",
       fill = "Shape Severidad") +
  scale_y_continuous(labels = scales::dollar) +
  theme_minimal()


💊 Aplicación en Seguros de Salud

Adaptación del modelo colectivo para gastos médicos, usando distribución Lognormal para capturar la alta variabilidad de costos de salud.



1. Modelo para Gastos Médicos

Cálculo de primas de salud incorporando cargos administrativos y analizando diferentes estructuras de pricing.

library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following object is masked from 'package:kableExtra':
## 
##     group_rows
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(kableExtra)

# Parámetros para seguros de salud
param_salud_N <- list(lambda = 1.2)  # 1.2 consultas por año en promedio
param_salud_X <- list(meanlog = 10.5, sdlog = 0.8)  # Lognormal para gastos médicos

# Simulación para salud
set.seed(789)
cartera_salud <- simular_modelo_colectivo(5000, param_salud_N, param_salud_X, tipo_X = "lognormal")

# Cálculo de primas con diferentes cargos
cargos_administrativos <- c(0.10, 0.15, 0.20)  # 10%, 15%, 20%
primas_salud <- data.frame(
  Cargo_Admin = cargos_administrativos,
  Prima_Total = mean(cartera_salud) * (1 + cargos_administrativos),
  VaR_95 = quantile(cartera_salud, 0.95) * (1 + cargos_administrativos),
  TVaR_95 = mean(cartera_salud[cartera_salud > quantile(cartera_salud, 0.95)]) * (1 + cargos_administrativos)
)

# Formatear resultados
primas_salud_formateado <- primas_salud %>%
  mutate(
    Prima_Total = paste("$", format(round(Prima_Total), big.mark = ",")),
    VaR_95 = paste("$", format(round(VaR_95), big.mark = ",")),
    TVaR_95 = paste("$", format(round(TVaR_95), big.mark = ","))
  )

kable(primas_salud_formateado, caption = "Primas para Seguro de Salud con Diferentes Cargos")
Primas para Seguro de Salud con Diferentes Cargos
Cargo_Admin Prima_Total VaR_95 TVaR_95
0.10 $ 65,250 $ 221,901 $ 306,364
0.15 $ 68,216 $ 231,987 $ 320,289
0.20 $ 71,182 $ 242,073 $ 334,215

2. Impacto de Límites y Deducibles

Evaluación de cómo las cláusulas de póliza (límites máximos y deducibles) afectan las primas y transfieren riesgo al asegurado.

library(kableExtra)
# Función para aplicar límites y deducibles
aplicar_limites_deducibles <- function(siniestros, deducible, limite) {
  siniestros_ajustados <- pmax(pmin(siniestros - deducible, limite), 0)
  return(siniestros_ajustados)
}

# Diferentes escenarios de deducibles y límites
deducibles <- c(0, 100000, 200000)  # $0, $100K, $200K
limites <- c(Inf, 5000000, 3000000)  # Sin límite, $5M, $3M

escenarios <- expand.grid(deducible = deducibles, limite = limites)
resultados_escenarios <- data.frame()

for(i in 1:nrow(escenarios)) {
  siniestros_ajust <- aplicar_limites_deducibles(cartera_salud, 
                                                escenarios$deducible[i], 
                                                escenarios$limite[i])
  
  resultados_escenarios <- rbind(resultados_escenarios, data.frame(
    Escenario = i,
    Deducible = escenarios$deducible[i],
    Limite = ifelse(is.infinite(escenarios$limite[i]), "Sin límite", 
                   paste("$", format(escenarios$limite[i], big.mark = ","))),
    Prima_Ajustada = mean(siniestros_ajust),
    Reduccion_Prima = (1 - mean(siniestros_ajust)/mean(cartera_salud)) * 100
  ))
}

# Mostrar resultados
resultados_escenarios %>%
  mutate(Prima_Ajustada = paste("$", format(round(Prima_Ajustada), big.mark = ",")),
         Reduccion_Prima = paste(round(Reduccion_Prima, 1), "%")) %>%
  select(-Escenario) %>%
  kable(caption = "Impacto de Deducibles y Límites en Primas de Salud")
Impacto de Deducibles y Límites en Primas de Salud
Deducible Limite Prima_Ajustada Reduccion_Prima
0e+00 Sin límite $ 59,318 0 %
1e+05 Sin límite $ 15,157 74.4 %
2e+05 Sin límite $ 3,927 93.4 %
0e+00 $ 5e+06 $ 59,318 0 %
1e+05 $ 5e+06 $ 15,157 74.4 %
2e+05 $ 5e+06 $ 3,927 93.4 %
0e+00 $ 3e+06 $ 59,318 0 %
1e+05 $ 3e+06 $ 15,157 74.4 %
2e+05 $ 3e+06 $ 3,927 93.4 %

🔄 Modelo Individual vs Colectivo

Comparación de dos enfoques de modelación: individual (detallado, intensivo computacionalmente) vs colectivo (eficiente, para carteras grandes).



1. Comparación de Enfoques

Análisis cuantitativo de diferencias en medias, desviaciones y medidas de riesgo entre ambos modelos.

library(kableExtra)
# Implementación del modelo individual
simular_modelo_individual <- function(n_asegurados, prob_siniestro, parametros_X, tipo_X = "gamma") {
  
  # Simular qué asegurados tienen siniestros
  tiene_siniestro <- rbinom(n_asegurados, 1, prob_siniestro)
  n_siniestros <- sum(tiene_siniestro)
  
  # Simular montos para quienes tienen siniestros
  if(n_siniestros > 0) {
    if(tipo_X == "gamma") {
      montos <- rgamma(n_siniestros, shape = parametros_X$shape, rate = parametros_X$rate)
    } else if(tipo_X == "lognormal") {
      montos <- rlnorm(n_siniestros, meanlog = parametros_X$meanlog, sdlog = parametros_X$sdlog)
    }
    # Asignar montos solo a quienes tienen siniestros
    montos_totales <- numeric(n_asegurados)
    montos_totales[tiene_siniestro == 1] <- montos
  } else {
    montos_totales <- numeric(n_asegurados)
  }
  
  return(list(
    perdida_total = sum(montos_totales),
    perdidas_individuales = montos_totales,
    n_siniestros = n_siniestros
  ))
}

# Comparar modelos para misma cartera
n_asegurados <- 1000
prob_siniestro <- 0.08
param_X_comp <- list(shape = 1.5, rate = 1/500000)

# Simular modelo individual múltiples veces
set.seed(321)
simulaciones_individual <- replicate(1000, {
  simular_modelo_individual(n_asegurados, prob_siniestro, param_X_comp)$perdida_total
})

# Simular modelo colectivo equivalente
lambda_equivalente <- n_asegurados * prob_siniestro
simulaciones_colectivo <- simular_modelo_colectivo(1000, list(lambda = lambda_equivalente), param_X_comp)

# Comparación
comparacion_modelos <- data.frame(
  Modelo = c("Individual", "Colectivo"),
  Media = c(mean(simulaciones_individual), mean(simulaciones_colectivo)),
  Desviacion = c(sd(simulaciones_individual), sd(simulaciones_colectivo)),
  VaR_95 = c(quantile(simulaciones_individual, 0.95), quantile(simulaciones_colectivo, 0.95))
)

comparacion_modelos %>%
  mutate(Media = paste("$", format(round(Media), big.mark = ",")),
         Desviacion = paste("$", format(round(Desviacion), big.mark = ",")),
         VaR_95 = paste("$", format(round(VaR_95), big.mark = ","))) %>%
  kable(caption = "Comparación Modelo Individual vs Colectivo")
Comparación Modelo Individual vs Colectivo
Modelo Media Desviacion VaR_95
Individual $ 59,755,376 $ 8,606,232 $ 74,453,156
Colectivo $ 60,430,304 $ 8,684,321 $ 75,415,912

2. Ventajas y Desventajas

Evaluación cualitativa de trade-offs: precisión vs eficiencia, detalle segmentado vs simplicidad operativa.

cat("COMPARACIÓN MODELO INDIVIDUAL VS COLECTIVO\n\n")
cat("MODELO INDIVIDUAL:\n")
cat("✓ Ventajas:\n")
cat("  - Captura heterogeneidad individual\n")
cat("  - Permite segmentación detallada\n")
cat("  - Más preciso para carteras pequeñas\n")
cat("✗ Desventajas:\n")
cat("  - Computacionalmente intensivo\n")
cat("  - Requiere datos individuales detallados\n")
cat("  - Complejidad analítica mayor\n\n")

cat("MODELO COLECTIVO:\n")
cat("✓ Ventajas:\n")
cat("  - Computacionalmente eficiente\n")
cat("  - Fácil implementación\n")
cat("  - Bueno para carteras grandes y homogéneas\n")
cat("✗ Desventajas:\n")
cat("  - Pierde información individual\n")
cat("  - Asume homogeneidad en la cartera\n")
cat("  - Menos preciso para segmentación fina\n\n")

cat("RECOMENDACIÓN:\n")
cat("• Usar modelo individual para pricing y segmentación\n")
cat("• Usar modelo colectivo para reservas y solvencia\n")
cat("• Considerar modelo colectivo para carteras grandes (>1,000 riesgos)\n")

🏭 Caso de Estudio Integrador

Aplicación completa del modelo colectivo a una compañía multi-línea, simulando simultáneamente seguros de autos, hogar, vida y salud.



1. Compañía de Seguros Multi-línea

Modelación integrada de múltiples líneas de negocio con diferentes características de riesgo, permitiendo análisis consolidado.

# Simular múltiples líneas de negocio

library(dplyr)
library(kableExtra)
simular_compania_multilinea <- function(n_sim) {
  # Parámetros para diferentes líneas
  lineas <- list(
    Autos = list(param_N = list(lambda = 80), param_X = list(shape = 1.5, rate = 1/500000)),
    Hogar = list(param_N = list(lambda = 25), param_X = list(shape = 2.0, rate = 1/1000000)),
    Vida = list(param_N = list(lambda = 5), param_X = list(shape = 3.0, rate = 1/2000000)),
    Salud = list(param_N = list(lambda = 120), param_X = list(meanlog = 10.5, sdlog = 0.8))
  )
  
  resultados <- data.frame(
    Simulacion = 1:n_sim,
    Autos = NA,
    Hogar = NA,
    Vida = NA,
    Salud = NA,
    Total = NA
  )
  
  for(i in 1:n_sim) {
    total_lineas <- 0
    
    # Autos (Gamma)
    n_autos <- rpois(1, lineas$Autos$param_N$lambda)
    if(n_autos > 0) {
      montos_autos <- rgamma(n_autos, shape = lineas$Autos$param_X$shape, 
                            rate = lineas$Autos$param_X$rate)
      resultados$Autos[i] <- sum(montos_autos)
      total_lineas <- total_lineas + sum(montos_autos)
    }
    
    # Hogar (Gamma)
    n_hogar <- rpois(1, lineas$Hogar$param_N$lambda)
    if(n_hogar > 0) {
      montos_hogar <- rgamma(n_hogar, shape = lineas$Hogar$param_X$shape,
                            rate = lineas$Hogar$param_X$rate)
      resultados$Hogar[i] <- sum(montos_hogar)
      total_lineas <- total_lineas + sum(montos_hogar)
    }
    
    # Vida (Gamma)
    n_vida <- rpois(1, lineas$Vida$param_N$lambda)
    if(n_vida > 0) {
      montos_vida <- rgamma(n_vida, shape = lineas$Vida$param_X$shape,
                           rate = lineas$Vida$param_X$rate)
      resultados$Vida[i] <- sum(montos_vida)
      total_lineas <- total_lineas + sum(montos_vida)
    }
    
    # Salud (Lognormal)
    n_salud <- rpois(1, lineas$Salud$param_N$lambda)
    if(n_salud > 0) {
      montos_salud <- rlnorm(n_salud, meanlog = lineas$Salud$param_X$meanlog,
                            sdlog = lineas$Salud$param_X$sdlog)
      resultados$Salud[i] <- sum(montos_salud)
      total_lineas <- total_lineas + sum(montos_salud)
    }
    
    resultados$Total[i] <- total_lineas
  }
  
  return(resultados)
}

# Simular compañía completa
set.seed(654)
compania <- simular_compania_multilinea(5000)

# Análisis de resultados por línea
resumen_compania <- data.frame(
  Linea = c("Autos", "Hogar", "Vida", "Salud", "Total"),
  Media = c(mean(compania$Autos, na.rm = TRUE), mean(compania$Hogar, na.rm = TRUE),
            mean(compania$Vida, na.rm = TRUE), mean(compania$Salud, na.rm = TRUE),
            mean(compania$Total)),
  VaR_95 = c(quantile(compania$Autos, 0.95, na.rm = TRUE), quantile(compania$Hogar, 0.95, na.rm = TRUE),
             quantile(compania$Vida, 0.95, na.rm = TRUE), quantile(compania$Salud, 0.95, na.rm = TRUE),
             quantile(compania$Total, 0.95)),
  TVaR_95 = c(mean(compania$Autos[compania$Autos > quantile(compania$Autos, 0.95, na.rm = TRUE)], na.rm = TRUE),
              mean(compania$Hogar[compania$Hogar > quantile(compania$Hogar, 0.95, na.rm = TRUE)], na.rm = TRUE),
              mean(compania$Vida[compania$Vida > quantile(compania$Vida, 0.95, na.rm = TRUE)], na.rm = TRUE),
              mean(compania$Salud[compania$Salud > quantile(compania$Salud, 0.95, na.rm = TRUE)], na.rm = TRUE),
              mean(compania$Total[compania$Total > quantile(compania$Total, 0.95)]))
)

resumen_compania %>%
  mutate(Media = paste("$", format(round(Media), big.mark = ",")),
         VaR_95 = paste("$", format(round(VaR_95), big.mark = ",")),
         TVaR_95 = paste("$", format(round(TVaR_95), big.mark = ","))) %>%
  kable(caption = "Análisis de Riesgo por Línea de Negocio")
Análisis de Riesgo por Línea de Negocio
Linea Media VaR_95 TVaR_95
Autos $ 60,115,130 $ 74,763,716 $ 78,495,836
Hogar $ 50,108,106 $ 71,855,320 $ 77,336,540
Vida $ 30,061,301 $ 58,110,771 $ 67,105,303
Salud $ 6,000,398 $ 7,294,935 $ 7,658,722
Total $ 146,104,566 $ 183,229,284 $ 193,230,601

2. Cálculo de Capital de Solvencia

Determinación de requerimientos de capital regulatorio usando Value-at-Risk al 99.5%, esencial para garantizar la estabilidad financiera.

# Calcular requerimientos de capital
library(dplyr)
library(kableExtra)

calcular_capital_solvencia <- function(perdidas, nivel_confianza = 0.995) {
  # Remover NA antes de calcular
  perdidas_clean <- na.omit(perdidas)
  
  var_nivel <- quantile(perdidas_clean, nivel_confianza, na.rm = TRUE)
  media <- mean(perdidas_clean, na.rm = TRUE)
  capital <- var_nivel - media
  
  return(list(
    VaR = var_nivel,
    Media = media,
    Capital_Solvencia = capital,
    Ratio_Capital = capital / media
  ))
}

# Verificar y limpiar datos primero
cat("Verificando datos de compañía:\n")
## Verificando datos de compañía:
cat("Autos - NAs:", sum(is.na(compania$Autos)), "\n")
## Autos - NAs: 0
cat("Hogar - NAs:", sum(is.na(compania$Hogar)), "\n")
## Hogar - NAs: 0
cat("Vida - NAs:", sum(is.na(compania$Vida)), "\n")
## Vida - NAs: 30
cat("Salud - NAs:", sum(is.na(compania$Salud)), "\n")
## Salud - NAs: 0
cat("Total - NAs:", sum(is.na(compania$Total)), "\n")
## Total - NAs: 0
# Capital por línea y total
capital_autos <- calcular_capital_solvencia(compania$Autos)
capital_hogar <- calcular_capital_solvencia(compania$Hogar)
capital_vida <- calcular_capital_solvencia(compania$Vida)
capital_salud <- calcular_capital_solvencia(compania$Salud)
capital_total <- calcular_capital_solvencia(compania$Total)

# Consolidar resultados
requerimientos_capital <- data.frame(
  Linea = c("Autos", "Hogar", "Vida", "Salud", "Total"),
  VaR_995 = c(capital_autos$VaR, capital_hogar$VaR, capital_vida$VaR, 
              capital_salud$VaR, capital_total$VaR),
  Capital_Requerido = c(capital_autos$Capital_Solvencia, capital_hogar$Capital_Solvencia,
                       capital_vida$Capital_Solvencia, capital_salud$Capital_Solvencia,
                       capital_total$Capital_Solvencia),
  Ratio_Capital = c(capital_autos$Ratio_Capital, capital_hogar$Ratio_Capital,
                   capital_vida$Ratio_Capital, capital_salud$Ratio_Capital,
                   capital_total$Ratio_Capital)
)

# Mostrar resultados
requerimientos_capital_formateado <- requerimientos_capital %>%
  mutate(
    VaR_995 = paste("$", format(round(VaR_995), big.mark = ",")),
    Capital_Requerido = paste("$", format(round(Capital_Requerido), big.mark = ",")),
    Ratio_Capital = paste(round(Ratio_Capital * 100, 1), "%")
  )

kable(requerimientos_capital_formateado, caption = "Requerimientos de Capital de Solvencia (99.5%)")
Requerimientos de Capital de Solvencia (99.5%)
Linea VaR_995 Capital_Requerido Ratio_Capital
Autos $ 83,051,791 $ 22,936,661 38.2 %
Hogar $ 84,918,450 $ 34,810,345 69.5 %
Vida $ 78,849,874 $ 48,788,574 162.3 %
Salud $ 8,122,279 $ 2,121,881 35.4 %
Total $ 205,959,043 $ 59,854,477 41 %

✅ Resumen y Conclusiones

Síntesis de aprendizajes clave, aplicaciones prácticas y direcciones futuras para el modelado de riesgos agregados en el sector asegurador.

cat("CONCLUSIONES SESIÓN 3 - AGREGACIÓN DE RIESGOS\n\n")
## CONCLUSIONES SESIÓN 3 - AGREGACIÓN DE RIESGOS
cat("PUNTOS CLAVE:\n")
## PUNTOS CLAVE:
cat("1. El modelo colectivo es fundamental para el análisis actuarial\n")
## 1. El modelo colectivo es fundamental para el análisis actuarial
cat("2. Proporciona un marco robusto para la agregación de riesgos\n")
## 2. Proporciona un marco robusto para la agregación de riesgos
cat("3. Permite calcular primas, reservas y capital de solvencia\n")
## 3. Permite calcular primas, reservas y capital de solvencia
cat("4. Es computacionalmente eficiente para carteras grandes\n\n")
## 4. Es computacionalmente eficiente para carteras grandes
cat("APLICACIONES PRÁCTICAS:\n")
## APLICACIONES PRÁCTICAS:
cat("• Pricing de pólizas y carteras\n")
## • Pricing de pólizas y carteras
cat("• Cálculo de reservas técnicas\n")
## • Cálculo de reservas técnicas
cat("• Determinación de capital económico\n")
## • Determinación de capital económico
cat("• Diseño de estructuras de reaseguro\n")
## • Diseño de estructuras de reaseguro
cat("• Evaluación de solvencia y estrés testing\n\n")
## • Evaluación de solvencia y estrés testing
cat("PRÓXIMOS PASOS:\n")
## PRÓXIMOS PASOS:
cat("• Incorporar dependencia entre líneas de negocio\n")
## • Incorporar dependencia entre líneas de negocio
cat("• Modelar riesgos catastróficos\n")
## • Modelar riesgos catastróficos
cat("• Implementar modelos más complejos (Pareto, Mixturas)\n")
## • Implementar modelos más complejos (Pareto, Mixturas)
cat("• Introducir simulación de escenarios macroeconómicos\n")
## • Introducir simulación de escenarios macroeconómicos