Scorecard Development and Internal Ratings-Based Risk Parameters
Overview
Builds points scorecards for binary targets (credit risk, fraud, propensity) on the optimal binning and weight of evidence engine of 'OptimalBinningWoE', and takes them to the risk parameters of the internal ratings-based (IRB) approach. Variables are selected through optimal binning, eight admission rules, hold-out revalidation with frozen bins and a consensus of 'glmnet', 'xgboost', 'lightgbm' and 'ranger' models weighted by out-of-sample performance; the audit funnel never drops a candidate from the report. The scorecard is fitted with an explicit, auditable scale alignment (a log-odds regression on the raw score composed with the points-to-double-the-odds map); cut-offs are swept with frozen cuts; reject inference is reported as a sensitivity band; the population and characteristic stability indices (PSI and CSI) are monitored with both the fixed and the sample-size-adjusted threshold; and production SQL is generated in fourteen dialects, with the agreement between R and SQL verified by test. The IRB layer builds the default flag; calibrates the scorecard to a long-run default rate with rating grades, margins of conservatism and floors to give the probability of default (PD); models workout loss given default (LGD) in two stages with downturn and in-default estimates; models credit conversion factors from facility snapshots to give the exposure at default (EAD); and computes expected loss, risk weights, regulatory capital and expected credit loss from parameter tables selected by framework preset. The heavy numeric kernels (rank correlation of wide weight of evidence tables, exact concordance counts for Somers' D, streamed expected credit loss paths) are compiled with 'RcppArmadillo'. The scorecard methodology follows Siddiqi (2017) doi:10.1002/9781119282396 and Thomas et al. (2017) doi:10.1137/1.9781611974560.
- New score studies, computed from one pass over the scored rows into a table of counts per score value:
scr_bands()cuts a score into percentile or tail bands frozen on a reference sample and reports, per band and sample, the event rate with a Jeffreys interval, lift, capture, KS, WOE, IV, PSI and a one-sided Fisher exact test of rank order, plus the AUC, Gini and KS with a bootstrap interval. Accepts a scorecard, a data.frame (with weights, a value column and sample labels) or pre-aggregated counts.scr_tiers()fits 2 to 9 tiers (labeled from "low" to "high", with words for 2 to 7 tiers) by an exact dynamic program under share, event and distinctness constraints, by event-rate anchors or by equal shares;round_togives policy-friendly cuts, andn_bootmeasures the stability of the cuts. An infeasible tier count falls back and is recorded in a ledger.
Show all changes in 0.3.2Hide the rest of the changes in 0.3.2
scr_rag()lights discrimination, calibration, stability and, for a scorecard, the variables red, amber or green, per period or segment withby; the thresholds are an editable table fromscr_rag_plan().scr_apply(),scr_sql()andscr_export()assign the bands or tiers in R and in SQL and write the study to a workbook. Tier labels carry their order in production ("01.very high"for the tier with the highest event rate, down to"05.very low"), so they sort from the event-richest tier; the tiers table has the same value intier_label, andnumbered = FALSEgives the plain labels.scr_claims()tests statements such as "rate >= 60% for scores of 625 or more" on a band, a tier or a score range, with an exact one-sided binomial test, a one-sided Jeffreys bound and a Holm adjustment, and writes each verdict ("supported", "refuted" or "not proven") as one sentence.type = "floor"tests the weakest end of the group under a monotone fit of the rate instead of its average.scr_operating()finds the cut that maximizes the value of targeting, alerting or approval under volume, share, budget, event-rate and daily capacity constraints, and reports the binding constraint and its shadow price.scr_score_cross()crosses two scores on the same rows: the table of their bands with one or two outcomes, Spearman's rho and Kendall's tau-b, and the overlap of the rows each selects, with the swap-in and swap-out rates.- The three write a workbook with
scr_export(); the vignette "Score studies" walks through them on credit, fraud and churn scores. scr_mix_shift()splits the change of the event rate between two samples, or between each period and a base, into a mix effect and a rate effect per band; the effects add up to the change exactly.scr_segments()reads one score on many segments: AUC with the DeLong standard error and a test of equal AUC, observed against expected events, the log-odds offset and the slope ratio, with a suggested action per segment.scr_maturity()estimates the cumulative incidence of the event by band and horizon under censoring (Kaplan-Meier with Greenwood's variance), and the discrimination at each horizon.scr_uplift()reads a score on a treated and a control group: uplift per band with the Newcombe interval, the Qini coefficient and the AUUC with bootstrap intervals, and a randomization check.scr_overlap()compares rule flags with the alerts of a score: what each catches, the incremental recall of one over the other and the rules the score makes redundant.scr_detection()measures, per alert threshold, the fraud episodes detected, the fraudulent transactions and the time before the first alert, and the loss prevented.- The six write a workbook with
scr_export(). - New configuration keys for the score studies (stage 13):
study_bands,study_level,tier_min_pct,tier_min_eventsandtier_max_bins. scr_pd_validate()gives the light"grey"to a row without a testable result (a missing p-value) instead ofNA, and the overall light is"grey", not"green", when no row has a testable result.scr_ead_validate()does the same and adds the overalllight. Inscr_lgd_validate(), a summary row over pools or drivers that are all grey is now grey, not green.scr_monitor()and the CSI timelines ofscr_export()compute the CSI asscr_psi()does: a bin empty in both samples is left out of the smoothing and of the degrees of freedom of the adjusted threshold, and the CSI and its critical value are missing when the period has no rows in the bins or fewer than two bins are populated. Other results are unchanged.scr_strategy()freezescrossing$cuton the training scores, like the bands: midway between the training scores on either side of the band edge of the crossing.score >= cut, the convention ofscr_cutoff(), then reproduces the split of the bands on train and on any score seen in training, so rows at a band edge seen in training no longer change side between the two functions.breaksgiven as a number of intervals now also gets a cut, taken on the evaluated sample.- The rank-order diagnostics of
scr_scorecard()test each band against the previous one with a one-sided Fisher exact test. The binomial test used before took the previous band's rate as known and flagged too many breaks when that band was small. scr_scorecard()says when ties in the training score give fewer score bands thanscore_groups.scr_metrics()draws its bootstrap on the counts per score value when the score has many ties (at most one distinct value for every ten rows: scorecard points, a grade scale, a WOE score on a large sample), so the cost of a resample follows the number of distinct scores, not of rows. The intervals of such scores keep their distribution but change for a given seed, wherever they are reported; scores with fewer ties keep the row resampling and their intervals. The band tables of the scorecard,scr_strategy(),scr_reject()andscr_psi()assign the bands as integer indices, without a factor per row. The DeLong standard error ofscr_pd_validate()is computed from the counts and can differ in the last digits (about 1e-16). No other result changes.- The cheat sheet gains a third page on the score studies.
From NEWS.md in the release
Install
Health
- OK13 OKNow
- OK6 OK2026-10-07
Documentation
The repository also keeps web-only articles.
- Help pages
- 97 (1 internal)includes a package overview page
- Examples that run
- 100%95 run in a plain check (5 of them under a condition)
- Exported functions with examples
- 99%
- Documented parameters
- 93%
- Return-value docs
- 100%
- Help pages citing references
- 27%
Downloads
Repository
- PRs merged (all time)
- 100%
- Median days to close, 50 most recently updated closed issues
- not measured
- Median days to close, 50 most recently updated closed PRs
- 0
9 development-tooling and community-health practices detected across 6 families in the upstream repository
Checks run against github.com/evandeilton/scorecraft on 2026-10-21.
The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel
GitHub Pages site last deployed 2026-10-10 · The repository has a site deploy workflow
pkgdown site last built 2026-10-10
Show all practicesHide 2 practices
This repository shows signs of AI coding tools.
- Claude Codefirst seen 2026-09-04Pull request it wrote: opened by a project memberCommits: 14 by its own account · at least 42 crediting it in the message
- Claude Opus 5.529 commits · Sep to Oct 2026
- Claude Fable 5.111 commits · Sep 2026
- Claude Sonnet 5.52 commits · Oct 2026
Dependencies
Installing scorecraft adds 61 packages (32 with compiled code, 51 MB of source tarballs). Heaviest: stringi 11 MB, ggplot2 6.0 MB, data.table 5.7 MB.
Code & Tests
Datasets
People & History
Pick two releases to compare their code metrics.
- 0.3.2Latest2026-10-06 · current release · diff ↗ ·
added 13 exports
scr_bands, scr_claims, scr_detection, scr_maturity, scr_mix_shift, scr_operating, scr_overlap, scr_rag, scr_rag_plan, scr_score_cross, scr_segments, scr_tiers, scr_uplift - 0.3.02026-10-06 ·
3 days in CRAN's queue
Listed in CRAN's incoming queue from 2026-10-03 21:57 to 2026-10-06 15:36 UTC, in 13 readings. - RR 4.6.0 released · 2026-04-24
Package metadata
- First published
- 2026-10-06
- Total releases
- 2 / 1 yrs
- License
- MIT + file LICENSE OSI
- Minimum R
- ≥ 4.1.0
- Bundled data
- 401 KB / 7 files
- Download size
- 1.4 MB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("scorecraft")This package has no citation file, so citation() returns this entry built from DESCRIPTION.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-23, which the citation names so these numbers can be found later. More on citing and the projects behind them.