F1 Race Outcome Classification

Random Forest and ANN classifiers on the Ergast Formula 1 dataset (1950–2024) for binary DNF prediction and multiclass finishing-tier prediction.

  • Binary classification: did the driver fail to finish (DNF)?
  • Multiclass classification: DNF / P11+ / P4–P10 / Podium / Winner
  • Random Forest and ANN (MLP) for both tasks, tuned with GridSearchCV
  • Per-hyperparameter validation curves, learning curves, and confusion matrices
  • Stratified 5-fold CV with fixed seeds for full reproducibility

Overview

A machine learning pipeline that predicts Formula 1 race outcomes from the Kaggle / Ergast F1 dataset (1950–2024). Two classification tasks, four tuned models, full hyperparameter sweeps with validation and learning curves. Final project for CSC 272 at Hofstra, completed with my teammate Michael Campos. This writeup covers the Random Forest and ANN half of the project (main.py); KNN, SVM, and Decision Tree results live in the accompanying report.

Tasks

TaskTargetEraSamplesPrimary metric
Binarydnf (did the driver fail to finish?)1958–202424,618Weighted F1 + AUC-ROC
MulticlasspositionTier (DNF / P11+ / P4–P10 / Podium / Winner)2012–20245,082Macro F1

The multiclass task is restricted to 2012+ because bestQualiTime and pitStopCount are only reliably populated from then on.

Headline Results

TaskModelTrain F1CV Val F1Test F1Test AUC
BinaryRandom Forest0.9560.8120.8040.877
BinaryANN (MLP)0.8210.8120.8020.874
MulticlassRandom Forest1.0000.4910.492N/A
MulticlassANN (MLP)0.5030.4500.436N/A

The binary task hits a shared ceiling near F1 ≈ 0.80; the multiclass task is data-limited (5,082 samples) and dominated by adjacent-tier confusion (P2–P3 ↔ P1, P4–P10 ↔ P11+).

Features

Binary (six pre-race features, no post-race leakage): grid, driverAge, driverStandingPos, constructorPoints, year, round.

Multiclass (six pace and strategy features): grid, driverPoints, constructorPoints, bestQualiTime, pitStopCount, year.

Hyperparameter Grids

ModelHyperparameters
Binary RFn_estimators ∈ 300, max_depth ∈ 25
Binary ANNhidden_layer_sizes ∈ 5 archs from (50,) to (50,50,50), learning_rate_init ∈ 0.1
Multiclass RFn_estimators ∈ 300, max_features ∈ 6
Multiclass ANNhidden_layer_sizes ∈ 5 archs from (50,) to (50,50,50), alpha ∈ 0.1

All experiments use StratifiedKFold(n_splits=5, shuffle=True, random_state=42). Binary scoring is f1_weighted; multiclass scoring is f1_macro. RF uses class_weight="balanced"; ANN uses StandardScaler plus early_stopping=True.

What the Numbers Actually Say

  • Binary task plateaus near F1 ≈ 0.80 for both models. Random Forest is the very narrow winner on test F1 and AUC, but ANN is within noise. The ceiling is the feature set, not the model.
  • Multiclass is data-limited. 5,082 samples across 5 classes, with most error coming from adjacent tiers (podium vs winner, midfield vs lower midfield). Random Forest doubles ANN's training F1 but only beats it by ~5 points on the test set.
  • Reproducibility is exact. Every seed is fixed (random_state=42) across train/test splitting, StratifiedKFold, RandomForestClassifier, and MLPClassifier. Re-running main.py against the same CSVs produces identical numbers and identical figures.

Tech Stack

  • Python 3.11, scikit-learn (RandomForestClassifier, MLPClassifier, GridSearchCV, StratifiedKFold)
  • pandas, NumPy for the data merge across 8 Ergast CSVs
  • Matplotlib for the 16 generated figures (validation curves, learning curves, confusion matrices)
  • conda environment pinned via environment.yml