154,624: NHL shots fit. 16,449: PWHL shots fit. 6: coefficients reliably differ. 2: features PWHL feed doesn't label Public xG models were built on NHL feeds. When they travel into other leagues, their coefficients travel with them, and the recalibration step that should happen often doesn't. This post refits a simplified version of that recipe on both leagues so we can see which coefficients survive the trip and which don't. It's simplified because the feature set is twelve columns: no pre-shot puck movement, no screen/traffic, no handedness. Our coefficients won't match Moneypuck's or Evolving-Hockey's even on NHL data. The point is cross-league difference , not absolute calibration against a production model. Two complete NHL regular seasons (2023-24 and 2024-25) on one side, every PWHL shot in our database on the other. Same twelve features, same sklearn solver, same L2 strength, same five-fold held-out evaluation, a 200-sample bootstrap for 95% confidence intervals on every coefficient. Distances are in feet in both fits. HockeyTech's PWHL coordinate grid is converted to real rink dimensions before any feature extraction, so the two coefficient sets live on a common scale. The coefficient chart, with error bars Point estimates without uncertainty make noise look like a finding. The chart below is the whole fit, both leagues, with 95% bootstrap intervals on every bar. Non-overlapping intervals mean the data is saying something. Overlapping ones mean it isn't, though with only 16,000 PWHL shots against 155,000 NHL shots, the PWHL intervals are roughly four to five times wider by sample size alone. "Overlap" here often means "not enough PWHL data to tell," not "same effect". 6 coefficients come out reliably different across the two leagues. The intervals don't overlap on distance, angle, rebound, tip, snap, and empty-net. The rest (slap, backhand, power-play premium) lands inside each other's interval, and in most cases this is a sample-size question as much as a sameness question. Empty net. NHL coefficient: +12.4 (CI [+12.1, +12.7]). PWHL coefficient: +6.4 (CI [+6.1, +6.7]). Both leagues convert empty-net attempts at 100% (NHL: 971 shots, all goals; PWHL: 86 shots, all goals), so both coefficients are just picking up 'this feature means goal.' The NHL coefficient is larger because the NHL sample is ~10× bigger, so L2 regularization shrinks the PWHL estimate harder toward zero. This is the cleanest example of what regularization does to rare-event features with small samples, and is worth mentioning because the same dynamic is at work on tip, deflection, and wrap-around in the PWHL fit. Distance and angle are steeper in the NHL NHL distance coefficient: -0.057 log-odds per foot . PWHL: -0.046 . Goal probability falls off about 25% faster with distance in the NHL than in the PWHL. Angle matters about twice as much: NHL -0.016 per degree, PWHL -0.008. Neither pair of intervals overlaps. In plain terms: a shot from a bad angle is penalised harder in the NHL than in the PWHL, and every additional foot of distance eats a bigger chunk of probability. One cross-league baseline worth noting before the coordinate caveat: the intercepts . NHL -0.17, PWHL -1.31. These are the models' implied probabilities for a straight-on, zero-distance, zero-angle wrist shot. It's not a realistic situation, but it's the cleanest single-number summary of the two fits' offsets. The ~1.1 log-odds gap is larger than the league conversion-rate gap alone (10.6% vs 8.3%) explains, which means the other coefficients (steeper distance decay, smaller angle penalty) are compensating in the opposite direction. The intercept is doing some of the work of the distance coefficient and vice versa; don't read either one in isolation. One caveat on distance worth flagging before anyone squints at the curve. HockeyTech's PWHL coordinate grid places the goal marker at x=50, which works out to ~16.7 ft from the end boards on our feet-based conversion; a regulation NHL goal line is 11 ft from the end boards. If HockeyTech's grid is a faithful drawing of a regulation rink (goals at their real positions), our conversion is fine. If it's a stylised rink with the goal marker placed where HockeyTech decided, then PWHL "distances" run ~5-6 ft longer than NHL distances at the same real-rink location, and some of the NHL-is-steeper gap is a coordinate-system convention rather than a shooting-behaviour difference. The real answer is probably a mix, and we can't cleanly separate the two from the public feed alone. Even after the coordinate caveat, a team importing an NHL-fit xG model into the PWHL without recalibrating distance should expect every in-slot chance to be over-credited and every point shot to be under-credited. The net effect on any one player or team depends on their shot distribution. Rebounds: the cross-league oddity The rebound coefficient is where the two fits diverge most. NHL fit: -0.28 (CI -0.35 to -0.22). PWHL fit: +0.83 (CI +0.63 to +1.00). The intervals are on opposite sides of zero. Treat this one carefully. Public NHL xG models (Moneypuck, Evolving-Hockey and most open-source reproductions) report a positive rebound premium. Our negative NHL coefficient is a consequence of a different definition. We use "same team, within three seconds, any coordinate"; published models typically add a distance or zone constraint and a shorter window, so their "rebound" captures legitimate second-chance looks while ours picks up scrambles and broken plays as well. Our distance coefficient then absorbs most of the goal-probability lift that rebounds really do produce, leaving a small negative residual for the rebound flag itself. The PWHL fit, using the exact same definition, gets a large positive rebound coefficient. So the finding is not "rebounds matter in the PWHL and not in the NHL." The finding is: with a single shared rebound definition, the coefficient moves from slightly negative in the NHL to strongly positive in the PWHL. Whether that reflects goaltending (PWHL rebounds aren't absorbed the way NHL rebounds are), a labelling difference in how shots within three seconds get flagged across the two feeds, or some combination, we can't separate with one fit. But a team importing an NHL rebound coefficient into a PWHL model would under-credit rebound goals by a lot. Shot types: mostly a draw Most shot-type coefficients don't reliably differ between the leagues. The PWHL slap coefficient (+0.48) sits inside the NHL slap coefficient's interval. Backhand overlaps. Power play overlaps. The PWHL slab of the data is thin, with only 744 slap attempts, 630 tips, and 1,031 backhands. The intervals are wide for a reason. The two shot-type coefficients that do reliably differ are tip and snap. NHL tips come in at -0.47: controlling for location, a tip attempt scores less than a wrist shot from the same spot, which makes sense if the NHL tip label captures a lot of grazes that barely redirect. The PWHL tip coefficient is +0.003, with an interval that straddles zero (too few tips to estimate). Snap shots show the same asymmetry: a clear NHL premium, no signal we can pull out of the PWHL data. Raw tip conversion rates are similar in both leagues (NHL 15%, PWHL 13%), so the small PWHL tip coefficient isn't saying tips don't score. It's saying the distance coefficient (tips cluster within 15 ft of net) absorbs almost all of the lift, and there's no residual premium the tip dummy can explain. Both models calibrate on their own data Held-out, not in-sample. Predictions for this plot come from sklearn's cross_val_predict . Every shot's probability comes from a fold where that shot wasn't in training. Then we bin by predicted probability decile and check the actual conversion rate inside each bin. Held-out log-loss lift versus a null (league-base-rate) model: 14.9% for the NHL fit, 12.1% for the PWHL fit . The NHL model has more lift, partly because the NHL corpus is about ten times larger (coefficients on rare features are actually estimable), and partly because the NHL feed labels more of them. What this means in practice Recalibrate distance and angle before using an NHL-derived xG in the PWHL. The p(goal | distance) curve is genuinely different between the two leagues, even after accounting for the HockeyTech coordinate convention. This is the part that will bias every downstream number.. Rebound coefficients don't travel between leagues under a shared definition. Whichever league's coefficient you import, you're importing the wrong one for the other league, and the direction of the error depends on how rebound is defined.. Don't over-read shot-type differences. With 744 slap attempts and 630 tips, most of the PWHL shot-type coefficients are too noisy to distinguish from the NHL values. The exceptions (tip, snap) differ partly because they're reliably estimated on the NHL side and poorly on the PWHL side, not because the leagues clearly differ.. The biggest PWHL xG improvement isn't a better fitter. It's richer labels. Deflection, wrap-around, and penalty-shot information isn't in the public feed at all; empty-net lives on a different event type than shots; 31% of PWHL shots carry a generic default label with no type information. The ceiling on this analysis is set by the label coverage, not the math. Methodology & caveats NHL data : every regular-season game from 2023-24 and 2024-25, pulled from api-web.nhle.com/v1/gamecenter/{id}/play-by-play . 154,624 shot-on-goal and goal events with coordinates. Missed-shot and blocked-shot events are excluded because their coordinates are unreliable for xG.. PWHL data : 16,449 shot events with coordinates from the PWHL's public HockeyTech feed, covering current and prior seasons. Note that the corpus is season-imbalanced: the newer season carries more games than the older one, so any implicit league-year trend lands in the intercept. 31% of PWHL shots carry a generic default shot-type label. The NHL feed, by comparison, labels ~99.98% of shots (only 38 out of 154,624 have a blank type). That label-coverage gap widens every shot-type dummy's confidence interval on the PWHL side.. Coordinate conversion : HockeyTech uses a 600×300 pixel grid with goal markers at x=50 / x=550. We convert x-coordinates at 200 ft / 600 units and y-coordinates at 85 ft / 300 units before computing distance and angle. HockeyTech's goal marker sits at ~16.7 ft from the end boards after this conversion; a regulation rink puts the goal line at 11 ft. We treat the marker as the goal, which is correct if HockeyTech's grid is a faithful drawing of a real rink and introduces a small systematic offset otherwise.. Feature set : distance-to-goal, angle, same-team rebound within 3 s, empty net (looked up from the companion event_type=goal row on the PWHL side; from situationCode on the NHL side), penalty shot (feature defined but not present in the PWHL feed), power play, plus six shot-type dummies (tip, deflection, snap, slap, backhand, wrap-around). Baseline is an even-strength wrist shot at zero angle.. Fitter : sklearn LogisticRegression(C=1, solver="lbfgs") on both corpora. Identical hyperparameters. 200-resample bootstrap for coefficient CIs. Five-fold cross_val_predict for held-out probabilities and the calibration plot.. What's still hand-waved : pre-shot puck movement (carries, passes, rebound chains past the 3 s window), shooter handedness, time since last event, score state, traffic/screen. A richer model would include these. This post uses a simplified version of the public-xG recipe. The rebound feature in particular is broader than what Moneypuck or Evolving-Hockey use (they add distance/zone constraints); our coefficients therefore differ from theirs even on NHL data.. Reproducibility : the fit artifact (coefficients, CIs, held-out predictions) is written to src/app/notebook/league_xg_fits.json and its .npz sidecar. The NHL shot cache lives under data/cache/nhl/pbp/ . Every number in this post is regenerated from scratch on each static build. Corrections, methodological critiques, or a better feature set to try are all welcome.