Releases: OpenActuarial/lossmodels
Releases · OpenActuarial/lossmodels
Release list
v0.7.2
0.7.2
Changed
fit_negbinomialnow refuses non-overdispersed data. The negative
binomial always satisfies variance/mean = 1/p > 1, so when the sample
variance is not greater than the mean no finite(r, p)maximizes the
likelihood -- the supremum is the Poisson limit (r -> inf,p -> 1). The
fitter previously ran the optimizer anyway and returned an arbitrary,
non-optimal finite result (withsuccess=True) whose value was unstable
across versions and platforms. It now raisesValueErrorpointing to
fit_poisson, matching the long-standing contract of
fit_negbinomial_moments. Becausefit_best_frequencyalready drops
candidates that fail to fit, model selection on underdispersed data now
cleanly falls back to Poisson.
Removed
- Obsolete negbinomial fit warning suppression. The
np.errstateguard
added in 0.7.1 silenced a SciPy finite-differenceRuntimeWarningthat only
arose when the optimizer chased thep -> 1boundary on near-Poisson data.
With such data now rejected up front, the optimizer only runs on
well-conditioned interior problems and the warning no longer occurs, so the
suppression has been removed rather than carried forward -- the guard is the
root-cause fix.
Tests
- Extended
tests/estimation/test_negbinomial_parameterization.pyto pin the
new refusal (underdispersed, equidispersed, and degenerate inputs raise),
confirm overdispersed fits are warning-free without suppression, and verify
fit_best_frequencyfalls back to Poisson on underdispersed data.
v0.7.1
0.7.1
Changed
fit_negbinomialperformance. The Negative Binomial MLE now aggregates
the data to distinct counts and scores each optimizer step with a single
vectorizedscipy.stats.nbinom.logpmfcall weighted by the count
multiplicities, instead of evaluating a scalar PMF once per observation per
iteration. Fitted results are unchanged (the likelihood is identical up to
floating point); only the runtime differs -- the two official
fit_best_frequencymodel-selection tests drop from ~23.5s each to well
under a second. Scoring in log space vialogpmfalso avoids the tail
underflow of the previouslog(pmf(...)).fit_negbinomialwarning hygiene. The L-BFGS-B finite-difference
gradient probes the edge of the feasible(r, p)box, where the negative
log-likelihood is+inf; the resultinginf - infinside SciPy's numerical
derivative raised a benign numpy "invalid value encountered"RuntimeWarning
during otherwise-successful fits. That specific floating-point warning is now
suppressed for the duration of the optimization only.
Fixed
examples/panjer_vs_simulation.pyaggregate grid. The Panjer recursion
step count is now sized to the discretized severity support
(int(round(max_loss / h))) rather than a fixed 50,000. The old value
computed the aggregate PMF out to ~250 aggregate means at large cost with no
effect on the reported mean; the example now runs an order of magnitude
faster while reproducing the same result.
Tests
- Added
tests/estimation/test_negbinomial_parameterization.py, pinning that
NegativeBinomial(r, p).pmfmatchesscipy.stats.nbinom(r, p)(and not the
flipped(r, 1 - p)convention), that the fit'slogpmflikelihood agrees
with the model's own PMF, and that the fit stays frequency-aggregated,
fast, and free of the finite-difference warning.