How to Debug Data Science Code

Think of everyone who has a talent you admire. Athletes, writers, anyone. If you were to ask each of them for the secret to their success, how many of them would be able to give the true answer? I’m not saying that they would deliberately lie. Rather, it’s just genuinely very hard to objectively assess oneself and turn natural implicit behaviors into explicit lessons that can be described to others.

Implicit lessons can be a barrier to people learning new skills: it’s much harder to learn something if their instructor doesn’t know it’s something they ought to teach. The best teachers are able to put themselves into the shoes of their students and convey the most important pieces of information.

One area of data science that is too often left implicit is troubleshooting. Everyone who writes code will get error messages. This is frustrating and can halt progress until solved. Yet most resources devoted to teaching new data scientists don’t discuss what to do, as if they’re expected to study enough to code everything correctly the first time and never encounter an unexpected error. You can find articles about common mistakes that data scientists make, but what about when you inevitably make an uncommon one? There are very few resources around how to debug broken code. (This one is quite nice, and these two are worth a read as well.) 

That’s what I’m hoping to partially remedy with this article. It’s far from the single canonical process for debugging, but I hope that it helps people get unstuck while they learn. The key points I want to convey are:

  • Every data scientist hits an error messages regularly, and doing so as a new programmer is not a sign of failure
  • Isolate the issue by finding the smallest piece of code that creates the problem
  • The exact language of an error message can be extremely helpful, even if it doesn’t make sense
  • The internet is (only in this particular instance) your friend, and there are particular resources that are particularly helpful for solving problems

Continue reading

Quantifying the Value of an NHL Timeout using Survival Analysis: Part 1

I’d like to thank Luke Benz, my mentor via the Hockey Graphs Mentorship Program, for all of his help in developing this project.

Introduction

Hockey, by nature, is a fast-paced sport that can be difficult to represent by discrete situations. While most other professional sports can be viewed as combinations of distinct in-game events – at-bats in baseball, plays and series in football, and even possessions in basketball – hockey is extremely fluid, with a constantly changing game state. This difference in game flow means that there are far fewer opportunities for a hockey coach to make any decisions based on distinct game states. While, for example, a football coach has several opportunities per game to decide whether or not to attempt a fourth-down conversion, a hockey coach has very few chances to make any comparable choice that can affect the outcome of the game. However, there are a few tools available to a hockey coach that can be researched so as to optimize their effectiveness in helping a team to win a game.

The most-researched of these decisions (thus far) for an NHL coach is when to pull the goalie in an endgame situation. There have been several papers published regarding the optimal time to pull the goalie, such as these two by Beaudoin and Swartz in 2010 and by Brown and Asness in 2018. (For even more great work on goalie pull times, you can check out Meghan Hall’s talk from the 2019 Seattle Hockey Analytics Conference and her Tableau dashboard, as well as the Goalie Pull Twitter Bot created by Rob Vollman and MoneyPuck.com.) All of this prior research has found that NHL teams should pull their goalies much sooner than conventional wisdom suggests, as teams are much more likely to score to tie the game if they pull their goalie earlier rather than later.

However, beyond pulling the goalie, there are still a few more tools at a coach’s disposal. Teams are allowed to challenge goals for certain rule infractions, use a 30-second timeout during a stoppage in play, or switch goalies if the starter is having a bad game, in addition to personnel decisions regarding line combinations or matching up players against the other team. This article focuses on timeout usage, but I plan to explore the other tools in future work.

Continue reading

Using Sequences for Analysis: Expected Goals Contribution and more

In a previous article, I presented a way to cut and slice a hockey game into Sequences. A Sequence extends from the moment a team gets control of the puck and starts moving forward, to the moment the team loses it for good. The objective was to measure the importance of every event happening between the beginning of a Sequence and its end, from a zone exit to any shot attempts, to a zone entry or any high-danger passes in between. If a Sequence includes one or several shot attempts, its value is the sum of the Expected Goals of all those attempts.

The natural follow-up was the creation of an Expected Goals Contribution metric for players.

The thinking behind it was to answer one of the two main questions we face in the daily use of analytics with coaches: What is the real contribution of each player? Overall, there are the well-known GAR or WAR type of metrics, but these are beyond the comprehension of many staffs as they are not tangible enough for a daily use.

Now, if we use Sequences where the team has possession of the puck, it means Expected Goals Contribution would only look at the offensive side of the game. Still, instead of looking separately at transition or shooting stats to evaluate a player, the objective is to sum all offensive efforts into one metric, weighting those efforts (zone exit, entry, etc.) according to their contribution to the Sequence. It also makes playmaking more apparent statistically.

In other words, it means sharing the total value of the Sequence (in terms of Expected Goals), between the players responsible. This is what we called Expected Goals Contribution.

Continue reading

Introducing Offensive Sequences and The Hockey Decision Tree

