Alex Diaz


Data Mining the Play-By-Play

At long last, my thesis is complete:

Data Mining the Play-By-Play

Overall summary:

  • Linear regression models demonstrating:
    • Full-strength tied Corsi% as a useful predictor for win percentage and goal percentage (“Full-strength tied Corsi” refers to a team’s shot attempts when the game is tied and with five skaters vs five skaters)
    • The surprisingly distinct contributions of powerplay and the penalty kill
  • Pretty graphs! I mean, “data visualization”.
  • A demonstration of how association rule learning and interest measures can be used to evaluate players and player combinations

Less technical summary:

  • If your team regularly has more shot attempts than opponents while the game is tied and while at full strength, that’s good
  • The powerplay and penalty kill don’t seem to overlap much and have roughly equal value in explaining win percentage
  • Pretty graphs! I mean, “data visualization”.
  • Ever wondered who really carries the second line? A machine learning technique called “association rule learning” can help tease out the details to see which players tend to contribute more (and which ones should be bumped from the second line to the first).

Measuring Corsi For and Against with Association Rules

I’ve previously discussed potential applications of association rules learning in the second half of a post from last year. The arulesViz package for R is broken for me right now, so I won’t be able to recreate the graph at the bottom without considerable effort. For now, we’ll use graphics I’ve generated on my own. While I’ve created some interesting results, I would like to strongly emphasize that this is essentially a prototype, so going forward one must remember the assumptions being made and the contexts of the statistics being analyzed.

Last weekend I presented some of my findings at Ottawa Hockey Analytics, and what I’m writing about today is largely the same. My data comes entirely from the NHL’s Play By Play (PBP) and Player TOI tables. For this work it suffices to use PBP data on its own; I find Corsi events reliable at correctly recording the players present on the ice. However, I originally intended this dataset to have other purposes, so I stripped the PBP of its player information and added it using TOI tables. There may be some errors as a consequence (e.g if shifts were not properly recorded). I organized the data into binary columns for every event and player. If a player is on the ice during an event, he is marked as a 1; those off the ice are marked as 0s. Events are recorded similarly. This is a sample of what I end up with:

Transaction dataset example (201314 LA)


In association rule learning, a binary dataset like this one can be thought of as a big list of itemsets. For our purposes, our items are players and events, and we’d like to measure how often they appear together. Our motivation is to highlight players’ presences during “good” or “bad” events; in this example, we’ll use Corsi For and Corsi Against, respectively. This technique is not limited to Corsi events — in fact, I’d like to expand it to many other events — but for now they’re the easiest to record and they have predictive value.

Before showing the results, I’ll provide a quick primer:

  • An itemset X is a a collection of items. It’s basically a row in our dataset. In the screenshot, our first itemset {ANZE_KOPITAR, JONATHAN_QUICK, DWIGHT_KING, CORSI_FOR}. Eventually I removed the goaltenders – I believe they have analytic value, but for now I’m keeping it simple. Well, simple-ish.
  • A rule X => Y is an implication between itemsets X and Y, written as X => Y.
    • Rules are split into the left-hand side (LHS, or “antecedent”) and right-hand side (RHS, or “consequent”)
    • Here, we only consider players on the LHS and events on the RHS
    • For example, our rules will appear as {ANZE_KOPITAR, DWIGHT_KING} => {CORSI_FOR}

The following metrics are interest measures. As the name implies, they are meant to highlight interesting relationships between variables.

  • The support of an itemset X is defined as the proportion of the database in which X appears
    • For us, a higher support means that the combination of players and events happens more often. Players with more ice time will necessarily have higher support simply because they’re on the ice when more things happen
  • The confidence of a rule X => Y is the ratio of the support for X and Y to the support of X alone.
    • CONF(X => Y) = SUPP(X, Y)/SUPP(X)
  • The lift of a rule X => Y is the ratio of the support for X and Y to the product of the supports of X and Y individually
    • LIFT(X => Y) = SUPP(X, Y)/[SUPP(X)*SUPP(Y)]
  • The difference of confidence of a rule X => Y is the difference of confidence between X => Y and ¬X => Y
    • DOC(X => Y) = CONF(X => Y) – CONF(¬X => Y)

Interest measures can be interpreted in a probability context. If we restrict our sample space to all Corsi events over an entire season, we are measuring the probability that Corsi events occur with respect to the players on the ice. Letting X = {Players on ice} and Y = {Event}, we get:

  • SUPP(X, Y) = P(X, Y) = Probability that a Corsi event and a particular combination of players occurs
  • CONF(X => Y) = P(X, Y)/P(X) = P(Y|X) = Probability that Y occurs, given that player combination X is on the ice
  • LIFT(X => Y) =P(X, Y)/[P(X)P(Y)]. Statistical independence between events X and Y is defined as P(X)P(Y) = P(X, Y), so the lift’s closeness to 1 could be used to indicate independence.
  • DOC(X => Y) = P(Y|X) – P(Y|¬X) = Probability that an event occurs given player combination X is on the ice – Probability that an event occurs given player combination X is not on the ice
    • Note that X is the entire combination of players. If X = {KOPITAR, KING}, then ¬X = {All sets without both of KOPITAR, KING}. Thus, ¬X includes all events where: (1) Kopitar is on the ice but King is not; (2) King is on the ice but Kopitar is not; and (3) Neither Kopitar nor King are on the ice

