lossmodels¶
Severity and frequency distributions, maximum-likelihood fitting, goodness-of-fit, and collective-risk (compound) models — the loss-distribution toolkit familiar from the actuarial FAM/STAM syllabus, as composable objects.
Quickstart¶
import lossmodels as lm
# a severity distribution
sev = lm.Lognormal(mu=8.0, sigma=1.5)
sev.quantile(0.99) # 99th-percentile claim
sev.limited_expected_value(250_000) # E[min(X, 250k)] -- a capped/limited loss
# a collective-risk (compound) model: random number of claims, random sizes
model = lm.CollectiveRiskModel(
frequency=lm.Poisson(lam=3.0),
severity=lm.Lognormal(mu=8.0, sigma=1.5),
)
model.mean() # E[aggregate]
model.var(0.99) # 99% Value-at-Risk of the aggregate
model.tvar(0.99) # 99% Tail VaR
Fitting¶
import numpy as np
import lossmodels as lm
data = lm.Lognormal(mu=8.0, sigma=1.2).sample(5_000, seed=0)
fit = lm.fit_lognormal(data) # MLE
lm.fit_best_severity(data) # compare candidates by AIC/BIC
API reference¶
lossmodels ¶
lossmodels: actuarial loss distributions, aggregate modeling, and fit diagnostics.
The full public API is surfaced here for convenience, so common entry points are
available directly as lossmodels.Lognormal, lossmodels.fit_best_severity,
lossmodels.goodness_of_fit, etc. Submodule imports
(from lossmodels.severity import Lognormal) continue to work unchanged.
SeverityModel ¶
Bases: ABC
Base class for severity (loss size) distributions.
All severity models must implement:
- sample
- mean
- variance
Source code in lossmodels/severity/base.py
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | |
sample
abstractmethod
¶
mean
abstractmethod
¶
variance
abstractmethod
¶
quantile ¶
Inverse CDF (quantile / Value-at-Risk).
Numerically inverts cdf. Subclasses with a closed-form inverse
override this for speed and accuracy. Returns a Python float for a
scalar p and a numpy.ndarray for array-like p.
Source code in lossmodels/severity/base.py
ppf ¶
limited_expected_value ¶
E[min(X, d)] computed deterministically from the survival function.
For a nonnegative loss random variable X,
E[min(X, d)] = integral_0^d S_X(x) dx
where S_X(x) = 1 - F_X(x).
The n_sim argument is retained for backward compatibility but is no
longer used.
Source code in lossmodels/severity/base.py
excess_loss ¶
E[(X - d)+] computed deterministically from the survival function.
For a nonnegative loss random variable X,
E[(X - d)+] = integral_d^infinity S_X(x) dx
where S_X(x) = 1 - F_X(x).
This remains well defined even when E[X] does not exist, provided the
tail integral from d to infinity converges. The n_sim argument is
retained for backward compatibility but is no longer used.
Source code in lossmodels/severity/base.py
Exponential ¶
Bases: SeverityModel
Exponential severity model.
Parameterization¶
X ~ Exponential(rate)
Support: x >= 0
Mean = 1 / rate Variance = 1 / rate^2
Parameters¶
rate : float Rate parameter (lambda), with rate > 0.
Source code in lossmodels/severity/exponential.py
Gamma ¶
Bases: SeverityModel
Gamma severity model.
Parameterization¶
X ~ Gamma(shape=alpha, scale=theta) Support: x > 0
Parameters¶
alpha : float Shape parameter, with alpha > 0. theta : float Scale parameter, with theta > 0.
Source code in lossmodels/severity/gamma.py
Lognormal ¶
Bases: SeverityModel
Lognormal severity model.
Parameterization¶
If Y = log(X) ~ Normal(mu, sigma^2), then X is Lognormal(mu, sigma). Support: x > 0
Parameters¶
mu : float Mean of log(X). sigma : float Standard deviation of log(X), with sigma > 0.
Source code in lossmodels/severity/lognormal.py
Pareto ¶
Bases: SeverityModel
Pareto Type I severity model.
Parameterization¶
X ~ Pareto(alpha, theta) Support: x >= theta
Density
f(x) = alpha * theta^alpha / x^(alpha + 1), x >= theta
Parameters¶
alpha : float Shape parameter, with alpha > 0. theta : float Scale (minimum) parameter, with theta > 0.
Source code in lossmodels/severity/pareto.py
SplicedSeverity ¶
Bases: SeverityModel
Two-piece spliced severity: a body below a threshold, a tail above it.
The density is
f(x) = w * f_body(x) / F_body(u), 0 < x <= u
f(x) = (1 - w) * f_tail(x), x > u
where u is the threshold and w = P(X <= u) is the body mass. The
body is renormalized onto (0, u] and the tail must be a distribution
supported on [u, inf) with F_tail(u) = 0 (e.g. a GPD with location
u from extremeloss, or a :class:~lossmodels.Pareto with
theta = u). The CDF is
F(x) = w * F_body(x) / F_body(u), x <= u
F(x) = w + (1 - w) * F_tail(x), x > u
which is continuous at u (both pieces equal w there). The density
may jump at u; this is the ordinary (unconstrained) spliced model, not a
smooth splice.
The result is an ordinary severity model -- it exposes sample(size) and
mean(), so it drops straight back into risksim and extremeloss
as a tail-corrected severity.
Parameters¶
body : severity model
Body distribution. Must implement cdf, pdf, quantile and
limited_expected_value (every lossmodels severity qualifies).
tail : tail distribution on [u, inf)
Must implement cdf (with cdf(u) == 0), pdf and
sample(size). quantile enables an exact spliced quantile;
mean / variance enable the spliced moments.
threshold : float
Split point u > 0.
weight : float
Body mass w = P(X <= u) in (0, 1).
Source code in lossmodels/severity/spliced.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | |
Weibull ¶
Bases: SeverityModel
Weibull severity model.
Parameterization¶
X ~ Weibull(shape=k, scale=lam) Support: x > 0
Parameters¶
k : float Shape parameter, with k > 0. lam : float Scale parameter, with lam > 0.
Source code in lossmodels/severity/weibull.py
Burr ¶
Bases: SeverityModel
Burr (Type XII, Singh-Maddala) severity.
X ~ Burr(alpha, theta, gamma), support x > 0. F(x) = 1 - [1 / (1 + (x/theta)^gamma)]^alpha E[X^k] = theta^k Gamma(1 + k/gamma) Gamma(alpha - k/gamma) / Gamma(alpha), for -gamma < k < alpha * gamma.
Source code in lossmodels/severity/transformed_beta.py
InverseBurr ¶
Bases: SeverityModel
Inverse Burr (Dagum) severity.
X ~ InverseBurr(tau, theta, gamma), support x > 0. F(x) = [ (x/theta)^gamma / (1 + (x/theta)^gamma) ]^tau E[X^k] = theta^k Gamma(tau + k/gamma) Gamma(1 - k/gamma) / Gamma(tau), for -tau*gamma < k < gamma.
Source code in lossmodels/severity/transformed_beta.py
GeneralizedPareto ¶
Bases: SeverityModel
Generalized Pareto severity (Klugman transformed-beta form; NOT the EVT GPD).
X ~ GeneralizedPareto(alpha, theta, tau), support x > 0. F(x) = Beta(tau, alpha; x/(x+theta)) (regularized incomplete beta) E[X^k] = theta^k Gamma(tau + k) Gamma(alpha - k) / (Gamma(alpha) Gamma(tau)), for -tau < k < alpha.
The extreme-value GPD (peaks-over-threshold tail) lives in extremeloss;
this is the three-parameter loss-severity distribution from Loss Models.
Source code in lossmodels/severity/transformed_beta.py
ParetoII ¶
Bases: SeverityModel
Pareto (Type II, Lomax) severity -- the FAM/ASTAM two-parameter "Pareto".
X ~ Pareto(alpha, theta), support x > 0. f(x) = alpha theta^alpha / (x + theta)^(alpha+1) F(x) = 1 - [theta / (x + theta)]^alpha E[X^k] = theta^k k! / [(alpha-1)...(alpha-k)] (positive integer k < alpha) E[X] = theta / (alpha - 1), alpha > 1.
Note: this is distinct from :class:lossmodels.Pareto, which is the Pareto
Type I (single-parameter) distribution with support x >= theta. The FAM table
lists this Type II / Lomax form under the name "Pareto"; the Type I appears
under "Single-Parameter Pareto".
Source code in lossmodels/severity/transformed_beta.py
InversePareto ¶
Bases: SeverityModel
Inverse Pareto severity.
X ~ InversePareto(tau, theta), support x > 0. f(x) = tau theta x^(tau-1) / (x + theta)^(tau+1) F(x) = [x / (x + theta)]^tau E[X^k] = theta^k Gamma(tau + k) Gamma(1 - k) / Gamma(tau), -tau < k < 1.
The mean (k = 1) lies on the boundary of the moment range and does not exist,
so :meth:mean and :meth:variance always raise.
Source code in lossmodels/severity/transformed_beta.py
Loglogistic ¶
Bases: SeverityModel
Loglogistic (Fisk) severity.
X ~ Loglogistic(gamma, theta), support x > 0. F(x) = (x/theta)^gamma / (1 + (x/theta)^gamma) E[X^k] = theta^k Gamma(1 + k/gamma) Gamma(1 - k/gamma), -gamma < k < gamma.
Source code in lossmodels/severity/transformed_beta.py
Paralogistic ¶
Bases: SeverityModel
Paralogistic severity (a Burr distribution with gamma = alpha).
X ~ Paralogistic(alpha, theta), support x > 0. E[X^k] = theta^k Gamma(1 + k/alpha) Gamma(alpha - k/alpha) / Gamma(alpha), for -alpha < k < alpha^2.
Source code in lossmodels/severity/transformed_beta.py
InverseParalogistic ¶
Bases: SeverityModel
Inverse paralogistic severity (an inverse Burr with gamma = tau).
X ~ InverseParalogistic(tau, theta), support x > 0. E[X^k] = theta^k Gamma(tau + k/tau) Gamma(1 - k/tau) / Gamma(tau), for -tau^2 < k < tau.
Source code in lossmodels/severity/transformed_beta.py
InverseGamma ¶
Bases: SeverityModel
Inverse gamma (Vinci) severity.
X ~ InverseGamma(alpha, theta), support x > 0. F(x) = 1 - Gamma(alpha; theta/x) E[X^k] = theta^k Gamma(alpha - k) / Gamma(alpha), k < alpha.
Source code in lossmodels/severity/transformed_gamma.py
InverseWeibull ¶
Bases: SeverityModel
Inverse Weibull (log-Gompertz) severity.
X ~ InverseWeibull(theta, tau), support x > 0. F(x) = exp[-(theta/x)^tau] E[X^k] = theta^k Gamma(1 - k/tau), k < tau.
Source code in lossmodels/severity/transformed_gamma.py
InverseExponential ¶
Bases: SeverityModel
Inverse exponential severity.
X ~ InverseExponential(theta), support x > 0. F(x) = exp(-theta/x) E[X^k] = theta^k Gamma(1 - k), k < 1.
The mean (k = 1) does not exist, so :meth:mean and :meth:variance raise.
Source code in lossmodels/severity/transformed_gamma.py
InverseGaussian ¶
Bases: SeverityModel
Inverse Gaussian (Wald) severity, Klugman (mu, theta) parameterization.
X ~ InverseGaussian(mu, theta), support x > 0. E[X] = mu, Var[X] = mu^3 / theta.
Mapped to scipy.stats.invgauss(mu=mu/theta, scale=theta).
Source code in lossmodels/severity/other_severity.py
LogT ¶
Bases: SeverityModel
Log-t severity.
If Y has a Student-t distribution with r degrees of freedom, then
X = exp(sigma * Y + mu) has the log-t distribution (support x > 0). It is
heavier-tailed than the lognormal; no positive moments exist, so
:meth:mean and :meth:variance raise. mu may be negative.
F(x) = F_r((ln x - mu) / sigma), F_r the Student-t cdf.
Source code in lossmodels/severity/other_severity.py
SingleParameterPareto ¶
Bases: SeverityModel
Single-Parameter Pareto severity (Pareto Type I; theta is a fixed lower bound).
X ~ SingleParameterPareto(alpha, theta), support x > theta. f(x) = alpha theta^alpha / x^(alpha+1), x > theta F(x) = 1 - (theta/x)^alpha, x > theta E[X^k] = alpha theta^k / (alpha - k), k < alpha.
This is the same distribution as :class:lossmodels.Pareto; it is provided
under the FAM/ASTAM name. Per Loss Models, only alpha is a true parameter
-- theta is the known lower truncation point set in advance.
Source code in lossmodels/severity/other_severity.py
Beta ¶
Bases: SeverityModel
Beta severity on (0, theta).
X ~ Beta(a, b, theta), support 0 < x < theta. E[X^k] = theta^k Gamma(a+b) Gamma(a+k) / (Gamma(a) Gamma(a+b+k)), k > -a. E[X] = theta a / (a + b).
Source code in lossmodels/severity/finite_support.py
GeneralizedBeta ¶
Bases: SeverityModel
Generalized beta severity on (0, theta).
X ~ GeneralizedBeta(a, b, theta, tau), support 0 < x < theta, defined by U = (X/theta)^tau ~ Beta(a, b). Equivalently X = theta * U^(1/tau). F(x) = Beta(a, b; (x/theta)^tau) E[X^k] = theta^k Gamma(a+b) Gamma(a + k/tau) / (Gamma(a) Gamma(a + b + k/tau)), k > -a*tau.
Source code in lossmodels/severity/finite_support.py
FrequencyModel ¶
Bases: ABC
Base class for all frequency distributions.
All frequency models must implement: - sample - mean - variance
Source code in lossmodels/frequency/base.py
Binomial ¶
Bases: FrequencyModel
Binomial frequency model.
Parameters¶
n : int Number of trials p : float Probability of success
Source code in lossmodels/frequency/binomial.py
pmf ¶
Geometric ¶
Bases: FrequencyModel
Geometric frequency model.
Support starting at 0: {0, 1, 2, 3, ...}
Parameters¶
p : float Probability of success
Notes¶
NumPy and SciPy define the geometric distribution on {1, 2, 3, ...} as the number of trials until first success. This implementation shifts that convention by 1 so the support starts at 0, which is more natural for claim counts.
Source code in lossmodels/frequency/geometric.py
pmf ¶
NegativeBinomial ¶
Bases: 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
Source code in lossmodels/frequency/negbinomial.py
Poisson ¶
Bases: FrequencyModel
Poisson frequency model.
Parameterization¶
N ~ Poisson(lam)
Support: {0, 1, 2, ...}
Parameters¶
lam : float Expected claim count, with lam >= 0.
Source code in lossmodels/frequency/poisson.py
ZeroTruncated ¶
Bases: FrequencyModel
Zero-truncated version of an (a, b, 0) frequency model.
Parameters¶
base : FrequencyModel
Any frequency model exposing pmf, cdf, mean, variance,
and sample (e.g. Poisson(2.0)). Its mass at zero is removed and
the remaining probabilities are rescaled by 1 / (1 - p_0).
Source code in lossmodels/frequency/truncated.py
ZeroModified ¶
Bases: FrequencyModel
Zero-modified version of an (a, b, 0) frequency model.
Parameters¶
base : FrequencyModel
Any frequency model exposing pmf, cdf, mean, variance,
and sample.
p0_modified : float
The (arbitrary) probability mass placed at zero, in [0, 1). Setting it to
0 recovers the zero-truncated distribution.
Source code in lossmodels/frequency/modified.py
Logarithmic ¶
Bases: FrequencyModel
Logarithmic frequency distribution (Loss Models B.3.1.3).
N ~ Logarithmic(beta), support {1, 2, ...}. p_k = (beta / (1+beta))^k / (k ln(1+beta)), k = 1, 2, ... E[N] = beta / ln(1+beta) Var[N] = beta [1 + beta - beta/ln(1+beta)] / ln(1+beta)
It is the r -> 0 limit of the zero-truncated negative binomial.
Source code in lossmodels/frequency/truncated.py
CollectiveRiskModel ¶
Bases: 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
Source code in lossmodels/aggregate/collective.py
sample ¶
Generate random samples of aggregate loss.
Source code in lossmodels/aggregate/collective.py
mean ¶
variance ¶
Var(S) = E[N] Var(X) + Var(N) (E[X])^2
Source code in lossmodels/aggregate/collective.py
summary ¶
Return a small summary of the model.
Source code in lossmodels/aggregate/collective.py
EmpiricalSeverity ¶
Bases: SeverityModel
Empirical severity model based on observed loss data.
Parameters¶
data : array-like Observed severity values. Must be nonempty and nonnegative.
Source code in lossmodels/empirical/distribution.py
sample ¶
Generate bootstrap samples from the empirical severity distribution.
Source code in lossmodels/empirical/distribution.py
pdf ¶
Empirical severity is discrete, so this returns the empirical point mass at x. For continuous-looking data, this will often be 0 except at exact observed values.
Source code in lossmodels/empirical/distribution.py
quantile ¶
Empirical quantile (inverse CDF) from the observed data.
excess_loss ¶
limited_expected_value ¶
E[min(X, d)] computed empirically.
EmpiricalFrequency ¶
Bases: FrequencyModel
Empirical frequency model based on observed claim count data.
Parameters¶
data : array-like Observed claim counts. Must be nonempty, nonnegative, and integer-valued.
Source code in lossmodels/empirical/distribution.py
sample ¶
Generate bootstrap samples from the empirical frequency distribution.
Source code in lossmodels/empirical/distribution.py
fit_exponential ¶
Fit an Exponential severity model by maximum likelihood.
For X_i ~ Exponential(rate), the MLE is: rate_hat = 1 / mean(data)
Source code in lossmodels/estimation/mle.py
fit_gamma ¶
Fit a Gamma severity model by maximum likelihood using SciPy.
Returns¶
Gamma Fitted Gamma(alpha, theta) model.
Notes¶
This constrains loc = 0 so the support is x > 0, consistent with the severity model implementation.
Source code in lossmodels/estimation/mle.py
fit_lognormal ¶
Fit a Lognormal severity model by maximum likelihood.
If log(X) ~ Normal(mu, sigma^2), the MLEs are: mu_hat = mean(log(data)) sigma_hat = sqrt(mean((log(data) - mu_hat)^2))
Notes¶
This uses the MLE version of the variance (ddof=0).
Source code in lossmodels/estimation/mle.py
fit_pareto ¶
Fit a Pareto Type I severity model by maximum likelihood.
For X_i ~ Pareto(alpha, theta) with support x >= theta, the MLEs are:
theta_hat = min(data)
alpha_hat = n / sum(log(data / theta_hat))
Returns¶
Pareto Fitted Pareto(alpha, theta) model.
Source code in lossmodels/estimation/mle.py
fit_poisson ¶
Fit a Poisson frequency model by maximum likelihood.
For N_i ~ Poisson(lam), the MLE is: lam_hat = mean(data)
Notes¶
An all-zero dataset is valid and yields lam_hat = 0.
Source code in lossmodels/estimation/mle.py
fit_weibull ¶
Fit a Weibull severity model by maximum likelihood using SciPy.
Returns¶
Weibull Fitted Weibull(k, lam) model.
Notes¶
This constrains loc = 0 so the support is x > 0, consistent with the severity model implementation.
Source code in lossmodels/estimation/mle.py
fit_negbinomial ¶
Fit a Negative Binomial frequency model by numerical maximum likelihood.
Parameterization¶
N = number of failures before the r-th success Support: {0, 1, 2, ...} Mean = r(1-p)/p Variance = r(1-p)/p^2
Source code in lossmodels/estimation/mle.py
fit_mle ¶
Generic numerical maximum likelihood estimation for models with a pdf method.
Parameters¶
model_class : class A model class that can be instantiated as model_class(*params) and provides a pdf(x) method. data : array-like Observed data. initial_params : array-like Initial parameter guess for the optimizer. bounds : list of tuple, optional Bounds passed to scipy.optimize.minimize.
Returns¶
object Fitted model instance of type model_class.
Source code in lossmodels/estimation/mle.py
fit_best_severity ¶
Fit a set of severity models and return the best one by AIC or BIC.
Parameters¶
data : array-like Severity observations. candidates : list of str, optional Candidate model names. Defaults to all supported severity fitters. method : {"mle", "moments"} Fitting method. criterion : {"aic", "bic"} Selection criterion.
Returns¶
dict Dictionary with keys: - "best_name" - "best_model" - "criterion" - "method" - "results"
Notes¶
Models that fail to fit are skipped.
Source code in lossmodels/estimation/model_selection.py
fit_best_frequency ¶
Fit a set of frequency models and return the best one by AIC or BIC.
Source code in lossmodels/estimation/frequency_selection.py
log_likelihood ¶
Compute the log-likelihood of observed data under a fitted model.
Parameters¶
model : object Model instance with a pdf(x) method for continuous models or pmf(x) method for discrete models. data : array-like Observed data.
Returns¶
float Log-likelihood value.
Source code in lossmodels/estimation/diagnostics.py
aic ¶
Compute Akaike Information Criterion.
Parameters¶
model : object Fitted model. data : array-like Observed data. k : int Number of estimated parameters.
Returns¶
float AIC value.
Source code in lossmodels/estimation/diagnostics.py
bic ¶
Compute Bayesian Information Criterion.
Parameters¶
model : object Fitted model. data : array-like Observed data. k : int Number of estimated parameters.
Returns¶
float BIC value.
Source code in lossmodels/estimation/diagnostics.py
ks_statistic ¶
Kolmogorov-Smirnov distance sup_x |F_n(x) - F(x)| (smaller is better).
Most sensitive in the body of the distribution. See the module note on estimated-parameter p-values.
Source code in lossmodels/estimation/diagnostics.py
anderson_darling ¶
Anderson-Darling statistic A^2 (smaller is better).
Weights the tails more than KS, so it is the better whole-distribution statistic for heavy-tailed loss data.
Source code in lossmodels/estimation/diagnostics.py
cramer_von_mises ¶
Cramer-von Mises statistic W^2 (smaller is better).
Source code in lossmodels/estimation/diagnostics.py
tail_quantile_table ¶
Compare fitted vs empirical high quantiles -- the tail-fit check.
Returns a list of dicts with keys prob, empirical, fitted,
abs_error, rel_error. A model can win on AIC and still miss here;
for tail risk (VaR / TVaR / stop-loss) this is the diagnostic that matters.
Requires the model to implement quantile(p).
Source code in lossmodels/estimation/diagnostics.py
goodness_of_fit ¶
One-call fit report combining relative and absolute measures.
Returns n, log_likelihood, aic, bic (relative -- compare
across candidates) and ks, anderson_darling, cramer_von_mises
(absolute distance-to-empirical -- smaller is better). See the module note
on the estimated-parameter caveat for the distance statistics.