Skip to main content
modelType: "scorecard" — a points-based scoring model where each rule contributes a configurable number of points when its condition matches. Points accumulate from a base score, then normalize to a probability via sigmoid (or linear). The math is intentionally simple so operators, auditors, and regulators can read it line-by-line.

When to use

  • Day-1 launch — no interaction history yet. Hand-craft rules from domain expertise.
  • Auditability is non-negotiable — financial services, healthcare, anything regulated. Every rule fired is recorded in the score explanation.
  • Cold-start mitigation while you build a real model — scorecard runs as the active model while you accumulate outcomes for a future bayesian or gradient_boosted candidate.
Skip it when you have ≥ 1k labeled outcomes and meaningful feature interactions — a learned model (logistic, GBT) will outperform on accuracy, and you can fall back to scorecard for the cold-start segment via Score.overrides[].

The math

Each rule applies one of 10 operators (eq, neq, gt, gte, lt, lte, in, not_in, contains, starts_with) to one attribute on the candidate or its customer enrichment.

Fixture config

This fixture is exercised in the algorithm-coverage proof: platform/scripts/proof-algorithms-e2e.mts shows it scores 0.917 for a customer with {credit_score: 760, income: 95000, age: 38, segment: "Gold"} — 4 of 5 rules fire (the super-prime bonus at 800+ doesn’t, credit_score 760 < 800).

Training

There’s no training step. Operators add and tune rules through the Algorithms → Models → Scorecard UI. Each rule’s points value is the only knob. If you want data-driven rule weights, train a logistic_regression model on the same predictors and read off the weights as a starting point for scorecard points.

Score interpretation

  • score[0, 1] — the engine consumes this as the propensity component (P) in PRIE, or as the raw score in propensity strategy.
  • rawScore[minScore, maxScore] — the pre-normalization point total. Operators reading the trace can tell exactly how many points each rule contributed.
  • explanations[] — one entry per rule, with {matched, points, field, expected, actual, description}. This is the audit trail.

Pitfalls

  • All-or-nothing rule sets — if all your rules are points: 10 and only one fires per candidate, every score is 50 or 60. Vary the point values so high-value rules can dominate.
  • Forgetting to set minScore / maxScore — defaults are [0, 100]. If your rules total > 100 in worst-case, the sigmoid will saturate at 1.0 for every prime customer.
  • No rules at all — every candidate scores baseScore normalized (= 0.5 by default). Documented in T20 Test C of the proof bundle, where scorecard-v2 was created with zero rules and Platinum’s adaptation positiveRate=0 triggered the starvation bug (now fixed via the propensity floor).
  • Categorical fields with high cardinalityeq rules need one rule per value. Use in with an array instead.

Lifecycle & cadence

Scorecard is offline-retrain only. The platform won’t update rule weights or AUC unless an operator explicitly triggers it. Out of the box (autoLearn: false, learnMode: "none") a scorecard model is frozen at whatever values were in predictors[] at creation time and metricsHistory stays empty. To make it learn: PUT /algorithm-models/{id} { "autoLearn": true, "learnMode": "scheduled", "learnSchedule": "24h" }. Default cadence on the cron is nightly (24h). For weekly cadence on stable workloads, set "7d". The retrain pass recomputes rule importance from accumulated interaction_history and writes a new entry to metricsHistory[]. See Learning cadence and Model lifecycle for the full 4-step path from creation to live champion.

Cross-reference