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)
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.
- 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
- Ingested multi-category 2024 NFL player performance statistics via SportsData.io API and local cached datasets.
- Standardized positions (mapping FB->RB, OLB/ILB->LB, secondary roles) and formulated custom PPR + IDP scoring weights.
- Calculated positional Value Over Replacement (VOR) baselines based on standard 12-team roster starter demand.
- Compared tier counts from k=2 to 10 with the elbow method, silhouette analysis and the gap statistic.
- 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.