Methodologies
What's on This Page
This page walks through the methodologies behind some of my projects, including my xG, RAPM, WAR, Elo, and SRS models for my player and team cards. Also included is a glossary of common hockey analytics and data science terms. Click any methodology or the glossary below to expand it.
Everything is built from the NHL's public API: the schedule and standings, play-by-play (shots, goals, faceoffs, penalties, hits, giveaways, and takeaways), shift charts, box scores, and player game logs. It covers the regular seasons from 2009-2010 through 2025-2026. Playoff games aren't part of any model.
Expected Goals (xG)
What Are Expected Goals?
Expected goals (xG) is the probability that a given shot becomes a goal. It captures shot quality, so a breakaway and a point shot are valued differently instead of both counting as one shot. A shot with an xG of 0.20, for example, goes in about once in every five tries, so a team that takes ten of them is expected to score about two goals. The model is trained entirely on shot-event data that I scrape myself, rather than relying on a third-party model. It covers every unblocked shot attempt (goals, shots on goal, and missed shots) from the 2009-2010 through 2025-2026 regular seasons: 1,726,876 shots and 117,224 goals. Blocked shots are left out because the coordinates recorded for them are where the shot was blocked, not where it was taken from. Overtime shots are included, but shootout attempts are not.
xG is the foundation for much of the rest of this page. RAPM uses the xG of every shot while a player is on the ice as the thing it tries to explain, and WAR builds on RAPM while also using xG to measure finishing (goals above xG), goaltending (goals saved above xG), and the value of drawing and taking penalties.
The Six Models
Instead of training one single model across every strength state, I train a separate gradient-boosted classifier (XGBoost, a decision-tree model that learns from past shots) for six different groups of similar situations, and I build that set of six models again for every season, so each season has its own six models. Each shot is used to train the model for the situation it was taken in.
| Model | Situations It Covers |
|---|---|
| 5v5 | 5v5 |
| Other Even Strength | 4v4 and 3v3 |
| Power Play | 5v4, 5v3, 4v3, and any state where the shooter has more skaters |
| Penalty Kill | 4v5, 3v5, 3v4, and any state where the shooter has fewer skaters |
| Empty Net Against | Any shot at a net with no goalie in it |
| Empty Net For | Any shot taken by a team with no goalie in net |
The Data
These are the shots the xG model works with, counted by the exact situation each was taken in. The shots-on-goal tabs count only goals and shots on goal, the unblocked-shots tabs add the missed shots, and the last two tabs show the shooting percentage (goals divided by shots) for each. In the tables, EN stands for empty net, and short misses (explained below) are not counted.
There are a few things to keep in mind with the data. Shots recorded as "short" misses (a miss reason added in 2023-2024, explained below) are much closer to fanned attempts than real shots, so I don't use them in the xG model. Three seasons were shortened, which shows up as low counts: 2012-2013 (lockout), 2019-2020 (COVID-19), and 2020-2021 (COVID-19). The "Other" column holds rare situations such as double-minor and matching-penalty combinations. 2009-2010's larger "Other" count comes mostly from shots whose strength could not be determined, because of gaps in the NHL's shift data for that season. 3v3 shots jump from 2015-2016 onward because that is when 3-on-3 overtime was introduced; the handful before then come from rare stretches of 3-on-3 in earlier seasons.
Shots on goal by situation
| Season | 5v5 | 5v4 | 4v5 | 4v4 | 3v3 | 5v3 | 4v3 | EN Against | EN For | Other | Penalty Shots | Total |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2009-2010 | 54,919 | 11,893 | 2,108 | 1,307 | 0 | 664 | 152 | 403 | 1,231 | 1,576 | 10 | 74,263 |
| 2010-2011 | 56,652 | 11,456 | 1,996 | 2,216 | 8 | 586 | 310 | 339 | 1,106 | 42 | 52 | 74,763 |
| 2011-2012 | 56,441 | 10,298 | 1,819 | 2,344 | 8 | 459 | 264 | 325 | 1,164 | 26 | 37 | 73,185 |
| 2012-2013 | 32,472 | 5,847 | 958 | 1,338 | 4 | 321 | 147 | 219 | 627 | 19 | 19 | 41,971 |
| 2013-2014 | 56,490 | 10,935 | 1,785 | 2,324 | 19 | 426 | 224 | 351 | 1,230 | 85 | 44 | 73,913 |
| 2014-2015 | 56,744 | 10,220 | 1,786 | 2,300 | 8 | 367 | 204 | 513 | 1,400 | 34 | 26 | 73,602 |
| 2015-2016 | 56,492 | 10,277 | 1,662 | 1,054 | 1,006 | 377 | 237 | 417 | 1,583 | 20 | 41 | 73,166 |
| 2016-2017 | 58,252 | 10,079 | 1,704 | 1,006 | 1,005 | 318 | 204 | 363 | 1,392 | 16 | 23 | 74,362 |
| 2017-2018 | 63,248 | 11,262 | 2,210 | 910 | 1,119 | 331 | 216 | 348 | 1,525 | 38 | 31 | 81,238 |
| 2018-2019 | 63,100 | 10,128 | 2,330 | 927 | 908 | 290 | 145 | 484 | 1,589 | 23 | 30 | 79,954 |
| 2019-2020 | 52,769 | 8,934 | 1,947 | 741 | 831 | 244 | 183 | 631 | 1,586 | 83 | 34 | 67,983 |
| 2020-2021 | 40,862 | 6,909 | 1,418 | 506 | 649 | 163 | 120 | 278 | 1,013 | 92 | 23 | 52,033 |
| 2021-2022 | 64,956 | 10,808 | 2,328 | 1,030 | 1,020 | 339 | 165 | 516 | 1,690 | 122 | 30 | 83,004 |
| 2022-2023 | 63,445 | 11,502 | 2,340 | 938 | 983 | 373 | 255 | 442 | 1,634 | 37 | 41 | 81,990 |
| 2023-2024 | 61,387 | 11,267 | 2,212 | 941 | 823 | 318 | 234 | 441 | 1,760 | 59 | 43 | 79,485 |
| 2024-2025 | 58,368 | 9,479 | 1,902 | 805 | 773 | 313 | 156 | 520 | 1,793 | 81 | 26 | 74,216 |
| 2025-2026 | 56,318 | 10,079 | 1,938 | 866 | 986 | 365 | 232 | 508 | 1,653 | 89 | 28 | 73,062 |
| Total | 952,915 | 171,373 | 32,443 | 21,553 | 10,150 | 6,254 | 3,448 | 7,098 | 23,976 | 2,442 | 538 | 1,232,190 |
Unblocked shot attempts by situation
| Season | 5v5 | 5v4 | 4v5 | 4v4 | 3v3 | 5v3 | 4v3 | EN Against | EN For | Other | Penalty Shots | Total |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2009-2010 | 76,031 | 16,660 | 2,738 | 1,805 | 1 | 919 | 200 | 601 | 1,727 | 2,193 | 12 | 102,887 |
| 2010-2011 | 78,569 | 15,985 | 2,614 | 3,032 | 10 | 801 | 426 | 555 | 1,574 | 57 | 58 | 103,681 |
| 2011-2012 | 78,236 | 14,644 | 2,359 | 3,212 | 14 | 636 | 380 | 502 | 1,607 | 32 | 42 | 101,664 |
| 2012-2013 | 45,283 | 8,107 | 1,280 | 1,792 | 5 | 448 | 207 | 318 | 940 | 22 | 21 | 58,423 |
| 2013-2014 | 78,630 | 15,238 | 2,275 | 3,149 | 23 | 600 | 323 | 558 | 1,802 | 114 | 51 | 102,763 |
| 2014-2015 | 78,838 | 14,304 | 2,261 | 3,121 | 11 | 498 | 282 | 807 | 1,963 | 40 | 32 | 102,157 |
| 2015-2016 | 78,611 | 14,415 | 2,108 | 1,427 | 1,344 | 495 | 350 | 664 | 2,201 | 26 | 44 | 101,685 |
| 2016-2017 | 80,957 | 14,231 | 2,138 | 1,330 | 1,347 | 451 | 292 | 580 | 1,997 | 20 | 31 | 103,374 |
| 2017-2018 | 87,663 | 15,663 | 2,709 | 1,210 | 1,455 | 465 | 303 | 557 | 2,177 | 45 | 39 | 112,286 |
| 2018-2019 | 87,301 | 13,991 | 2,814 | 1,251 | 1,173 | 400 | 212 | 769 | 2,256 | 25 | 39 | 110,231 |
| 2019-2020 | 72,654 | 12,249 | 2,304 | 992 | 1,077 | 322 | 247 | 944 | 2,203 | 105 | 43 | 93,140 |
| 2020-2021 | 56,220 | 9,477 | 1,716 | 680 | 842 | 237 | 158 | 441 | 1,398 | 115 | 27 | 71,311 |
| 2021-2022 | 88,963 | 14,819 | 2,815 | 1,341 | 1,320 | 455 | 246 | 784 | 2,359 | 155 | 33 | 113,290 |
| 2022-2023 | 88,610 | 16,075 | 2,837 | 1,238 | 1,267 | 521 | 362 | 744 | 2,339 | 46 | 49 | 114,088 |
| 2023-2024 | 88,585 | 15,953 | 2,774 | 1,304 | 1,103 | 467 | 328 | 773 | 2,565 | 82 | 45 | 113,979 |
| 2024-2025 | 88,116 | 13,811 | 2,391 | 1,149 | 1,050 | 453 | 226 | 923 | 2,766 | 112 | 30 | 111,027 |
| 2025-2026 | 86,353 | 14,904 | 2,437 | 1,228 | 1,341 | 537 | 334 | 988 | 2,608 | 128 | 32 | 110,890 |
| Total | 1,339,620 | 240,526 | 40,570 | 29,261 | 13,383 | 8,705 | 4,876 | 11,508 | 34,482 | 3,317 | 628 | 1,726,876 |
Shooting percentage (goals per shot on goal) by situation
| Season | 5v5 | 5v4 | 4v5 | 4v4 | 3v3 | 5v3 | 4v3 | EN Against | EN For | Other | Penalty Shots | All |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2009-2010 | 8.1% | 12.2% | 8.3% | 8.4% | – | 18.2% | 19.7% | 53.1% | 10.4% | 7.4% | 30% | 9.1% |
| 2010-2011 | 7.8% | 11.7% | 8.7% | 9.3% | 0.0% | 24.4% | 15.8% | 69.0% | 11.3% | 7.1% | 46% | 9.0% |
| 2011-2012 | 7.8% | 12.1% | 9.0% | 8.4% | 12.5% | 22.2% | 14.4% | 72.6% | 9.6% | 11.5% | 46% | 8.9% |
| 2012-2013 | 7.9% | 12.8% | 8.2% | 7.5% | 0.0% | 23.4% | 18.4% | 66.2% | 11.0% | 0.0% | 37% | 9.1% |
| 2013-2014 | 7.8% | 11.8% | 10.5% | 8.5% | 5.3% | 21.4% | 15.6% | 66.7% | 10.7% | 8.2% | 39% | 8.9% |
| 2014-2015 | 7.7% | 12.3% | 8.2% | 8.1% | 0.0% | 20.2% | 16.7% | 60.0% | 10.1% | 2.9% | 50% | 8.9% |
| 2015-2016 | 7.5% | 12.4% | 9.8% | 8.8% | 13.7% | 18.8% | 15.6% | 86.8% | 10.5% | 5.0% | 37% | 9.0% |
| 2016-2017 | 7.7% | 12.6% | 9.9% | 9.8% | 15.7% | 20.8% | 17.6% | 81.5% | 9.1% | 18.8% | 48% | 9.0% |
| 2017-2018 | 7.8% | 12.7% | 8.7% | 11.5% | 15.3% | 20.8% | 12.5% | 100.0% | 12.3% | 5.3% | 48% | 9.2% |
| 2018-2019 | 8.1% | 13.2% | 8.6% | 11.1% | 17.1% | 24.1% | 22.8% | 84.5% | 10.5% | 13.0% | 43% | 9.5% |
| 2019-2020 | 8.2% | 13.0% | 8.3% | 9.6% | 15.4% | 18.4% | 18.6% | 55.3% | 11.4% | 3.6% | 29% | 9.5% |
| 2020-2021 | 8.3% | 13.2% | 7.5% | 10.7% | 17.4% | 24.5% | 14.2% | 93.5% | 12.8% | 7.6% | 39% | 9.7% |
| 2021-2022 | 8.4% | 13.2% | 8.3% | 9.9% | 15.7% | 20.1% | 18.2% | 93.2% | 11.8% | 11.5% | 27% | 9.8% |
| 2022-2023 | 8.6% | 13.4% | 9.0% | 11.0% | 17.3% | 22.5% | 17.3% | 98.4% | 11.5% | 5.4% | 37% | 10.1% |
| 2023-2024 | 8.7% | 13.5% | 9.4% | 12.1% | 19.0% | 18.6% | 19.2% | 100.0% | 11.1% | 6.8% | 37% | 10.2% |
| 2024-2025 | 9.0% | 14.5% | 9.3% | 11.2% | 19.7% | 25.9% | 24.4% | 100.0% | 12.1% | 19.8% | 27% | 10.6% |
| 2025-2026 | 9.5% | 14.3% | 8.9% | 9.5% | 17.7% | 24.1% | 15.1% | 99.8% | 12.7% | 7.9% | 21% | 11.1% |
| All seasons | 8.2% | 12.8% | 8.9% | 9.3% | 16.5% | 21.5% | 17.1% | 81.4% | 11.2% | 7.9% | 38% | 9.5% |
Shooting percentage (goals per unblocked shot attempt) by situation
| Season | 5v5 | 5v4 | 4v5 | 4v4 | 3v3 | 5v3 | 4v3 | EN Against | EN For | Other | Penalty Shots | All |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2009-2010 | 5.8% | 8.7% | 6.4% | 6.1% | 0.0% | 13.2% | 15.0% | 35.6% | 7.4% | 5.3% | 25% | 6.6% |
| 2010-2011 | 5.6% | 8.4% | 6.6% | 6.8% | 0.0% | 17.9% | 11.5% | 42.2% | 7.9% | 5.3% | 41% | 6.5% |
| 2011-2012 | 5.7% | 8.5% | 7.0% | 6.1% | 7.1% | 16.0% | 10.0% | 47.0% | 7.0% | 9.4% | 40% | 6.4% |
| 2012-2013 | 5.7% | 9.2% | 6.2% | 5.6% | 0.0% | 16.7% | 13.0% | 45.6% | 7.3% | 0.0% | 33% | 6.5% |
| 2013-2014 | 5.6% | 8.5% | 8.3% | 6.3% | 4.3% | 15.2% | 10.8% | 41.9% | 7.3% | 6.1% | 33% | 6.4% |
| 2014-2015 | 5.6% | 8.8% | 6.5% | 6.0% | 0.0% | 14.9% | 12.1% | 38.2% | 7.2% | 2.5% | 41% | 6.4% |
| 2015-2016 | 5.4% | 8.8% | 7.7% | 6.5% | 10.3% | 14.3% | 10.6% | 54.5% | 7.5% | 3.8% | 34% | 6.5% |
| 2016-2017 | 5.5% | 8.9% | 7.9% | 7.4% | 11.7% | 14.6% | 12.3% | 51.0% | 6.3% | 15.0% | 35% | 6.5% |
| 2017-2018 | 5.6% | 9.1% | 7.1% | 8.7% | 11.8% | 14.8% | 8.9% | 62.5% | 8.6% | 4.4% | 38% | 6.6% |
| 2018-2019 | 5.8% | 9.5% | 7.1% | 8.2% | 13.2% | 17.5% | 15.6% | 53.2% | 7.4% | 12.0% | 33% | 6.9% |
| 2019-2020 | 5.9% | 9.5% | 7.0% | 7.2% | 11.9% | 14.0% | 13.8% | 37.0% | 8.2% | 2.9% | 23% | 6.9% |
| 2020-2021 | 6.0% | 9.6% | 6.2% | 7.9% | 13.4% | 16.9% | 10.8% | 59.0% | 9.3% | 6.1% | 33% | 7.1% |
| 2021-2022 | 6.1% | 9.6% | 6.9% | 7.6% | 12.1% | 14.9% | 12.2% | 61.4% | 8.4% | 9.0% | 24% | 7.2% |
| 2022-2023 | 6.2% | 9.6% | 7.4% | 8.3% | 13.4% | 16.1% | 12.2% | 58.5% | 8.0% | 4.3% | 31% | 7.2% |
| 2023-2024 | 6.0% | 9.5% | 7.5% | 8.7% | 14.1% | 12.6% | 13.7% | 57.1% | 7.6% | 4.9% | 36% | 7.1% |
| 2024-2025 | 5.9% | 10.0% | 7.4% | 7.8% | 14.5% | 17.9% | 16.8% | 56.3% | 7.8% | 14.3% | 23% | 7.1% |
| 2025-2026 | 6.2% | 9.7% | 7.1% | 6.7% | 13.1% | 16.4% | 10.5% | 51.3% | 8.1% | 5.5% | 19% | 7.3% |
| All seasons | 5.8% | 9.2% | 7.1% | 6.9% | 12.5% | 15.5% | 12.1% | 50.2% | 7.8% | 5.8% | 33% | 6.8% |
How It Is Trained
Each season's models are trained on the five seasons before it and not on the season being scored, so every shot is scored by a model that has not seen it. Training on the season being scored makes its xG more descriptive of that season, but the goal is a model that is predictive of the next season, so a model is never trained on the seasons it is used on. Five seasons is enough shots to learn from, without reaching so far back that it is learning an old style of play. The first five seasons in the data (2009-2010 through 2013-2014) don't have five earlier seasons to train on, so they share the model trained for 2014-2015, a simple way to cover the older data. That means those five seasons are in-sample (their shots were part of the model's training data).
All six models share the same XGBoost settings, and xG is never rescaled to match the number of goals scored, so every xG value is exactly what the model predicted.
One correction is applied before training. NHL arenas record shot locations a little differently, so each arena's shot distances are nudged toward the league-wide distribution for that season, by a weight of n / (n + 2000), where n is the number of shots in that arena-season. A small, noisy arena-season is left mostly alone and a large one is corrected almost fully. The 2000 is a hand-picked constant.
Penalty shots aren't ordinary shots, so they aren't part of the training data. Each is simply given the conversion rate of the penalty shots in the previous five seasons instead, so the value follows the current scoring environment.
The Model Features
Every shot is described by 37 engineered features, chosen for their variety and because every one of them can be built from public data. The feature table below lists what each one is and the values it can take, and the importance chart shows how much each contributes to the 5v5 model.
| Group | Feature | What it is | Values |
|---|---|---|---|
| Where and How the Shot Was Taken | Distance | The distance from the shot origin to the center of the goal | Numerical value in feet |
| Angle | The angle of the shot away from the line straight out from the center of the goal | Numerical value in degrees | |
| Behind Net | If the shot came from behind the goal line | 0 or 1 (0 means it didn't, 1 means it did) | |
| Crossed Royal Road | If the puck crossed the middle of the ice, side to side, between the previous event and the shot | 0 or 1 (0 means it didn't, 1 means it did) | |
| Off Wing | If the shot came from the shooter's off wing (a left-handed shooter on the right side, or the reverse) | 0 or 1 (0 means it didn't, 1 means it did) | |
| Shot X Norm | How far along the length of the rink the shot was taken, normalized so the shooter is always attacking the same side | Numerical value in feet | |
| Shot Y Norm | How far to either side of the middle of the ice the shot was taken, normalized so the shooter is always attacking the same side | Numerical value in feet | |
| Shot Type | How the shot was taken | Wrist, snap, slap, backhand, tip-in, deflected, wrap-around, poke, bat, between-legs, cradle, or unknown (when the NHL didn't record a type) | |
| Shooter Shoots | The handedness of the shooter | Left or right, or unknown (when the NHL doesn't list it) | |
| What Led to the Shot | Prior Event Type | What the previous event was | Faceoff, shot on goal, hit, blocked shot, missed shot, giveaway, takeaway, goal, penalty, or none (no usable previous event) |
| Prior Miss Reason | If the previous event was a missed shot, how it missed | Wide left, wide right, wide of the net, high and wide left, high and wide right, above the crossbar, over the net, hit the crossbar, hit the left post, hit the right post, hit the goalpost, short, failed bank attempt, unknown, or none (the previous event wasn't a missed shot) | |
| Prior Event Elapsed | Time between the previous event and the shot | Numerical value in seconds | |
| Distance Change | How much closer to or farther from the goal the puck is compared with the previous event | Numerical value in feet (negative means the puck moved closer to the net) | |
| Angle Change | How much the angle to the goal changed from the previous event | Numerical value in degrees | |
| Prior Event Speed | How fast the puck traveled from the previous event to the shot | Numerical value in feet per second (capped at 50) | |
| Lateral Movement | How far the puck moved side to side since the previous event | Numerical value in feet | |
| Same Team As Prior Event | If the previous event belonged to the shooter's own team | 0 or 1 (0 means it didn't, 1 means it did) | |
| Prior X Norm | How far along the length of the rink the previous event was, normalized so the shooter is always attacking the same side | Numerical value in feet | |
| Prior Y Norm | How far to either side of the middle of the ice the previous event was, normalized so the shooter is always attacking the same side | Numerical value in feet | |
| Is Rush | If the shot is classified as a rush shot (if it came within four seconds of an event in the neutral or defensive zone, with no stoppage in play in between) | 0 or 1 (0 means it wasn't, 1 means it was) | |
| Rebound Chain Position | How many rebounds deep the shot is in a scramble, where each rebound is a follow-up shot by the same team within three seconds of its own shot on goal, with the count capped at 3 | 0 (not a rebound), 1, 2, or 3 (three or more) | |
| Time Since Chain Start | Time since the first shot of the rebound chain | Numerical value in seconds (blank for shots that aren't part of a rebound chain) | |
| Distance Since Chain Start | How far the shot is from the first shot of the rebound chain | Numerical value in feet (blank for shots that aren't part of a rebound chain) | |
| Game Situation | Strength | The on-ice situation when the shot was taken, as the shooter's skaters against the opponent's (the empty net models use each team's skater counts instead) | The possible values differ per model: 5v5: not used (every shot is 5v5); Other Even Strength: 4v4, 3v3 (periods 1 to 3), 3v3ot (overtime); Power Play: 5v4, 5v3, 4v3, etc.; Penalty Kill: 4v5, 3v4, 3v5, etc.; Empty Net For: 6v5, 6v4, 5v5, 5v4, etc.; Empty Net Against: 5v6, 5v5, 4v6, 5v4, etc. |
| Strength Elapsed | Time the current on-ice situation (skater counts and goalies in net) has been in effect, such as time into a power play | Numerical value in seconds | |
| Score State | The shooting team's goal lead at the time of the shot, capped at plus or minus 3 | -3 to 3 (whole goals) | |
| Period Number | The period of the game | 1, 2, 3, or 4 (overtime) | |
| Time Remaining In Period | Time left in the period | Numerical value in seconds | |
| Is Home | If the shooting team is the home team | 0 or 1 (0 means it didn't, 1 means it did) | |
| Is B2B | If the shooting team is playing the second game of a back-to-back | 0 or 1 (0 means it didn't, 1 means it did) | |
| Time Since Last Offensive-Zone Faceoff Win | Time since the shooting team won an offensive-zone faceoff, if there has been no whistle since | Numerical value in seconds (blank if there was no such faceoff win) | |
| Shots Since Last Offensive-Zone Faceoff Win | Shots the team has taken since that faceoff win | Whole number of shots (blank if there was no such faceoff win) | |
| Players and Fatigue | Shooter Shift Length | Time the shooter has been on their current shift | Numerical value in seconds |
| Opponent Shift Length Min | The shortest current shift among the opposing skaters on the ice | Numerical value in seconds | |
| Opponent Shift Length Avg | The average current shift of the opposing skaters on the ice | Numerical value in seconds | |
| Opponent Shift Length Max | The longest current shift among the opposing skaters on the ice | Numerical value in seconds | |
| Goalie Catches | The goalie's handedness | Left, right, or unknown (when the NHL doesn't list it) |
Two of the categorical features changed over the seasons, so not every value exists in every season. The shot type gained four options in 2022-2023 (bat, poke, between-legs, and cradle). The NHL's miss reasons were broad through 2022-2023 (wide of the net, over the net, goalpost, and hit the crossbar), but in 2023-2024 they became more specific (wide left, wide right, high and wide left, high and wide right, above the crossbar, hit the left post, hit the right post, and hit the crossbar, short) with one more option (failed bank attempt) added in 2024-2025.
The chart shows the 5v5 model, which has 36 of the 37 features (it doesn't use strength state as a feature since every shot in it is 5v5). Each bar is a feature's share of the total gain (how much its splits improve the model).
Where Shots Are Worth the Most
The map below shows the average xG of a 5v5 shot from each spot between the red line and the end boards, using every out-of-sample season from 2014-2015 through 2025-2026 and leaving blank any spot with fewer than 10 shots. It shows what the model learned about geometry: xG climbs steadily toward the crease and is highest straight out in front of the net, which lines up with the shot danger zones.
One thing to keep in mind is the area behind the goal line, which looks dangerous on this map but in realit isn't nearly that dangerous. The NHL records a shot at the spot where the shooter was when it happened, so a wrap-around shot, which starts behind the net and ends up on the goalie from close range, is logged as a shot from behind the net, and the model rates those shots highly. Few shots are taken from back there, so a handful of goals can also make a spot look better than it is. In reality these shots score far less often than the model expects: across the out-of-sample seasons, 5v5 shots from behind the net scored about 430 goals against about 660 expected.
Model Performance
AUC (area under the ROC curve) measures how well the model separates goals from non-goals, where 0.5 is no better than random and 1.0 is perfect separation. Log loss measures how close the predicted probabilities are to what happened (lower is better), and calibration is total predicted xG divided by actual goals, where 1.00 means the model predicted exactly the right number of goals. Every season from 2014-2015 on is scored out of sample, and the shaded seasons mark the in-sample seasons. The charts show the three main models (5v5, power play, and penalty kill), while the tables include all six.
AUC (higher is better)
| Season | 5v5 | PP | PK | Other ES | EN Against | EN For | Overall |
|---|---|---|---|---|---|---|---|
| 2009-2010 | 0.799 | 0.763 | 0.897 | 0.762 | 0.945 | 0.898 | 0.804 |
| 2010-2011 | 0.805 | 0.759 | 0.878 | 0.860 | 0.922 | 0.901 | 0.811 |
| 2011-2012 | 0.805 | 0.780 | 0.910 | 0.887 | 0.942 | 0.878 | 0.816 |
| 2012-2013 | 0.800 | 0.755 | 0.869 | 0.890 | 0.931 | 0.892 | 0.809 |
| 2013-2014 | 0.803 | 0.768 | 0.876 | 0.867 | 0.906 | 0.869 | 0.811 |
| 2014-2015 | 0.790 | 0.732 | 0.818 | 0.745 | 0.853 | 0.740 | 0.790 |
| 2015-2016 | 0.796 | 0.718 | 0.787 | 0.741 | 0.757 | 0.768 | 0.795 |
| 2016-2017 | 0.794 | 0.731 | 0.774 | 0.699 | 0.816 | 0.696 | 0.791 |
| 2017-2018 | 0.786 | 0.723 | 0.832 | 0.697 | 0.646 | 0.720 | 0.787 |
| 2018-2019 | 0.787 | 0.701 | 0.808 | 0.680 | 0.811 | 0.724 | 0.786 |
| 2019-2020 | 0.781 | 0.699 | 0.833 | 0.734 | 0.857 | 0.696 | 0.780 |
| 2020-2021 | 0.785 | 0.707 | 0.832 | 0.688 | 0.706 | 0.709 | 0.784 |
| 2021-2022 | 0.771 | 0.687 | 0.817 | 0.705 | 0.725 | 0.688 | 0.773 |
| 2022-2023 | 0.761 | 0.672 | 0.814 | 0.710 | 0.693 | 0.686 | 0.761 |
| 2023-2024 | 0.767 | 0.659 | 0.819 | 0.692 | 0.658 | 0.715 | 0.764 |
| 2024-2025 | 0.773 | 0.664 | 0.788 | 0.718 | 0.672 | 0.711 | 0.774 |
| 2025-2026 | 0.779 | 0.670 | 0.822 | 0.726 | 0.763 | 0.677 | 0.776 |
Log loss (lower is better)
| Season | 5v5 | PP | PK | Other ES | EN Against | EN For | All Situations |
|---|---|---|---|---|---|---|---|
| 2009-2010 | 0.185 | 0.261 | 0.170 | 0.189 | 0.315 | 0.186 | 0.199 |
| 2010-2011 | 0.180 | 0.260 | 0.181 | 0.189 | 0.376 | 0.193 | 0.195 |
| 2011-2012 | 0.181 | 0.254 | 0.176 | 0.167 | 0.354 | 0.186 | 0.193 |
| 2012-2013 | 0.182 | 0.277 | 0.174 | 0.159 | 0.347 | 0.183 | 0.197 |
| 2013-2014 | 0.179 | 0.256 | 0.210 | 0.177 | 0.404 | 0.194 | 0.194 |
| 2014-2015 | 0.183 | 0.271 | 0.195 | 0.203 | 0.452 | 0.234 | 0.200 |
| 2015-2016 | 0.178 | 0.274 | 0.236 | 0.261 | 0.564 | 0.230 | 0.199 |
| 2016-2017 | 0.181 | 0.273 | 0.246 | 0.301 | 0.498 | 0.224 | 0.201 |
| 2017-2018 | 0.185 | 0.278 | 0.208 | 0.315 | 0.636 | 0.268 | 0.206 |
| 2018-2019 | 0.191 | 0.296 | 0.216 | 0.325 | 0.498 | 0.240 | 0.212 |
| 2019-2020 | 0.195 | 0.295 | 0.203 | 0.286 | 0.442 | 0.268 | 0.216 |
| 2020-2021 | 0.196 | 0.294 | 0.194 | 0.323 | 0.594 | 0.287 | 0.217 |
| 2021-2022 | 0.202 | 0.301 | 0.208 | 0.300 | 0.573 | 0.274 | 0.222 |
| 2022-2023 | 0.205 | 0.307 | 0.222 | 0.318 | 0.611 | 0.266 | 0.227 |
| 2023-2024 | 0.202 | 0.306 | 0.217 | 0.335 | 0.635 | 0.255 | 0.224 |
| 2024-2025 | 0.196 | 0.316 | 0.230 | 0.319 | 0.627 | 0.255 | 0.220 |
| 2025-2026 | 0.201 | 0.305 | 0.207 | 0.292 | 0.573 | 0.267 | 0.223 |
Calibration (closer to 1.00 is better)
| Season | 5v5 | PP | PK | Other ES | EN Against | EN For | All Situations |
|---|---|---|---|---|---|---|---|
| 2009-2010 | 0.99 | 1.00 | 1.08 | 0.91 | 0.97 | 1.01 | 0.98 |
| 2010-2011 | 1.01 | 1.02 | 1.00 | 0.95 | 1.04 | 0.93 | 1.00 |
| 2011-2012 | 1.00 | 1.01 | 0.99 | 1.04 | 0.98 | 1.05 | 0.99 |
| 2012-2013 | 0.99 | 0.92 | 1.10 | 1.09 | 0.95 | 1.07 | 0.97 |
| 2013-2014 | 1.00 | 1.02 | 0.86 | 0.98 | 1.04 | 0.99 | 0.99 |
| 2014-2015 | 1.00 | 0.99 | 1.06 | 1.00 | 1.02 | 1.03 | 0.99 |
| 2015-2016 | 1.03 | 0.97 | 0.90 | 0.86 | 0.97 | 1.00 | 0.99 |
| 2016-2017 | 1.01 | 0.99 | 0.89 | 0.81 | 1.00 | 1.21 | 0.99 |
| 2017-2018 | 1.00 | 1.00 | 0.96 | 0.86 | 0.98 | 0.84 | 0.97 |
| 2018-2019 | 0.97 | 0.95 | 0.98 | 0.82 | 0.99 | 1.02 | 0.95 |
| 2019-2020 | 1.06 | 1.06 | 1.02 | 1.00 | 1.08 | 0.91 | 1.03 |
| 2020-2021 | 1.03 | 1.03 | 1.12 | 0.96 | 1.01 | 0.86 | 1.01 |
| 2021-2022 | 1.04 | 1.08 | 1.09 | 1.11 | 0.98 | 1.01 | 1.03 |
| 2022-2023 | 1.08 | 1.12 | 1.02 | 1.03 | 1.04 | 1.18 | 1.07 |
| 2023-2024 | 1.06 | 1.15 | 0.95 | 0.91 | 1.02 | 1.23 | 1.05 |
| 2024-2025 | 1.01 | 1.02 | 0.84 | 1.00 | 1.02 | 1.11 | 1.00 |
| 2025-2026 | 1.03 | 1.11 | 1.07 | 1.15 | 1.11 | 1.06 | 1.04 |
Limitations and Things to Keep in Mind
- Power-play xG is the weakest model. Public play-by-play has no passing or screen information, and those are what make many power-play chances dangerous, so power-play AUC has slipped from about 0.73 in 2014-2015 to about 0.67 in 2025-2026, and its calibration has run high (up to 1.15) in recent seasons.
- The small models are noisy. They train on only a few hundred to a few thousand shots a season, so penalty kill calibration, for example, ranges from 0.84 to 1.12 across seasons.
- xG can't see passing or screens. A player who sets up good chances gets credit only through on-ice ratings, while the shooter who finishes them gets credit for beating xG, so scorers tend to rate a bit above playmakers.
- The model doesn't know who is shooting or in net. It only knows which hand the shooter shoots with and the goalie catches with. That is deliberate, since finishing and goaltending are measured separately, but it means xG is the chance an average shooter would score against an average goalie.
- Blocked shots aren't modeled, so a player or team who blocks shots well gets no xG credit for it.
- Second shots in a scramble count in full. A flurry discount is used only for RAPM, so a player's own xG totals count every shot in a rebound chain at full value.
- Penalty shots use a fixed value (per season) that doesn't vary by shooter, goalie, or the actual shot taken.
- The prior miss reason changed in 2023-2024. It carries more detail in recent seasons than in older ones (see the features above).
- The first five seasons are in-sample. Their xG, and anything built on it, is flattered a little, so treat 2009-2010 through 2013-2014 as a bit more descriptive than predictive.
- Some NHL data is missing. Five games have no or partial shift data, so they are missing from, or only partly counted in, the on-ice stats, RAPM and WAR, though their shots and goals still count in individual stats. Three are in 2009-2010 and have none (PIT at CAR on 2009-10-14, NYI at DAL on 2010-01-08, and SJS at CBJ on 2010-02-10), one is in 2010-2011 and has about half (WSH at CAR on 2010-10-27), and one is in 2013-2014 and has none (CBJ at DAL on 2014-04-09). In 2009-2010, 2,161 shots (about 2.1% of the season's shots) have no strength state because of gaps in the shift data: 256 are from the three games above and the rest are spread over about 290 other games. They count in the all-situations stats but not in the 5v5, 5v4 or 4v5 splits, and the xG model scores them with its catch-all other even strength model, so that season's xG is less reliable. One game in 2009-2010 (TBL at FLA on 2010-01-16) has no faceoff data.
Regularized Adjusted Plus-Minus (RAPM)
What Is RAPM?
Raw plus-minus has an obvious problem: it credits and blames players for everything that happens while they're on the ice, regardless of who else is out there. RAPM isolates each player's individual contribution using ridge regression across every stint in a season. Ridge regression estimates every player's effect at the same time, and the "ridge" part pulls each player toward average so linemates don't absorb each other's credit. It covers the 2009-2010 through 2025-2026 regular seasons. It is built from the NHL's shift charts, which record who is on the ice and when, and from the xG of every shot, with roughly 300,000 to 410,000 stints in a full season. The ratings produced, measured in expected goals per hour, feed WAR below. For example, Connor McDavid's Even Strength Offense rating in 2025-2026 is +0.48, which means their team is estimated to have generated about 0.48 more expected goals per hour of even strength play with him on the ice than if they would have had an average player in his place, after adjusting for their teammates and opponents.
The Ridge Regression
Building the Stints
Every stint, a stretch of play where no player changes, is reconstructed from the shift charts. Shift changes recorded within one second of each other are treated as one line change, because the chart logs a change's outgoing and incoming players a second or two apart, which otherwise creates a flurry of very short one to three second stints with an impossible lineup.
The Response
The predicted xG of every shot in the stint is attached, and each stint becomes a regression row from both teams' perspectives: one column for every offensive player on the ice, one for every defensive player, and the response is the xG rate generated during the stint, weighted by its length. So every player ends up with two numbers: an offense rating (how much they add to their team's xG rate) and a defense rating (how much they cut the opponent's). I use xG as the response because that is the typical way to build an RAPM, and real goals are far noisier.
The xG response is flurry-adjusted: every shot after the first in a same-team rebound chain is discounted by the chance the chain had already scored, because raw xG would count one scramble's single scoring chance once per rebound and over-reward whoever was on the ice for flurries. Each stint's implied rate is also capped at 50 per hour so a handful of very short, high-scoring stints can't dominate the fit.
Context Covariates
A short list of context covariates sits alongside the player columns, so a player isn't credited or blamed for the situations they were deployed in. Each stint becomes two rows, one from each team's side: the team whose players are in the offense columns is the offense team and the other is the defense team, and every covariate below is from the offense team's side unless it says otherwise. Every covariate is fed to the regression as 0s and 1s, one column per category.
| Covariate | What it is | Values |
|---|---|---|
| Zone Start | The zone of any faceoff during the stint, from the offense team's side (offensive, defensive, or neutral). A stint with no faceoff has all three at 0 | Offensive, defensive, or neutral (each fed in as 0 or 1) |
| Score State | The offense team's goal lead or deficit, capped at plus or minus 3. Tied is the baseline, so it has no column of its own | Up 1, up 2, up 3 or more, down 1, down 2, down 3 or more, or tied (each fed in as 0 or 1) |
| Special-Teams Expiry | An even-strength stint that starts within 10 seconds after a power play or penalty kill ends. One flag is for when the offense team was the one on the power play, the other for when it was the one shorthanded | 0 or 1 for each flag (0 means it didn't, 1 means it did) |
| Special-Teams Start on the Fly | A power-play or penalty-kill stint that began straight out of even strength with no faceoff at its start (play never stopped). The same flag for both teams | 0 or 1 (0 means it didn't, 1 means it did) |
| Home Ice | If the offense team is the home team | 0 or 1 (0 means it isn't, 1 means it is) |
| Back-to-Back | If the offense team, and separately the defense team, is playing the second game of a back-to-back | 0 or 1 for each team (0 means it isn't, 1 means it is) |
| State Flags | Which situation the stint was played in, with 5v5, 5v4 and 4v5 as the baselines in their fits | 4v4 or 3v3 in the even-strength fit, 5v3 or 4v3 in the power-play fit, 3v5 or 3v4 in the penalty-kill fit (each fed in as 0 or 1) |
The Ridge Penalty
Ridge is needed because linemates play together, and without it the ratings are wildly unstable. The ridge penalty shrinks every player's rating toward its prior (zero, or last season's rating, below). Its strength for the player columns is fixed for each fit: 20.0 for even strength and 10.0 for both the power-play and penalty-kill fits. The context covariates get one fixed, much lighter penalty of 1.0 through a column-scaling trick, since there are only a handful of them and they're well observed.
Separate Fits and the Six Ratings
Even strength and special teams are fit as separate regressions, since power-play and penalty-kill units behave very differently from 5v5 play. The special teams are fit twice, once from the power-play side and once from the penalty-kill side, because who is attacking and who is defending in the same stints are different questions. Both fits pool the rarer states in with the main one, with a pair of flags telling the model which state each stint was played at. The even strength pools 5v5, 4v4, and 3v3, the power-play fit pools 5v4, 5v3, and 4v3, and the penalty-kill fit pools 4v5, 3v5, and 3v4. That lets those stints, individually too sparse to support their own regression, still contribute signal. Each fit gives an offense and a defense rating, and the three fits together produce six ratings, named by the situation the skater is playing in. All six are signed so a higher number is better, including on defense:
| Rating | What it is | Skater's States Pooled In |
|---|---|---|
| Even Strength Offense | A skater's effect on their team's expected goal rate at even strength | 5v5, 4v4, 3v3 |
| Even Strength Defense | A skater's effect on the opponent's expected goal rate at even strength | 5v5, 4v4, 3v3 |
| Power Play Offense | A skater's effect on their team's expected goal rate on the power play | 5v4, 5v3, 4v3 |
| Power Play Defense | A skater's effect on the opponent's expected goal rate while on the power play | 5v4, 5v3, 4v3 |
| Penalty Kill Defense | A skater's effect on the opponent's expected goal rate while shorthanded | 4v5, 3v5, 3v4 |
| Penalty Kill Offense | A skater's effect on their own team's expected goal rate while shorthanded | 4v5, 3v5, 3v4 |
Last Season's Rating as a Starting Point
Instead of shrinking everyone toward zero, a player's rating is shrunk toward a prior built from last season's saved rating:
$$ \text{prior}_{i,t} = a + b \times r_{i,t-1} $$
where \( r_{i,t-1} \) is the player's rating last season, \( a \) is an intercept, and \( b \) is a slope: how much of that component actually repeats from year to year. The slope is fit separately for forwards and defensemen, and for each of the six components, on the five seasons before the one being rated, so a season's prior never uses its own data. These are the slopes behind the 2025-2026 priors (fit on 2020-2021 through 2024-2025):
| Rating | Forwards | Defensemen |
|---|---|---|
| Even Strength Offense | 0.65 | 0.45 |
| Even Strength Defense | 0.44 | 0.35 |
| Power Play Offense | 0.59 | 0.45 |
| Power Play Defense | 0.11 | 0.22 |
| Penalty Kill Defense | 0.24 | 0.30 |
| Penalty Kill Offense | 0.32 | 0.19 |
A slope of 0.65 means a forward's Even Strength Offense rating carries about 65% of last year's rating forward, while the Penalty Kill ratings and Power Play Defense carry only 11% to 32%, which is why they are the least stable. A full, slope-of-one prior would make ratings too sticky, since a strong year would almost never be followed by a poor one. Because each season's prior is the previous season's saved, already prior-informed rating, a player's history chains forward through the years. Using only last season keeps this simple, since the chain already carries earlier seasons forward, though I may look at a longer lookback later. The first season in the data has no earlier season, so it is fit with no prior.
What a Rating Means
The output is a rate stat per player per situation (even strength offense and defense, power play offense and defense, and penalty kill offense and defense) that represents estimated on-ice impact independent of who they're playing with or against. A rating from a prior-informed fit is best read as the best estimate of a player's current ability using last season as a starting point, not as a purely descriptive account of that one season.
Limitations and Things to Keep in Mind
- RAPM inherits xG's blind spots. It can't see certain events such as passing or screens (see the xG limitations).
- Players who are almost always together are hard to separate. Linemates who are almost always on the ice together can't be fully told apart, even with ridge.
- Ratings are rates, and low-minute players are uncertain. Players with little ice time have noisier ratings, and the ridge pulls them toward their prior.
- Deployment is only partly captured. How a player was used is captured only through the covariates listed above, so anything else about their role isn't adjusted for.
- Ratings lean on last season. They estimate current ability and are not a purely descriptive account of one season, and the 2009-2010 ratings, the first season in the data, have no prior at all, so they are noisier.
- Eras aren't strictly comparable. Ratings spread out more after 2021, so compare seasons using ranks and percentiles more than raw ratings.
- Empty-net and other very rare situations aren't included. Only 5v5, 4v4, 3v3, 5v4, 5v3, 4v3, 4v5, 3v5 and 3v4 are used, with both goalies in net, so play with a goalie pulled is left out (about 2% of ice time).
- The first five seasons use in-sample xG. Treat those ratings as approximate (see the xG limitations).
- Three games in 2009-2010, one in 2010-2011 and one in 2013-2014 are missing some shift data (the 2009-2010 and 2013-2014 games have none, and the 2010-2011 game has about half), so they have no or partial stints and are left out of or only partly counted in those seasons' RAPM and WAR, though their shots and goals still count in individual stats.
Wins Above Replacement (WAR)
What Is WAR?
WAR is built on top of RAPM. RAPM gives each player several ratings in expected goals per hour, which can be hard to compare or add up. WAR turns them, along with finishing and penalties, into one easy-to-read number: how many wins a player contributed over a season compared with a replacement-level player (at even strength, a typical 14th forward or 8th defenseman). WAR reports what happened: a player's WAR is their actual goals above expected, luck included, so use it as a description of a season and RAPM as the better guide going forward.
The Components
A skater's WAR is the sum of eight components, and a goalie's WAR has three:
$$ \text{WAR}_{\text{skater}} = \text{ES Off} + \text{ES Def} + \text{PP Off} + \text{PP Def} + \text{PK Off} + \text{PK Def} + \text{Fin} + \text{Pen} $$
$$ \text{WAR}_{\text{goalie}} = \text{ES} + \text{PK} + \text{PP} $$
Finishing and penalties are each already the sum of their pieces across every strength (5v5, 5v4, 4v5, and the rarer states), so a skater's total covers all of their ice time. Goalie WAR is built from separate goalie components and is not added to any skater components.
Skater components
| Component | What it measures | Built from | Replacement level (ranked by team ice time) |
|---|---|---|---|
| Even Strength Offense | Goals added at even strength | Even Strength Offense rating and even-strength ice time | Forwards ranked 14th or lower, defensemen 8th or lower |
| Even Strength Defense | Goals prevented at even strength | Even Strength Defense rating and even-strength ice time | Forwards ranked 14th or lower, defensemen 8th or lower |
| Power Play Offense | Goals added on the power play | Power Play Offense rating and power-play ice time | Forwards ranked 10th or lower, defensemen 4th or lower |
| Power Play Defense | Goals prevented while on the power play | Power Play Defense rating and power-play ice time | Forwards ranked 10th or lower, defensemen 4th or lower |
| Penalty Kill Offense | Goals added while shorthanded | Penalty Kill Offense rating and penalty-kill ice time | Forwards ranked 8th or lower, defensemen 6th or lower |
| Penalty Kill Defense | Goals prevented on the penalty kill | Penalty Kill Defense rating and penalty-kill ice time | Forwards ranked 8th or lower, defensemen 6th or lower |
| Finishing | Goals scored beyond what the shot quality (xG) predicts | Actual goals minus the xG of their own shots, in every strength | The rate depth players actually shoot at |
| Penalties | Penalties drawn minus penalties taken | Net penalty minutes, valued at the xG a power play is worth per minute | The penalty rate of even-strength depth players |
Goalie components
| Component | What it measures | Built from | Replacement level |
|---|---|---|---|
| Even Strength | Goals saved beyond what the shots predict | Goals Saved Above Expected (GSAx) at 5v5, 4v4, and 3v3 | The backups on each team (every goalie below the starter) |
| Penalty Kill | Goals saved beyond what the shots predict while shorthanded | GSAx while the goalie's team is a skater or two down (4v5, 3v5, 3v4) | The backups on each team (every goalie below the starter) |
| Power Play | Goals saved beyond what the shots predict while the goalie's team is on the power play | GSAx while the goalie's team is a skater or two up (5v4, 5v3, 4v3) | The backups on each team (every goalie below the starter) |
How WAR Is Calculated
A player's WAR for a component is the difference between their own rate and replacement level, scaled by their ice time and converted from goals to wins:
$$ \text{WAR}_{\text{component}} = (\text{rate} - \text{replacement rate}) \times \text{hours played} \times \dfrac{k}{4 \bar{g}} $$
where \( \bar{g} \) is that season's league average goals per team per game (counting only goals scored against a real goalie, to match the components, which all exclude empty-net play) and \( k \) is the Pythagorean exponent, a sabermetrics method that relates goals scored and allowed to win percentage, used here in reverse to translate a goal swing into a win swing. The 4 comes from taking the Pythagorean formula's slope at an average team, where \( k / (4 \bar{g}) \) is the number of wins one extra goal is worth. I fit \( k \) once, to the standings of every NHL season in the data, and it comes out at 2.15. Because \( \bar{g} \) is each season's own league average, the same \( k \) works out to somewhere between 4.5 and 5.5 goals per win, depending on how much scoring there was that season.
For example, take a forward in 2025-2026 with a +0.48 Even Strength Offense rating, against a replacement level of -0.02. That is 0.50 expected goals per hour better than replacement. Over 24 hours of even strength ice time, that is about 12.0 expected goals, and at that season's 0.192 wins per goal, the component is worth about 2.3 wins.
WAR here is a season total in wins. Among skaters who played at least half a season (leaving out the three shortened seasons), the median is about 0.5 WAR, the top quarter are above 1.25, the top 10% are above 2.3, and the best skater each season lands between about 4.7 and 8.9. Goalies are more spread out: among goalies with at least a quarter of a season, the median is about 0.9 and the top 10% are above 4.5.
Replacement Level
Replacement level is the performance of an easy-to-find player, a fringe lineup regular. For each component, I compute a replacement-level rate per position from the players ranked below a cutoff in ice time on their own team in that situation. That ties replacement level to who is realistically available on a roster, not to a fixed league-wide percentile. Each component is measured against its own replacement level. The cutoffs are hand-picked.
| Situation | Used for | Forwards ranked | Defensemen ranked |
|---|---|---|---|
| Even strength | Even Strength Offense, Even Strength Defense, even-strength finishing, and penalties | 14th or lower | 8th or lower |
| Power play | Power Play Offense, Power Play Defense, and power-play finishing | 10th or lower | 4th or lower |
| Penalty kill | Penalty Kill Offense, Penalty Kill Defense, and penalty-kill finishing | 8th or lower | 6th or lower |
| Goalies | Even Strength, Penalty Kill, and Power Play | Every goalie ranked below the team's starter | |
Finishing
Finishing is a player's actual goals minus the xG of their own shots (goals above expected), then taken above replacement. A replacement-level shooter isn't an average shooter: in every season, replacement-level forwards scored only about 72% to 86% of their xG at 5v5 while regular forwards scored close to all of it. So the baseline is the rate depth players actually shoot at, and a regular's finishing WAR is their goals above expected minus what a replacement-level shooter would have scored on the same number of shots, converted to wins. Whether that gap is real finishing talent or shot quality the xG model can't see (passes and screens) can't be separated with public data. This is the finishing piece of a goals-above-replacement measure: because depth players really do shoot worse than xG, an average finisher is worth more than zero above replacement.
Finishing is measured separately by the strength the shooter's team was at: 5v5, 5v4, 4v5, and three groups of rarer states, "Other even strength" (4v4 and 3v3), "Other power play" (5v3 and 4v3), and "Other penalty kill" (3v5 and 3v4). Each group has its own replacement rate, taken from the depth players of the matching situation, and the pieces add up to a player's finishing WAR.
Penalties
Penalties are net minutes drawn minus minutes taken, valued at the xG a power play is worth per minute. Every penalty is valued as a full power play, for simplicity. That value is fit for each season from the five before it and depends on the situation the penalty was taken in: roughly 0.09 to 0.11 xG per minute at 5v5 (so a two-minute minor is worth about 0.2 xG to the other team), and about 0.19 to 0.26 when the team is already shorthanded, since that pushes the game further into a lopsided state.
Penalties are split the same way as finishing, by the strength the committing player's team was at before the penalty: 5v5, 5v4, 4v5, Other even strength (4v4 and 3v3), Other power play (5v3 and 4v3), and Other penalty kill (3v5 and 3v4). The rarer groups are too small to fit their own value per minute, so each uses the value of the nearest main state: Other even strength uses the 5v5 value, Other power play uses 5v4, and Other penalty kill uses 4v5.
Only penalties that are an individual player's doing count:
| Penalty | Charged to | Credited to |
|---|---|---|
| An ordinary penalty | The player who took it | The player who drew it |
| A penalty nobody drew (puck over the glass, embellishment) | The player who took it | No one |
| A team penalty (too many men, bench minors, unsuccessful challenges) | No one, since the "taker" only served the time | No one |
| Matching fighting majors | Cancel out for each fighter | Cancel out for each fighter |
Penalty value is measured against replacement the same way as finishing, using the penalty rate per hour of ice time of even-strength depth players, because the special-teams pools alone are too thin to give a stable baseline.
Goalie WAR
Goalies skip RAPM entirely and get their own WAR built from Goals Saved Above Expected (GSAx), the xG against minus the actual goals against, at even strength, on the penalty kill, and on the power play, measured against the backups on each team (every goalie below the starter) and converted to wins the same way as skaters. Short misses (explained in the xG section) aren't in the shot data, so goalies get no credit for them.
Limitations and Things to Keep in Mind
- Scorers rate a bit above playmakers. xG can't see passing or screens (see the xG limitations), so the shooter who finishes a chance is credited with beating xG while the passer is credited only through on-ice ratings.
- Goalie WAR depends on an xG model that doesn't know who is shooting. The xG model only knows which hand the shooter shoots with, so a goalie who faces more dangerous shooters than average, or whose team gives up more screens and passes than the model can see, gets credit or blame that isn't theirs.
- WAR is a counting stat. Missed games and shortened seasons lower a player's WAR, so a player who was hurt has fewer chances to add wins.
- League totals float. Nothing pins league WAR to a fixed number, so it moves with how many players are above replacement and how lucky the goalies and shooters were that year. In a typical season, about 40% of skaters finish below 0 WAR (between 34% and 43% across the 17 seasons), so compare seasons using ranks and percentiles more than raw totals.
- The replacement-level cutoffs are hand-picked. Moving them shifts every player's WAR.
- Penalties are all valued as a full power play. That is a simplification, since a minor ends early when the power play scores and overlapping penalties don't each give a full extra power play.
- Empty-net and other very rare situations aren't included. Play with a goalie pulled, and any state outside the ones listed in the RAPM section, counts toward neither RAPM nor WAR, including empty-net goals scored and allowed.
- The first five seasons use in-sample xG. Treat 2009-2010 through 2013-2014 as approximate (see the xG limitations).
- Some games are missing shift data. Five games have no or partial shift data, so they are left out of or only partly counted in WAR (see the RAPM limitations).
Elo Ratings
What Is Elo?
A team's win-loss record alone doesn't capture the strength of the opponents it played or how close those games actually were. Elo addresses that by giving every team a single rating that updates after each game based on how the actual result compared to what was expected, so a win over a strong team moves the rating more than a win over a weak one. Elo covers every regular-season game from 2009-2010 through 2025-2026. Because ratings update after every result, Elo reflects a team's current form and trajectory over the course of a season, rather than a single fixed-in-time snapshot.
How Ratings Update
Elo Calculation
Team Elo ratings update after every game of a season, starting every team at a rating of 1500 at the start of each season. Before a game, each team's expected score (between 0 and 1) is calculated from the ratings gap between the two teams using the standard logistic Elo expectation formula, where team A is the home team, \( R_A \) and \( R_B \) are the two teams' ratings, \( H = 30 \) is a fixed home-ice advantage added to the home team's rating, and \( D = 400 \) is the Elo scale factor that controls how quickly the expected score approaches 0 or 1 as the ratings gap grows. The away team's expected score is \( 1 - E_A \):
$$ E_A = \dfrac{1}{1 + 10^{\frac{R_B - (R_A + H)}{D}}} $$
After the game, the home team's rating shifts based on the difference between the actual result \( S_A \) and the expected score \( E_A \), scaled by a K-factor of 20 and a margin-of-victory multiplier \( M \), and the away team's rating moves by the same amount in the opposite direction:
$$ R_A' = R_A + K (S_A - E_A) \times M $$
The constants are:
| Constant | Value | What it is |
|---|---|---|
| Starting rating | 1500 | Every team's rating at the start of each season |
| Home-ice advantage (H) | 30 | Added to the home team's rating before the expected score is calculated |
| Scale (D) | 400 | How quickly the expected score approaches 0 or 1 as the ratings gap grows |
| K-factor (K) | 20 | How far a single result can move a rating |
To get a feel for the scale, a team rated 100 points higher than its opponent has an expected score of about 0.64, and the 30-point home-ice advantage on its own is worth an expected score of about 0.54.
Scoring Results
Results aren't scored as a simple win/loss. Each result type is assigned a fixed value for \( S_A \), so a regulation win is worth full credit while overtime and shootout results are worth partial credit in both directions, and the rating system reflects how close a game actually was, not just who won:
| Result | Value |
|---|---|
| Regulation Win | 1.0 |
| Overtime Win | 0.9 |
| Shootout Win | 0.7 |
| Shootout Loss | 0.3 |
| Overtime Loss | 0.1 |
| Regulation Loss | 0.0 |
The Margin-of-Victory Multiplier
The margin-of-victory multiplier scales each rating change by how lopsided the final score was, where the margin is the winner's goals minus the loser's. It grows with the goal margin on a log scale, so each extra goal counts for less than the one before. It is also dampened as the gap between the two teams' ratings widens, so a blowout win by the stronger team moves ratings less than the same margin from the weaker team. Shootout results always use a flat multiplier of 1.0 instead, since the shootout goal differential isn't a meaningful measure of game control.
The formula is adapted from Neil Paine's NHL Elo methodology, where \( R_w \) and \( R_l \) are the winning and losing team's ratings:
$$ M = \dfrac{(0.6686 \ln(\text{margin}) + 0.8048) \times 2.05}{(R_w - R_l) \times 0.001 + 2.05} $$
Limitations and Things to Keep in Mind
- Hockey is noisy. Even a good Elo picks the winner only a little more often than always picking the home team: across all 20,382 games, picking the team with the higher Elo (home ice included) was right 56.5% of the time, against 54.2% for always picking the home team.
- It only knows scores. Injuries, goalies, lineup changes, and rest aren't considered.
- Empty-net goals inflate the margin. A late empty-net goal widens the final margin, so the winner's rating gain is larger than the game's closeness suggests.
- Ratings reset every season. Every team starts at 1500, so early-season ratings sit close together and depend on opponents whose own ratings are still settling, and ratings aren't comparable from one season to the next.
- Home ice is one fixed value. It is the same 30 points for every team and every season.
Simple Rating System (SRS)
What Is SRS?
SRS gives every team one rating for a season: how many goals per game better or worse than an average team it was, after adjusting for the opponents it played and for home ice. Put simply, it is a team's goal differential per game, adjusted for who it played and where. It solves for a whole season's worth of results all at once, so the fit isn't sensitive to which order the games were played in. SRS is fit separately for every regular season from 2009-2010 through 2025-2026. For a rating that updates after every game instead, see Elo above.
How SRS Is Calculated
It estimates a single rating for every team, plus one shared home-ice advantage value \( H \), by minimizing the sum of squared residuals between each team's predicted and actual goal margins across every game in a season. A (home) team's predicted margin \( \hat{m}_h \) against an away team in any given game is simply the difference between the two teams' ratings, adjusted for home ice:
$$ \hat{m}_h = (R_h - R_a) + H $$
The optimization then solves for the full set of team ratings and \( H \) that minimize the total squared error between every predicted margin \( \hat{m}_g \) and the actual margin \( m_g \) across all \( n \) games in the season:
$$ \underset{R,\, H}{\arg\min} \sum_{g=1}^{n} (m_g - \hat{m}_g)^2 $$
The ratings are also constrained so that the league-wide average rating \( \bar{R} \) is zero.
The final output is a single rating per team. Taking the difference between any two teams' ratings and adding the home-ice advantage gives the model's predicted goal margin if those two teams played each other, with \( R_h \) as the home team and \( R_a \) as the away team. For example, a home team rated +0.40 against an away team rated -0.20 is predicted to win by 0.40 - (-0.20) + 0.26 = 0.86 goals, using a typical home-ice value of 0.26. The table below lists what goes into the fit and what it solves for:
| Piece | What it is |
|---|---|
| Game margin (input) | The home team's goals minus the away team's goals in a regular-season game (a shootout win counts as a one-goal margin) |
| Team rating (solved for) | One value per team, in goals per game above or below the league average |
| Home-ice advantage, H (solved for) | One value shared by every team, fit alongside the ratings (it averages about 0.26 goals per game, and ranges from 0.13 to 0.36 across seasons) |
| Constraint (rule for the fit) | The ratings average zero, so a rating only means something against the other teams in the same season |
Limitations and Things to Keep in Mind
- It measures goals, not shot quality. Good or bad luck in scoring and goaltending is part of a team's rating.
- Every goal counts the same. Blowouts and empty-net goals count fully, and a shootout win counts as a one-goal margin.
- One blowout can pull a rating a lot. The fit uses squared error with no cap on the goal margin, so a single lopsided game counts for more than several close ones.
- It's one rating for the whole season. A team that changed a lot at the deadline still gets a single rating, so SRS can't show a trend.
- Ratings compare teams within a season only. They average zero each season, and shortened seasons have fewer games behind each rating.
- Home ice is one shared value. It is the same for every team within a season.
Glossary
A reference for common hockey analytics, statistics, and data science terms, whether you're reading through this site or hockey analytics content elsewhere. Search for a term, or open a section below.
No matching terms.
Basic Hockey Terms (25)
Positions (Skater, Forward, Defenseman, Goalie)
A skater is any player who isn't the goalie. Skaters are forwards (a center and a left and right winger) and defensemen. A team typically dresses 12 forwards, 6 defensemen, and 2 goalies, and plays with five skaters and a goalie on the ice at full strength.
Forward Lines and Defense Pairs
Teams change players constantly. Forwards play in groups of three (a center and two wingers) called lines, and defensemen play in groups of two called pairs. A team usually dresses four forward lines and three defense pairs, with the top lines and pairs playing the most.
Zones (Offensive, Neutral, Defensive)
The two blue lines split the ice into three zones. A team's defensive zone is the end it's defending, its offensive zone is the end it's attacking, and the neutral zone is the middle.
Faceoff
How play starts or restarts. An official drops the puck between one player from each team, usually the centers, who battle for possession. Faceoffs happen at the start of each period and after stoppages.
Preseason
The exhibition games a team plays before the regular season starts, where coaches test lineups and look at prospects. They don't count in the standings.
Regular Season
The schedule of games that decides the standings. Each team plays 84 (used to be 82) games, and the standings decide which 16 teams (8 per conference) reach the playoffs.
Playoffs
The postseason tournament for the 16 teams that qualify. It is a series of best-of-seven rounds that ends with the Stanley Cup Final.
Home-Ice Advantage
The statistical edge a team gets from playing in its own arena.
Overtime/Overtime Loss
If a regular season game is tied after 60 minutes of play, it goes to a five-minute overtime with three skaters a side (four a side before 2015-2016), and then a shootout if it's still tied. A team that loses in overtime or a shootout still earns one standings point (an overtime loss, OTL), where a regulation loss earns none.
Penalty Shot/Shootout
A penalty shot is a free, uncontested attempt on the goalie, awarded when a player is fouled on a breakaway. A shootout is the series of one-on-one attempts used to settle a game that is still tied after overtime.
Shot on Goal/Missed Shot/Blocked Shot
The three things that can happen to a shot attempt. A shot on goal reaches the net and is either saved or scores. A missed shot goes wide of the net or hits the post or crossbar without going in. A blocked shot is stopped by a defending skater before it reaches the net.
Shot Types
How a shot was taken. A wrist shot is a quick sweeping release, a snap shot is a shorter, faster motion, and a slap shot uses a full wind-up for the hardest shot. A backhand uses the back of the blade, a tip-in redirects a shot or pass on purpose, and a deflection is a shot that changes direction off a player or stick on its way to the net. A wrap-around starts from behind the net. A poke is a short stab at the puck with the stick, a bat knocks the puck out of the air, a between-the-legs shot is taken through the shooter's own legs, and a cradle is a lacrosse-style shot where the puck is carried on the blade and flipped at the net.
Slot
The area in the middle of the ice in front of the net, between the faceoff circles. It is where the best scoring chances come from, so most high-danger shots are taken from the slot.
Point Shot
A shot from a player at the blue line, far from the net. A single point shot is usually a low-quality chance, but it can be effective through screens, tips, and rebounds.
Breakaway
A skater gets past every defender and has only the goalie to beat, with a clear path to the net. It is one of the highest-quality chances in the game.
Rebound
A rebound happens when the puck strikes the goaltender (or occasionally the goalpost or crossbar) and bounces back out into play, rather than being caught or frozen by the goalie.
Odd-Man Rush
A rush where the attackers outnumber the defenders, such as a 2-on-1 or 3-on-2. They create dangerous chances because the defense can't cover everyone.
Screen
A player standing in front of the goalie to block their view of the puck, making it harder to make the save.
Strength State
The number of skaters each team has on the ice, (5v5, 5v4, 4v5, etc.).
Even Strength (ES)
Play with both teams skating the same number of skaters, most commonly 5v5.
Power Play (PP)
When a team has more skaters on the ice than its opponent because of a penalty (5v4 is the most common). Together with the penalty kill, it makes up special teams.
Penalty Kill (PK)
When a team has fewer skaters on the ice than its opponent because of a penalty (4v5 is the most common), and is trying to keep the other team from scoring until the penalty ends. Together with the power play, it makes up special teams.
Empty Net/Pulled Goalie
A net with no goalie in it, usually because a trailing team takes its goalie off the ice and deploys an extra skater.
On-the-Fly Change
A line change made while play is happening instead of at a stoppage.
Back-to-Back
A team plays on two days in a row, so its second game comes on less rest.
Advanced Hockey Terms (12)
Shot Danger Zones (HDC/MDC/LDC)
Shots are sorted into three zones by where they were taken, measured from the center of the goal. A high-danger chance (HDC) is a shot attempt within 29 feet and between the lines from the faceoff dots to two feet outside the goalposts. A medium-danger chance (MDC) is a shot attempt from 29 to 43 feet, between the same lines. A low-danger chance (LDC) is a shot attempt from anywhere else: beyond 43 feet, from a wide angle outside the lines, or from behind the goal line.
Royal Road
An imaginary line running the length of the ice through the center of both nets. A shot or pass that crosses it tends to be more dangerous, since it forces the goalie to move laterally.
Off Wing
A shot taken from the side of the ice opposite a player's shooting hand (like a left shot playing the right wing), which tends to open up a better shooting angle toward the net.
Rush Shot
Any shot attempt within four seconds of an event in the neutral or defensive zone, with no stoppage in play in between.
Shift
The time from when a player gets on the ice to when they get off the ice.
Stint
A period of time when all the same players stay on the ice, ending as soon as any one of them changes. A shift can span several stints.
Zone Entry/Zone Exit
A player carrying, passing, or dumping the puck into the offensive zone (entry) or out of the defensive zone (exit). A "controlled" entry/exit keeps possession of the puck, while a dump-in/dump-out gives it up in exchange for territory.
Score State
The goal differential at a given point in a game (tied, up one, down two, etc.), which strongly influences how teams play.
Score Effects
The tendency for teams to change their style of play based on score state (trailing teams tend to attack more, leading teams tend to play more defensively).
Deployment Context
How a player is used, as opposed to how well they play: the quality of their teammates and opponents (QoT and QoC) and how often their shifts start in the offensive zone.
Quality of Competition (QoC)
A measure of how strong the opposing players a skater faces are on average, relative to the rest of the league.
Quality of Teammates (QoT)
A measure of how strong a player's own teammates are on average, relative to the rest of the league.
Hockey Rules (15)
Offside
A stoppage called when an attacking player crosses the offensive blue line ahead of the puck. Play restarts with a faceoff in the neutral zone.
Icing
A stoppage called when a team shoots the puck from behind the center red line all the way past the opponent's goal line and no one touches it. Play restarts with a faceoff in the zone of the team that iced it, and that team can't change players. A team that is shorthanded is allowed to ice the puck.
Goaltender Interference
Contact with the goalie in or around their crease that stops them from making a save. If an attacking player interferes, the goal doesn't count and a minor penalty can be called. If a defender pushes an attacker into the goalie, it isn't interference.
Penalty
A rule violation that sends a player to the penalty box, so their team plays a skater short (a power play for the other team). How long they sit depends on the type of penalty: minor, double minor, major, misconduct, or match.
Minor Penalty
A 2-minute penalty for common infractions like tripping or hooking. The penalized team plays a skater short, and the penalty ends early if the other team scores on the power play.
Common Minor Penalties
The most frequently called minors are tripping, hooking, slashing, holding, interference, high-sticking, roughing, cross-checking, delay of game (like shooting the puck over the glass from your own zone), and too many men on the ice.
Double Minor
A 4-minute penalty served as two back-to-back minors, usually for high-sticking that draws blood. A power play goal ends the first minor, and the second minor starts right after.
Major Penalty
A 5-minute penalty for more serious infractions, such as fighting. It stays in effect for the full five minutes even if the other team scores, so the penalized team can give up more than one power play goal.
Fighting
Two players dropping their gloves and throwing punches. Each fighter gets a 5-minute major, which cancels out, so teams usually stay at even strength. The player who starts the fight (the instigator) also gets a minor and a 10-minute misconduct.
Misconduct/Game Misconduct
A misconduct is a 10-minute penalty for unsportsmanlike behavior that sends the player off but lets their team stay at full strength with a replacement. A game misconduct ejects the player for the rest of the game, and their team stays at full strength unless another penalty came with it.
Match Penalty
The most serious penalty, called when a player tries to injure an opponent. The player is ejected, their team plays shorthanded for five minutes (another player serves the time), and the league reviews the play for a suspension.
Delayed Penalty
When a penalty is called but the team that was fouled still has the puck, play continues until the penalized team touches it. The fouled team usually pulls its goalie for an extra attacker during that time, and if it scores before the whistle, the penalized player may not have to serve their minor.
Coincidental Penalties
Equal penalties called on both teams at the same time, such as two minors or two majors. Both players sit but neither team gets a power play, so teams play 4v4 for coincidental minors.
Coach's Challenge
A coach can ask for a video review of a goal for offside or goaltender interference. If the call is overturned, the goal is wiped out, and if it stands, the challenging team is given a minor penalty for delay of game.
Last Change
The home team gets the final line change after every stoppage, so it can choose its matchups after seeing who the visiting team sends out. It is one reason home teams do slightly better.
Basic Hockey Stats (28)
Games Played (GP)
The number of games a player appeared in or a team has played.
Goal
The puck completely crossing the goal line between the posts and under the crossbar. Each goal adds one to the team's score, and the team with more goals at the end of the game wins.
Assist
Credit given to up to two players who touched the puck just before a teammate scored. Their touches have to be consecutive, so no opposing player can touch the puck in between. The last passer gets the primary assist and the one before that gets the secondary assist. Not every goal has assists, and some have only one.
Point
A goal or an assist: a player's points are their goals plus their assists. Not to be confused with the standings points a team earns for winning.
Game-Winning Goal (GWG)
The goal that gives the winning team the lead it never gives up. It is the goal that puts the winner one ahead of the loser's final total, so in a 4-2 win it is the team's third goal. A shootout winner counts as the game-winning goal.
Power Play Goal (PPG)
A goal scored by the team with the extra skater while it is on the power play.
Shorthanded Goal (SHG)
A goal scored by the team that is down a skater, which is rare and usually comes off a turnover.
Shots (SOG)
The number of shots on goal a player or team takes, usually shown as a total or per game. It leaves out missed and blocked shots, so it is smaller than the total number of shot attempts.
Shooting Percentage (SH%)
The percentage of shots on goal that result in a goal. Calculated as goals divided by total shots on goal.
Goals For/Goals Against (GF/GA)
The goals a team scores (GF) and the goals it allows (GA), either over a season or while a player is on the ice.
Goal Differential
A team's goals scored minus its goals allowed, including goals awarded for shootout wins.
Plus-Minus
A raw count of the goals scored for minus the goals scored against while a player is on the ice, not counting goals scored while their team has the power play. Simple, but credits and blames a player for every goal regardless of who else was on the ice.
Time on Ice (TOI)
The amount of game time a player spends on the ice, reported in either total minutes or as a per-game average.
Hits
A body check that separates an opponent from the puck. Hits are counted by the arena's scorekeeper, so the totals vary a little from arena to arena.
Blocks
A shot attempt stopped by a defending skater before it reaches the net.
Giveaways/Takeaways
A giveaway is a turnover where a player loses the puck to the other team, and a takeaway is when a player steals it. Both are judged by the scorekeeper, so they are somewhat subjective.
Penalty Minutes (PIM)
The total minutes a player accumulates from penalties they take. A minor adds 2, a major adds 5, and a misconduct adds 10.
Penalties Drawn/Taken
Penalties taken are the ones a player is called for, and penalties drawn are the ones called against the other team because of them. Drawn minus taken is a player's net penalties.
Faceoff Win Percentage (FO%)
The percentage of faceoffs a player or team wins.
Power Play Percentage (PP%)
The share of a team's power plays that end in a goal.
Penalty Kill Percentage (PK%)
The share of the penalties a team kills off without allowing a power play goal.
Saves/Shots Against (SA)
Shots against are the shots on goal a goalie faces, and saves are the ones they stop, so saves equal shots against minus goals allowed.
Save Percentage (SV%)
The percentage of shots on goal a goalie stops. Calculated as saves divided by shots on goal.
Goals Against Average (GAA)
The goals a goalie allows per 60 minutes played.
Shutout (SO)
A game in which a goalie allows no goals for the entire game. If two goalies split a game, neither gets the shutout.
Record (W-L-OTL)
A team's results as wins, regulation losses, and overtime losses. Wins are worth two standings points, overtime losses one, and regulation losses none.
Points Percentage (P%)
The percentage of available standings points a team has earned (2 for a win, 1 for an overtime or shootout loss, 0 for a regulation loss). Calculated as points divided by two times games played.
Counting Stat
A stat that adds up over a season, like goals or WAR, so a player who plays more games has more chances to add to it. A rate stat, such as goals per game or per 60, is scaled by playing time instead.
Advanced Hockey Stats (26)
Per 60 (/60)
A stat scaled to what it would be over 60 minutes of play, which is one full game of ice time: the count times 60 divided by the minutes played. It compares players with different ice time, which per-game numbers don't.
Relative (Rel)
A stat compared with the team's own result when the player is off the ice (the team's rate with them on the ice minus its rate with them off).
Corsi (CF%)
The share of all shot attempts (shots on goal, missed shots, and blocked shots) a team or player accounts for while on the ice. A common proxy for puck possession.
Fenwick (FF%)
The share of unblocked shot attempts (shots on goal and missed shots) a team or player accounts for while on the ice. (Corsi, but without blocked shots).
Individual Shot Attempts (iCF/iFF)
A player's own shot attempts. iCF counts every attempt (goals, shots on goal, misses, and blocks) and iFF leaves out blocks.
Scoring Chances (SCF/SCA)
Shot attempts taken from areas likely to produce a goal, counted for (SCF) and against (SCA) while a player is on the ice.
On-Ice Shooting %/Save % (oiSH%/oiSV%)
A team or player's shooting and save percentages while they're on the ice, as opposed to just their own individual shots or saves. The two components that make up PDO.
PDO
The sum of a team or player's on-ice shooting percentage and save percentage. A PDO far from 100 often signals unsustainable puck luck rather than true talent.
Zone Start Percentage (OZS% or DZS%)
The percentage of a player's non-neutral-zone and non-on-the-fly shifts that begin with an offensive-zone or defensive-zone faceoff.
Primary Points
A player's goals plus primary (first) assists, excluding secondary assists.
Individual Point Percentage (IPP)
The share of a team's goals while a player is on the ice that the player earned a point on, either scoring or assisting.
Expected Goals (xG)
The probability that a given shot results in a goal, based on shot location, type, and situational context. See the xG model above.
Individual Expected Goals (ixG)
The sum of the xG of the shots one player took themselves. Comparing it to their actual goals gives their goals above expected.
Expected Goals Against (xGA)
The sum of expected goals value from shots taken against a team or while a player is on the ice.
Expected Goals For % (xGF%)
The share of the expected goals in a player's or team's ice time that go to their own side. Calculated as xGF divided by the sum of xGF and xGA. Above 50% means they create better chances than they allow. Similar to Corsi, but each shot is weighted by its quality.
Goals Above Expected (GAx)
A shooter's actual goals minus the xG of their own shots. A positive number means they scored more than an average shooter would have on the same shots.
Finishing
How a player's goals compare with the xG of their own shots (goals above expected). A positive number means they scored more than an average shooter would have on the same shots. In WAR it is taken above replacement, and it can't separate real shooting talent from shot quality the xG model can't see.
Goals Saved Above Expected (GSAx)
A goalie's actual goals allowed subtracted from the number of goals an average goalie would be expected to allow on the same shots, based on xG.
Goals Saved Above Average (GSAA)
How many goals a goalie saved compared with an average goalie who faced the same number of shots: the league-average save percentage times their shots against, minus their goals against. It is like GSAx but doesn't account for how dangerous the shots were.
Regularized Adjusted Plus-Minus (RAPM)
A ridge-regression-based method for isolating a player's on-ice impact from the effects of their teammates and competition. See the RAPM model above.
Replacement Level
The performance baseline WAR is measured against. The production expected from a readily available fringe player.
Goals Above Replacement (GAR)
A player's goals above what a replacement-level player would have produced in the same role, before converting to wins. WAR is GAR converted to wins.
Wins Above Replacement (WAR)
A single number expressing how many wins a player added over a season compared to a replacement-level player. See the WAR model above.
Elo Rating
A sequentially updating team-strength rating that shifts after every game based on the result and how expected it was. See Elo ratings above.
Simple Rating System (SRS)
A team-strength rating fit across an entire season at once by minimizing error between predicted and actual goal margins. See SRS above.
Pythagorean Exponent
The exponent k in the Pythagorean formula, which estimates a team's win percentage from goals scored and allowed (goals for to the power k, divided by goals for to the power k plus goals against to the power k). WAR uses it to convert goals into wins. See the WAR model above.
Data Science Terms (17)
Sample Size
The number of observations behind a number. Small samples are noisy: a player's shooting percentage over 20 shots says little.
Percentile/Percentile Rank
The share of the qualifying pool that a player ranks above. A player in the 90th percentile ranks above 90% of the pool.
Standard Deviation
A measure of how spread out values are around their average. In a bell-shaped distribution, about two-thirds of values fall within one standard deviation of the average.
Regression to the Mean
The tendency for extreme results, good or bad, to move back toward average the next time, because part of them was luck. A player who shoots far above their xG one season will usually shoot closer to normal the next.
Ridge Regression
A regression technique that shrinks coefficient estimates toward zero to reduce overfitting, especially useful when predictors (like individual players) are numerous and collinear.
Collinearity
When two inputs move together so closely that a model can't tell which one is responsible. Linemates who are almost always on the ice together are the classic hockey case.
Covariate
An extra input to a model that isn't the thing being measured but can affect the outcome, such as home ice or score state in RAPM. Including it adjusts for it, so players aren't credited or blamed for it.
Prior
The starting estimate that a new estimate is pulled toward before the data is considered. In RAPM, it is built from the player's rating last season.
Gradient Boosting
A machine learning technique that builds a strong model out of many small decision trees, each one trained to correct the errors of the trees before it. XGBoost is a popular implementation. A model that sorts each input into a category (such as goal or no goal) is called a classifier.
One-Hot Encoding
A way of turning a categorical value into numeric columns a model can use, with one column per possible category that's set to 1 for the matching category and 0 for every other.
Gain (Feature Importance)
How much a feature's splits improve a tree model, used to rank how important each feature is. It favors features with many distinct values, so it can overstate their effect.
In-Sample vs. Out-of-Sample
In-sample results are measured on data the model was trained on and flatter it; out-of-sample results are measured on data it never saw, and are the honest test.
Overfitting
When a model learns the quirks and noise of its training data instead of the real patterns, so it looks great on data it has seen and worse on new data.
ROC Curve (Receiver Operating Characteristic)
A plot of a classification model's true positive rate against its false positive rate across every possible decision threshold, used to visualize how well it separates two outcomes.
AUC (Area Under the Curve)
The area under the ROC curve, condensing it into a single number: a measure of how well a classification model separates positive and negative outcomes, where 0.5 is no better than random and 1.0 is perfect separation.
Log Loss
A score for how close a model's predicted probabilities are to what actually happened, punishing confident misses hard. Lower is better.
Calibration
Whether predicted probabilities mean what they say. A common check is total predicted divided by total actual, where 1.00 is perfect.