Skip to content

Releases: OpenActuarial/lossmodels

Release list

v0.7.2

Choose a tag to compare

@github-actions github-actions released this 05 Jul 22:03

0.7.2

Changed

  • fit_negbinomial now 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 (with success=True) whose value was unstable
    across versions and platforms. It now raises ValueError pointing to
    fit_poisson, matching the long-standing contract of
    fit_negbinomial_moments. Because fit_best_frequency already 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.errstate guard
    added in 0.7.1 silenced a SciPy finite-difference RuntimeWarning that only
    arose when the optimizer chased the p -> 1 boundary 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.py to pin the
    new refusal (underdispersed, equidispersed, and degenerate inputs raise),
    confirm overdispersed fits are warning-free without suppression, and verify
    fit_best_frequency falls back to Poisson on underdispersed data.

v0.7.1

Choose a tag to compare

@github-actions github-actions released this 05 Jul 19:26

0.7.1

Changed

  • fit_negbinomial performance. The Negative Binomial MLE now aggregates
    the data to distinct counts and scores each optimizer step with a single
    vectorized scipy.stats.nbinom.logpmf call 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_frequency model-selection tests drop from ~23.5s each to well
    under a second. Scoring in log space via logpmf also avoids the tail
    underflow of the previous log(pmf(...)).
  • fit_negbinomial warning 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 resulting inf - inf inside 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.py aggregate 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).pmf matches scipy.stats.nbinom(r, p) (and not the
    flipped (r, 1 - p) convention), that the fit's logpmf likelihood agrees
    with the model's own PMF, and that the fit stays frequency-aggregated,
    fast, and free of the finite-difference warning.