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
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
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
Aplicación práctica mediante simulación Monte Carlo, combinando distribuciones para frecuencia (Poisson, Binomial Negativa) y severidad (Gamma, Lognormal).
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 |
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")
| 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 |
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.
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.
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.
mplementación del modelo para calcular primas de automóviles, considerando frecuencia de accidentes (λ ≈ 8%) y severidad de daños (distribución Gamma).
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")
| 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 |
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()
Adaptación del modelo colectivo para gastos médicos, usando distribución Lognormal para capturar la alta variabilidad de costos de salud.
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")
| 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 |
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")
| 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 % |
Comparación de dos enfoques de modelación: individual (detallado, intensivo computacionalmente) vs colectivo (eficiente, para carteras grandes).
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")
| 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 |
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")
Aplicación completa del modelo colectivo a una compañía multi-línea, simulando simultáneamente seguros de autos, hogar, vida y salud.
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")
| 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 |
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%)")
| 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 % |
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