Skip to content

feat(scoring): expose HH_pd/CG_pd + PKB score conversion (0.6.0) - #17

Merged
anthrax63 merged 1 commit into
mainfrom
feat/agg-133-pd-score-conversion
Aug 14, 2026
Merged

feat(scoring): expose HH_pd/CG_pd + PKB score conversion (0.6.0)#17
anthrax63 merged 1 commit into
mainfrom
feat/agg-133-pd-score-conversion

Conversation

@anthrax63

Copy link
Copy Markdown
Member

Summary

Per PKB (Абай): the LightGBM booster's predict output is a probability of default (*_pd), not a scoring band. Response now exposes both — raw *_pd and converted *_score — instead of only the raw value under the *_score name (which was confusing).

Per-row response fields when scoring is enabled:

  • HH_pd, CG_pd — raw booster output (float 0..1)
  • HH_score, CG_score — integer PKB band, int(round(500 + 50 * log2((1 - pd) / pd)))

Formula source: exact PKB expression from the ticket handoff. Clipping pd to (1e-6, 1 - 1e-6) prevents log2 from blowing up on 0/1; NaN/None pd yields None score.

Version bump 0.5.1 → 0.6.0 (BREAKING: *_score field is now an integer band, not a raw float).

Files touched

  • src/kz_scoring_api/scoring.py — added pd_to_score, split HH_KEY/CG_KEY into HH_PD_KEY/HH_SCORE_KEY/CG_PD_KEY/CG_SCORE_KEY, score_rows writes both fields.
  • Tests updated across test_scoring.py, test_lookup.py, test_endpoints.py. New TestPdToScore covers half/low/high/0/1/NaN/None.
  • pyproject.toml bump.

Test plan

  • pytest tests/ — 93 passed locally (LightGBM real-model test skipped for missing dep, works in CI).
  • After merge, GHA docker-image.yml publishes ghcr.io/aggregion/kz-scoring-api:v0.6.0.
  • Mirror to cr.selcloud.ru/aggregion/main/kz-scoring-api:v0.6.0.
  • Rebake v0.6.0-models (models COPY layer) on top of the CI-produced v0.6.0, replace the current baked artifact.

Consumer impact

The change is breaking only in one direction: HH_score / CG_score type changed float → int, and its meaning changed from raw probability → integer band. A caller who relied on the old float value should switch to HH_pd / CG_pd.

…mula (0.6.0)

Per PKB: the LightGBM booster's predict output is a probability of default
(*_pd), not a score. Convert to their scoring band via
int(round(500 + 50 * log2((1 - pd) / pd))), clipping pd to (eps, 1 - eps)
to avoid log2 blowing up on 0/1. NaN/None pd yields None score.

Response schema per row now carries four fields when scoring is enabled:
HH_pd, HH_score, CG_pd, CG_score. Both fields for a model are omitted
together when that model path is not configured.

BREAKING CHANGE: the meaning of HH_score / CG_score changed. Previously
these were the raw booster output (float 0..1). Now they are integer PKB
score bands. Consumers that parsed the old *_score as a probability need
to switch to *_pd; consumers that need the integer band can keep reading
*_score but must accept int instead of float.
@anthrax63
anthrax63 merged commit ce30fad into main Aug 14, 2026
3 checks passed
@anthrax63
anthrax63 deleted the feat/agg-133-pd-score-conversion branch August 14, 2026 09:34
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.

1 participant