←Projects

MLB Player Analytics Engine

2025

A player similarity search tool I built for the 2025 SABR Analytics Conference, focused on finding MLB players with similar statistical profiles.

Pythonpandasscikit-learnJupyterGitHub

I built this project for the 2025 SABR Analytics Conference, which I attended through a sponsorship from Major League Baseball. The idea came from a common scouting question: given a player's statistics, who else in the dataset plays similarly? Teams use player comparisons when evaluating talent, building projections, and making decisions about player value. I wanted to build a smaller version of that process and make each step easy to follow.

The project is a Python notebook that uses pandas for data processing and scikit-learn for the modeling. It takes a CSV of player statistics, split into three groups: hitting, batted-ball, and swing metrics.

Hitting statistics include batting average, slugging, walk rate, and strikeout rate. Batted-ball metrics include exit velocity, launch angle, and barrel rate. Swing metrics include bat speed and attack angle. I wanted to use all three groups because looking at a player's overall profile gives a more useful comparison than relying on a single statistic.

Method

The pipeline starts by handling missing values using the median, then standardizes the features so that statistics with larger numerical ranges do not dominate the comparison.

For similarity, I implemented both cosine similarity and inverse Euclidean distance. You can select a player, choose a metric, and retrieve the ten closest matches in the dataset.

The query
  1. 01
    Read
  2. 02
    Fill
  3. 03
    Scale
  4. 04
    Rank
Rafael Devers
Hitting
BA
.279
SLG
.535
HR
29
Batted ball
EV
93.5
LA
12.7
Brl
16%
Swing
Bat
71.6
Ang
9.7
Miss
31%
A player arrives as three kinds of evidence: the batting line, the batted ball, and the swing.
Median imputation, then a standard scale, then a top-ten list. Rafael Devers’s hitting, batted-ball, and swing numbers are the worked example.
Nearest hitters
Query
Luis Arraez
cosine
contactpower
1Nolan Schanuel0.988
2Steven Kwan0.978
3Jacob Wilson0.964
4Josh Smith0.957
Cosine similarity ranks the nearest profiles to Luis Arraez. They are the contact hitters.
Luis Arraez is the query. The closest names are other contact hitters, and power hitters land farther away. The notebook returns ten names. The four nearest are drawn.

I also added optional K-Means clustering to group players with similar statistical profiles. The number of clusters is selected using the elbow method, and PCA plots help visualize how the groups are distributed.

I used these plots to explore whether different types of hitters, such as contact hitters and three-true-outcomes hitters, formed distinct groups.

Outliers

One decision I spent more time on was how to handle outliers. A common preprocessing step is to remove extreme values before fitting a model, but in baseball, some of the most interesting players are outliers precisely because of their performance.

Rather than automatically removing them, I looked at how those players affected the results and decided to keep them in the dataset.

Past the fence
Home runs
654 players
02649
Juan Soto34
Aaron Judge42
Shohei Ohtani44
Kyle Schwarber49
Most of the league sits between 1 and 11 home runs. The median is 4.
Home runs for 654 players. The box is the middle half of the league. Judge, Ohtani, Soto, and Schwarber sit past the 1.5×IQR fence, and they remain in the similarity search.

I wanted the similarity results to be something a scout could actually look through and understand. Keeping the pipeline relatively simple also makes it easier to see how the data is processed and why two players end up being matched.