If you ever work for a hockey team as an analyst, you could be facing two very recurrent questions from the coaching staff. The first one is very practical: How can analytics help us work better and faster? The second one is: What is the real contribution of each player? Meaning beyond the usual on-ice “possession” stats like Corsi or Expected Goals and individual production metrics such as shots taken, scoring chances, expected goals created, zone exits, entries, or even high-danger passes (passes that end or go through the slot). But those events were not yet statistically linked to each other. Finding a way to provide answers to both questions was my goal for the last few months, and the solution was: I needed to split the game in “Sequences”.

Video coaches often break down game tape to highlight certain plays, such as a rush-based attack or a zone exit under pressure. I wanted to do the same and divide a game in as many parts as necessary, or “Sequences”. Roughly, every time the puck changes possession between teams, a new Sequence” begins. That’s about 250 Sequences per game.

Looking at this from the point of view of the team that owns the puck, offensive Sequences extend from the moment a team gets control of the puck and starts moving forward, to the moment she loses it for good, and it must include a shot attempt in the process to have a positive value. How does this work? Let’s say a player gets the puck back in your defensive zone, you try a zone exit but fail. Sequence starts over, there can only be one exit recorded in the Sequence. So he tries another zone exit and succeed, gets into the offensive zone, the team records a couple of shot attempts, loses the puck and if the other teams gets enough control of it to try a zone exit, it means the end of the Sequence.

How does this help? Well, the basic principle is to see the total value of a Sequence. We’re use Expected Goals as our measure of “value”. To do that, we add the Expected Goals of the shot attempts in the Sequence. For example, a Sequence with two shot attempts:

  • A high danger shot: 0.23 Expected Goals
  • A shot from the blue line: 0.01 Expected Goals
  • Total Sequence value: 0.23 + 0.01 = 0.24 Expected Goals

Sequences

Continue reading

An Introduction to R With Hockey Data

I have written a couple articles over the past few months on using R with hockey data (see here and here), but both of those articles were focused on intermediate techniques and presumed beginner knowledge of R. In contrast, this article is for the complete beginner. We’ll go through the steps of downloading and setting up R and then, with the use of a sample hockey data set, learn the very basics of R for exploring and visualizing data.

One of the wonderful things about using R is that it’s a flexible, growing language, meaning that there are often many different ways to get to the same, correct result. The examples below are meant to be a gentle introduction to different parts of R, but please know that this really only scratches the surface of what’s available.

The code used for this tutorial (which also includes more detail and more examples) is available on our Github here.

Downloading R and Getting Set Up

Continue reading

Lateral Puck Movement in the NZ

Research shows that lateral/”east-west” puck movement in the offensive zone is beneficial to increasing one’s odds of scoring. But I have now heard from people in various positions within the hockey industry on why it might also be useful to generate east-west puck movement in the neutral zone. The theories – focused on lateral passing, lane changes and stretch passes, respectively – all boiled down to one point: When you rush the puck up ice, the defending team will focus on that side, leaving the other side of the ice somewhat more open, so there might be open ice to exploit.

Continue reading

Passing clusters: A Framework to Evaluate a Team’s Breakout

Quick breakouts – trying to move the puck out of your zone right after gaining possession – make up roughly 38% of possessions and account for 22% of all shots and 22.4% of Expected Goals (at least according to my possession and xG definitions). Therefore, understanding what does and does not work when breaking out the puck against present forecheckers is important. There is evidence that passes from the defensive half boards by wingers inside produce more offense than those straight up ice. But the puck is more often recovered elsewhere, so these passes by wingers aren’t the first pass in a possession and are therefore presumably influenced by the previous play. It should be interesting to find out how the inclusion of the pass(es) that came before affects this conclusion.

Continue reading

Exploratory Data Analysis Using Tidyverse

This post assumes beginner knowledge of R.

Welcome to the second article in our series on basic data cleaning and data manipulation! In this article, we’re going to use play-by-play data from two NHL games and answer two questions:

  • which power play unit generated the best shot rate in each game?
  • which defenseman played the most 5v5 minutes in each game?

In the process of doing so, we’ll cover several topics of basic data manipulation in the tidyverse, including using functions, creating joins, grouping and summarizing data, and working with string data.

Continue reading

Combining Manually-Tracked Data with Play-by-Play Data

This post assumes beginner knowledge of R.

If you’ve ever analyzed hockey data, then you’re probably familiar with the NHL’s Real Time Scoring System, which produces what’s more commonly known as play-by-play data. These data are publicly available and allow us to see every event recorded by the NHL in a given game. Shown below are selected details about the first 10 events from two games on February 18, 2019: Tampa Bay at Columbus and Vegas at Colorado.

Continue reading

The Importance of Pressure for a Successful Forecheck

Most of my posts so far have talked about zone exits from the perspective of the team trying to breakout out of their defensive zone. Now, let’s flip the script and discuss the team on the forecheck. This team does not have possession of the puck, but they are in their offensive zone, which is an advantage. So, how can they regain control?

Continue reading