Skip to content

#272 added geometric averaging type to the Development() estimator#811

Merged
kennethshsu merged 57 commits into
mainfrom
#272_geometric_LDFs
May 22, 2026
Merged

#272 added geometric averaging type to the Development() estimator#811
kennethshsu merged 57 commits into
mainfrom
#272_geometric_LDFs

Conversation

@kennethshsu
Copy link
Copy Markdown
Collaborator

@kennethshsu kennethshsu commented May 18, 2026

Summary of Changes

Added geometric LDFs in the Development() estimator.

Related GitHub Issue(s)

Additional Context for Reviewers

Because geometric averaging cannot be easily implemented in the regression framework, it is calculated outside. We then have to carefully nan out all relevant params related to the estimated values, such as sigma_, std_err_, and std_residuals_.

  • I passed tests locally for both code (uv run pytest) and documentation changes (uv run jb build docs --builder=custom --custom-builder=doctest)

Note

Medium Risk
Introduces a new averaging mode and rewires weighted regression/std-error calculations, which can change LDFs and stochastic outputs (sigma_, std_err_, residuals) across workflows if behavior differs from prior methods.

Overview
Adds geometric averaging as a supported average option for Development, including per-development-period mixing of simple/geometric methods.

Refactors WeightedRegression to accept the chosen averaging method, compute regression weights internally (tracking _w_reg/exponent_), handle geometric averaging via a log-based coefficient calculation with a new warning for zero values, and centralizes std_err_ filling via a new std_err_fill() helper. Updates Development.fit() to use these new regression outputs when computing standardized residuals.

Expands the test suite to validate geometric/simple averaging results and to assert expected sigma_, std_err_, and std_residuals_ values.

Reviewed by Cursor Bugbot for commit 81cef7e. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread chainladder/development/development.py Outdated
Comment thread chainladder/utils/weighted_regression.py
Comment thread chainladder/development/development.py Outdated
Comment thread chainladder/utils/weighted_regression.py Outdated
Comment thread chainladder/utils/weighted_regression.py Outdated
Co-authored-by: Kenneth Hsu <kennethshsu@users.noreply.github.com>
@kennethshsu kennethshsu marked this pull request as ready for review May 21, 2026 03:50
@kennethshsu
Copy link
Copy Markdown
Collaborator Author

@henrydingliu ok ready for review!

@kennethshsu
Copy link
Copy Markdown
Collaborator Author

In case anyone wants to look at the Excel replication.
geomean.xlsx

Comment thread chainladder/development/tests/test_development.py
Comment thread chainladder/development/development.py
# but using the log link function and taking the differences
w_geo = num_to_nan(self.w)
geo_coef = xp.exp(
xp.nanmean(w_geo * xp.log(y), axis)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need any extra error catching around negative values ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think a cumulative triangle can ever be negative. But I do a potential problem in an edge case where losses are 0 for the first few periods for a super long tailed business. In that case, the geometric LDFs will error out...

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

geometric ldf is calculated regardless of whether it's selected, correct? so this could error out even when the user doesn't want geomean at all

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's a good point, though not likely, but ya I can add a guard to skip if geometric is not present so it runs faster.

Comment thread chainladder/utils/weighted_regression.py
Comment thread chainladder/utils/weighted_regression.py
@kennethshsu kennethshsu marked this pull request as draft May 21, 2026 19:12
@kennethshsu kennethshsu marked this pull request as ready for review May 21, 2026 19:55
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2737959. Configure here.

Comment thread chainladder/utils/weighted_regression.py
Comment thread chainladder/utils/weighted_regression.py
Copy link
Copy Markdown
Collaborator

@henrydingliu henrydingliu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

harmonic mean next?

@kennethshsu
Copy link
Copy Markdown
Collaborator Author

lol if you have the formulas we can do it, it's been refactored so should be pretty easy

@kennethshsu kennethshsu merged commit e76d85d into main May 22, 2026
17 checks passed
@kennethshsu kennethshsu deleted the #272_geometric_LDFs branch May 22, 2026 03:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Medial and geometric averages

3 participants