Source code for lossmodels.aggregate.collective

import numpy as np
from ..utils.random import RNGLike, resolve_rng

from .base import AggregateModel
from ..frequency.base import FrequencyModel
from ..severity.base import SeverityModel


[docs] class CollectiveRiskModel(AggregateModel): """ Collective risk model for aggregate loss: S = X1 + X2 + ... + XN where: - N is the claim count random variable (frequency) - Xi are iid claim severities Assumes: - severities are iid - N is independent of severities """ def __init__(self, frequency: FrequencyModel, severity: SeverityModel): self.frequency = frequency self.severity = severity
[docs] def sample(self, size: int = 1, rng: RNGLike = None) -> np.ndarray: """ Generate random samples of aggregate loss. ``rng`` may be ``None`` (legacy global ``numpy.random`` state), an ``int`` seed, or a ``numpy.random.Generator``; a seed or generator is threaded through both the frequency and severity draws so the whole aggregate simulation is reproducible. """ if size <= 0: raise ValueError("size must be positive") rng = None if rng is None else resolve_rng(rng) counts = ( self.frequency.sample(size=size) if rng is None else self.frequency.sample(size=size, rng=rng) ) aggregate_losses = np.zeros(size, dtype=float) for i, n_claims in enumerate(counts): if n_claims > 0: draws = ( self.severity.sample(size=int(n_claims)) if rng is None else self.severity.sample(size=int(n_claims), rng=rng) ) aggregate_losses[i] = np.sum(draws) return aggregate_losses
[docs] def mean(self) -> float: """ E[S] = E[N] * E[X] """ return self.frequency.mean() * self.severity.mean()
[docs] def variance(self) -> float: """ Var(S) = E[N] Var(X) + Var(N) (E[X])^2 """ en = self.frequency.mean() vn = self.frequency.variance() ex = self.severity.mean() vx = self.severity.variance() return en * vx + vn * (ex ** 2)
def frequency_mean(self) -> float: return self.frequency.mean() def severity_mean(self) -> float: return self.severity.mean()
[docs] def summary(self) -> dict: """ Return a small summary of the model. """ return { "frequency_model": repr(self.frequency), "severity_model": repr(self.severity), "frequency_mean": self.frequency.mean(), "severity_mean": self.severity.mean(), "aggregate_mean": self.mean(), "aggregate_variance": self.variance(), "aggregate_std": self.std(), }
def __repr__(self): return ( f"CollectiveRiskModel(" f"frequency={repr(self.frequency)}, " f"severity={repr(self.severity)})" )