Skip to content
Ben Manguiat
All work

Only 22 of 163 NFL players earned an elite fantasy tier.

Unsupervised machine learning pipeline that clusters NFL players into actionable fantasy performance tiers using custom PPR+IDP scoring, Value Over Replacement (VOR), and K-Means, with the tier count checked against three validation methods.

Project
NFL Player Clustering & Fantasy Tier Analytics
Role
Data Analyst (Solo Project)
When
Spring 2025
Validation Methods
Elbow, Silhouette, Gap
Clustering Model
K-Means (k=4, silhouette 0.57)

Source code

What I found

  • Ranked players across positions on one scale by comparing each to a replacement-level starter (VOR), instead of raw points.
  • Split players into 4 draft tiers. The validation methods did not agree on one k (silhouette peaked at k=2 with 0.69); k=4 was chosen to give usable draft tiers, with a silhouette of 0.57.
  • Packaged as a CLI pipeline + Colab notebook with a bundled sample dataset so it runs without an API key.

The tiers

Sample run on the repo's bundled 2024 dataset (163 players, includes placeholder records). k=4, silhouette 0.57.

Vertical: value over replacement (VOR)Horizontal: fantasy points (PPR + IDP)
Tier 1: Elite
VOR 173 to 294, 22 players
Tier 2: High-end starters
VOR 85 to 166, 36 players
Tier 3: Average
VOR 33 to 83, 73 players
Tier 4: Below replacement
VOR -40 to 29, 32 players

The question

Evaluating NFL player fantasy draft value using raw stats leads to recency bias. Traditional position labels ignore historical performance clusters, positional scarcity, and replacement baselines.

How I built it

  1. Ingested multi-category 2024 NFL player performance statistics via SportsData.io API and local cached datasets.
  2. Standardized positions (mapping FB->RB, OLB/ILB->LB, secondary roles) and formulated custom PPR + IDP scoring weights.
  3. Calculated positional Value Over Replacement (VOR) baselines based on standard 12-team roster starter demand.
  4. Compared tier counts from k=2 to 10 with the elbow method, silhouette analysis and the gap statistic.
  5. Trained K-Means model, sorted clusters by descending average VOR, and mapped actionable fantasy draft tiers.

The code

Python (scikit-learn)

# K-Means Clustering on Value Over Replacement (VOR)
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

# 1. Isolate feature vector (Value Over Replacement)
X = df_selected_players[['VOR']].values

# 2. Fit K-Means clustering model (k=4)
kmeans = KMeans(n_clusters=4, random_state=418, n_init=10)
df_selected_players['Cluster'] = kmeans.fit_predict(X)

# 3. Sort & rank clusters by descending mean VOR into actionable tiers
cluster_summary = df_selected_players.groupby('Cluster')['VOR'].mean().sort_values(ascending=False)
tier_map = {old: new for new, old in enumerate(cluster_summary.index)}
df_selected_players['Tier'] = df_selected_players['Cluster'].map(tier_map)

# 4. Map readable tier labels
tier_labels = ["Tier 1 — Elite", "Tier 2 — High-End Starters", "Tier 3 — Average", "Tier 4 — Sub-Replacement"]
df_selected_players['TierLabel'] = df_selected_players['Tier'].map(lambda x: tier_labels[x])

What I delivered

Built a modular data science repository with an end-to-end CLI pipeline and reproducible Google Colab notebook that partitions NFL players into 4 empirical draft tiers.