Source code for lossmodels.frequency.negbinomial

import numpy as np
from ..utils.random import RNGLike, resolve_rng
from scipy.stats import nbinom

from .base import FrequencyModel
from ..utils.numeric import eval_dist


[docs] class NegativeBinomial(FrequencyModel): """ Negative Binomial frequency model. Parameterization ---------------- N = number of failures before the r-th success Support: {0, 1, 2, ...} Parameters ---------- r : float Number of successes, with r > 0. p : float Probability of success, with 0 < p <= 1. Notes ----- This matches SciPy's negative binomial parameterization: scipy.stats.nbinom(r, p) Under this convention: E[N] = r(1 - p) / p Var(N) = r(1 - p) / p^2 """ def __init__(self, r: float, p: float): if r <= 0: raise ValueError("r must be positive.") if not (0 < p <= 1): raise ValueError("p must be in (0, 1].") self.r = r self.p = p
[docs] def sample(self, size: int = 1, rng: RNGLike = None) -> np.ndarray: """ Generate random samples of claim counts. """ if size <= 0: raise ValueError("size must be positive.") return resolve_rng(rng).negative_binomial(self.r, self.p, size=size)
[docs] def mean(self) -> float: """ E[N] = r(1 - p) / p """ return self.r * (1 - self.p) / self.p
[docs] def variance(self) -> float: """ Var(N) = r(1 - p) / p^2 """ return self.r * (1 - self.p) / (self.p ** 2)
def pmf(self, k): return eval_dist(lambda v: nbinom.pmf(v, self.r, self.p), k) def cdf(self, k): return eval_dist(lambda v: nbinom.cdf(v, self.r, self.p), k) def __repr__(self) -> str: return f"NegativeBinomial(r={self.r}, p={self.p})"