A text-focused feed — short essays and notes.
2026-02-09
Unlike the lineups produced in my last post on Olympic lineups with announced rosters, which will eventually have a point of comparison, these hypothetical Russian lines will remain hypothetical. Using MoneyPuck data from both the 2024 and 2025 seasons, I've applied the same optimization methods (linear programming and greedy) to available Russian NHL players[^1].
2026-02-01
Using the announced Olympic rosters, we can apply our GNN model to the players who will actually compete in Milan-Cortina. Unlike the previous Olympic roster post, where we considered all eligible NHL players, here we're constrained by the national team rosters.
2026-01-31
Throughout this series, we have explored how players interact within lines and teams. We’ve seen how to optimize a single roster and how to predict performance for unseen combinations. Here, we are inverting the logic: instead of asking how to build a team around players, we are asking which individual players provide the most value to any line they join.
2026-01-31
In my previous post, we looked at all possible combinations of lines and pairings on a team's roster. But, where this is most interesting, is looking at combinations across teams. Typically this would be hamstrung by a lack of data; there's limited data on how players from different teams would play together. With the Olympics approaching, this presents a fascinating challenge. Searching the full pool of eligible players produces hundreds of thousands of potential combinations.
2026-01-31
Finding optimal combinations is, as it sounds, a combinatorial problem. A roster of 13 forwards and 7 defensemen, can yield 286 unique forward lines and 21 unique defensive pairings. If a coach wanted to see just 20 minutes of play from every forward combination, it would take approximately 95 games of icetime to cycle through them all.
To solve this, we can extrapolate from existing data to infer how unseen combinations would perform. By encoding players and their historical relationships into a Graph Neural Network (GNN), we can embed player information as "nodes" and their shared icetime as "edges". This allows the model to predict the expected goals percentage (xG%) for lines that may have never played a single shift together.
2026-01-31
Fire up the line blender. Over this series of posts, I'm going to explore an approach to finding optimal lineups using data-driven modeling. I'll start with the fundamentals of optimization before moving into more complex territory, using Graph Neural Networks (GNN) to evaluate previously unseen lines.
2026-01-19
Earlier this week, I was sucked into this thread: Ask HN: Share your personal website. Paging through people's personal websites is great; there are plenty of examples of creativity and personality on the internet and outside of social media.
2026-01-12
I began using Plotly in 2016 to add interactivity to what were previously static matplotlib charts. When I launched my personal website in 2017 and began publishing data visualizations, Plotly was the default tool I chose. And for the last eight years, my charts lived on in Plotly's "Chart Studio".