With all that in mind, here is a description of what I’m working with:

  • The dataset contains all even-strength 5v5 tied Corsi events from 2013-14
  • All Corsi events are treated equally. I haven’t made adjustments for quality of competition,
  • We are limited to how often player-event combinations occur within a team. There are two sides to this: the first is how often a situation exists; the second is how often a player is in the situation to begin with
  • All analysis was done within teams. Comparing between teams may not be useful.

I believe the best application of this analysis is to compare how players are faring in their current roles on their teams. We can highlight player chemistry, their performances relative to teammates in the same position, and (hopefully) hidden potential. Over time, we may also be able to use multiple seasons to see how a player has performed with different teammates and team strengths.

I’ve generated six graphs for each team:

  1. All individual performances
  2. Defensemen, as individuals
  3. Defensemen, as pairs
  4. Forwards, as individuals
  5. Forwards, as pairs
  6. Forwards, as trios

Support for Corsi Against is on the left; support for Corsi For is on the right. More green means that the Difference of Confidence is higher for that statistic, implying that the event is more likely give that the specific player combination is on the ice. More purple is the opposite (an event is relatively less likely given that player combination). Rules with fewer than 25 occurrences were dropped, so if a column is missing on one side it’s probably because it missed that threshold.

Important note: The initial batch of images I uploaded on Feb 13th had some errors based on when players were on the ice. I have since fixed the error in my code but I won’t be immediately redoing the analysis for each team. Here is a direct link to the album.

Examples and discussion

Toronto Maple Leafs, 2013-14:

  • Possession numbers are terrible across the board
  • Phaneuf is on the ice for about a fifth of even-strength tied shot attempts against with a very strong difference of confidence against him
  • Jake Gardiner and Morgan Rielly have the strongest indication in favour of possession among defensive pairings
  • Forward possession is driven by Kessel and Van Riemsdyk. Looking at forward pairs, it suggests the Kessel and JVR have stronger chemistry than either combining with Bozak
    • Kadri’s support for Corsi For/Against are better when paired with either winger, and with stronger difference of confidence, suggesting he could be a better first line centre
  • Lupul and McClement had awful years

Los Angeles Kings, 2013-14:

  • The top pairing of Doughty-Muzzin is strong. The difference of confidence at an individual level is much higher in Muzzin’s favour, though he and Doughty don’t seem to have shared defence partners at any point
  • Anze Kopitar drives play strongly
  • Tyler Toffoli had a strong year with a variety of linemates

Who pays the iron price? Goalpost and crossbar hits since 2009-2010

PING! “AWWWwwwwww…”, the crowd rumbles. Depending on which side took the shot, the arena is either flooded with relief or tearing their hair out at a missed opportunity.

Is your team cursed? Do they dance with Lady Luck? Are you suspicious that the nets are ever-so-slightly smaller in some arenas? I have no idea, but luckily the NHL tracks posts and crossbars as missed shots in their play by play pages. As usual, there is some grumbling about the accuracy of their numbers, but for our purposes we’ll take them at face value. The graphs below measure the ratio of goal posts and crossbars hit to shots on goal – that is, shots that hit the net. This is a rough measurement of which NHL teams hit the post or crossbar most often.

Offensive posts

IronFor2009-10 to 2013-14

Over the last five full seasons, the Sabres and the Avalanche were relatively lucky, respectively hitting iron just 14.7 and 14.8 times for every 1000 shots on goal. The Senators fared the worst in the league with 22.3 bouncing away from the net. The league ratio (highlighted in red) was 18.6 post/crossbar hits per thousand shots.

Below we have each season individually.

The worst ratios come from the lockout season, which could be a result of sample size from a shortened season. In 2012-2013, there were 19.7 shots off the iron for every 1000 on goal; the Canucks managed to ring a whopping 31.1 per 1000. Conversely, the 2009-2010 Sabres escaped with just 10.2 for every 1000.

Defensive posts

IronAgainst2009-10 to 2013-14

As before, the league saw 18.6 posts or crossbars for every 1000 shots. The Bruins got the least help from their nets, which rang only 14.7 times per 1000 shots, while the Jets (with their somewhat truncated sample) heard 21.8 per 1000.

Again, each season presented individually:

The lockout season once more gives us the highest number: the 2012-2013 Winnipeg Jets saw 26.7 shots hit iron for every 1000 that hit the net. The 2012-2013 Penguins got no help from their nets, seeing a paltry 8.6 posts or crossbars for every 1000 shots.


It’s possible that measuring defensive goalposts has different interpretations from offensive goalposts. When we look at offensive statistics, players are facing different goaltenders and teams regularly, whereas defensive statistics are more or less the same goalies. It could be that certain goalies are more likely to catch pucks that would normally hit iron, or that they (or their defensemen) force players to miss the net entirely because of their positioning. Whether this has a measurable outcome on a game is anyone’s guess. If the numbers are accurate and hitting iron turns out to be mostly luck, then some teams face a swing of a dozen or more goals each year, balancing their fates on a half-inch bounce in the right direction. Hey, sometimes that’s all you need.

