Scratch tickets come from a finite pool. As a game sells, its real prizes get claimed, so two games on the shelf today can carry genuinely different present value. We measure five value factors per game, then use principal-component analysis to collapse them into one axis and rank the catalogue from least-bad to worst.
Each game is reduced to five standardized factors. PCA finds the single combination of them that explains the most variation across the catalogue — the value axis. The loadings below show how much each factor pulls on that axis for the current data.
Every live game projected onto the value axis and sorted. The 0–100 column rescales the raw projection so the worst live game sits at 0 and the least-bad at 100 — it is a relative position within today's shelf, not a probability and not a grade.
No black box. The endpoint reads one row per game, standardizes the five factors (z-score), builds their correlation matrix, runs a cyclic Jacobi eigensolver, takes the leading eigenvector as the value axis (sign-aligned so higher EV yield is positive), and projects each game onto it.
GET /api/scratch/factor-rank // per game ev_yield = ev / price overall_fresh = Σ remaining / Σ total // all prize tiers top_fresh = top_remaining / total_top_prizes win_quality = 1 / overall_odds sharpe = stored risk-adjusted value // pipeline Z = zscore(features) // standardize C = correlation(Z) // 5×5 symmetric (λ, V) = jacobiEigen(C) // eigen-decompose PC1 = sign_align(V[0]) // value axis score = Z · PC1 // project & rank
The response includes variance_explained,
the full factor loadings for PC1 and PC2,
and every game's raw value_score,
so the numbers on this page can be checked against the source.