Measuring the value of Crosby, Getzlaf, and Giroux to their teams

Last week, the Hart Memorial Trophy candidates were announced. According to the infallible internet, it’s likely that Crosby will win — but let’s figure out if that’s true. To get the obvious stats out of the way, Crosby (36G, 68A, 80GP), Getzlaf (31G, 56A, 77GP), and Giroux(28G, 58A, 82GP) finished first, second, and third in scoring this year, with points-per-games of 1.30, 1.13, and 1.05, respectively. Pittsburgh, Anaheim, and Philadelphia finished with 242, 263, and 233 goals, respectively. Since the Hart looks at a player’s value to his team, it makes sense to look at his contributions to the team’s overall scoring.

Pie charts are terrible.

Candidate’s points (in teal) as a proportion of a team’s overall goals.

Looking at points alone, Crosby has a pretty huge head start over the other two. Now, the Hart (allegedly) isn’t the Art Ross 2.0, so it makes sense for us to look at possession statistics and the some frequencies from association rule mining.

Team Strength Candidate Corsi % Fenwick %
Pittsburgh All On 0.6036322 0.6095969
Pittsburgh All Off 0.4225558 0.4267751
Anaheim All On 0.5423348 0.5500000
Anaheim All Off 0.4812510 0.4914966
Philadelphia All On 0.5998837 0.5955325
Philadelphia All Off 0.4552777 0.4539683
Pittsburgh Even On 0.5308595 0.5372152
Pittsburgh Even Off 0.4638907 0.4685562
Anaheim Even On 0.5193694 0.5249392
Anaheim Even Off 0.4928212 0.4995057
Philadelphia Even On 0.5437117 0.5356383
Philadelphia Even Off 0.4811052 0.4763085

You may have noticed that Crosby and Giroux have a larger impact on the ice for their team than Getzlaf. These differences become much clearer when they’re visualized.

Fenwick strength status

At this point it becomes clear that if there’s any competition, it’s between Crosby and Giroux. While all of the players improve their teams’ performances, it’s obvious that Getzlaf’s relative contribution is not as strong as either of the other two.

Looking deeper, the Fenwick percentage at even-strength tilts the odds further towards Crosby and quite a bit farther away from Getzlaf. The next combination of graphs compares the game-by-game Fenwick.

Hart multiplot even

Blue and red lines represent season averages with and without the player on the ice, respectively. Black lines are the team average.

Two things to notice here: (1) Pittsburgh’s possession stats with Crosby are higher than Philadelphia’s with Giroux; and (2) Pittsburgh possession stats without Crosby are lower than Philadelphia’s without Giroux. This is especially evident when you look at the gaps between points — Giroux is very good, but Crosby absolutely lifts his team. This caught me a bit off guard, since until I wrote this post I hadn’t noticed that Pittsburgh finished the regular season with Corsi and Fenwick percentages below 0.500.

When we look at association rules, we the same story being told, albeit in a different manner.

Rank Player Event Support Confidence
1 Any Shot for 0.155 0.155
2 Any Shot against 0.149 0.149
3 Any Hit for 0.137 0.137
4 Any Hit against 0.133 0.133
5 Any Block for 0.075 0.075
6 Sidney Crosby Shot for 0.073 0.201
7 Any Block against 0.069 0.069
8 Any They miss 0.062 0.062
9 Chris Kunitz Shot for 0.062 0.201
10 Matt Niskanen Shot for 0.061 0.178
Rank Player Event Support Confidence
1 Any Shot against 0.150 0.150
2 Any Shot for 0.149 0.149
3 Any Hit for 0.130 0.130
4 Any Hit against 0.125 0.125
5 Any Block against 0.077 0.077
6 Any Block for 0.072 0.072
7 Claude Giroux Shot for 0.064 0.188
8 Braydon Coburn Shot against 0.061 0.175
9 Any We miss 0.060 0.060
10 Jakub Voracek Shot for 0.057 0.200

The main takeaway from Crosby’s table is how high up his generation of offense is — about 7.3% of all active events in the game are a Pittsburgh shot on goal while he’s on the ice, and when he’s on the ice, there’s 20.1% chance that the active event will be a Pittsburgh shot hitting the net. In fact, Crosby was on the ice for a Pittsburgh shot on goal more often than any player was on the ice for an opponent having their shot blocked. Crosby’s linemate Kunitz is only on for 6.4% of Pittsburgh’s shots, so that suggests that Crosby is doing quite a bit on his own. (As a note, you’ll see similar stuff for players like Erik Karlsson, who tend to be head and shoulders above their teammates, even if their teammates are very skilled on their own.)

What’s the conclusion here? In terms of relative contributions to their teams, this is a race between Crosby and Giroux — one that Crosby will very probably win.

Hello world!

Perpetually under construction.