TrackVision is a production-grade AI-powered Formula 1 analytics dashboard that visualizes driver performance trends and predicts upcoming race results. Built using ML architecture and a streamlined data pipeline, TrackVision ingests real race data, trains predictive models, and serves intelligent insights through a modern API layer.
| Component | Description |
|---|---|
FastAPI |
Backend API for race stats, visualizations, and predictions |
scikit-learn |
ML model training and evaluation pipeline |
AWS S3 |
Cloud storage for datasets and trained models |
Apache Airflow |
Orchestrates weekly model retraining and updates |
React + Vite |
(Frontend) Visual dashboard for race analysis |
- 📈 Visualize performance for any current F1 driver
- 🧠 Predict next race finishing position using ML
- ⚙️ Cloud-first design with S3 data ingestion and model storage
- 🚀 Weekly retraining pipeline via Apache Airflow
- 🔄 RESTful API integration with frontend dashboard
TrackVision uses a Gradient Boosting Regressor trained on sliding windows of recent race data to predict a driver's next finishing position. The model considers:
- Average grid and finish positions
- DNF count and lap completion
- Qualifying rank
- Fastest lap rank
- Constructor gap (team points lead vs. current top team)
The model is optimized using GridSearchCV and evaluated via Mean Absolute Error (MAE).
Returns the current top driver in the championship standings.
{ "driver": "Oscar Piastri" }Returns summary stats and race history for a specific driver.
range=1→ Last racerange=5→ Last 5 racesrange=full→ Entire season
{
"driver": "Max Verstappen",
"season": "2025",
"range": "1",
"summary": {
"total_points": 1.0,
"best_position": 10,
"races_completed": 1
},
"races": [
{
"round": 9,
"race_name": "Spanish Grand Prix",
"date": "2025-06-01",
"position": 10,
"grid_position": 3,
"points": 1.0,
"status": "Finished"
},
...
]
}Returns the predicted position for a driver in the next race.
{
"driver": "oscar piastri",
"predicted_position": 2,
"confidence": 98,
"upcoming_race": {
"name": "Canadian Grand Prix",
"circuit": "Circuit Gilles Villeneuve",
"date": "2025-06-15"
},
"recent_finishes": [1, 1, 3, 3, 1],
"average_finish": 1.8,
"team_points_lead": 192,
"qualifying_rank": 1
}-
Data Ingestion
- Driver results for the 2025 season are stored in
Parquetformat in S3. - Fetched into memory using
boto3andpandas.
- Driver results for the 2025 season are stored in
-
Model Training
train_model.pyextracts features from recent race windows.- Uses
scikit-learn'sGradientBoostingRegressorwith hyperparameter tuning. - Trained model and constructor encoder are saved to S3 for future inference.
-
API Layer
- Built using
FastAPIfor high-speed, async-ready responses. - Handles endpoints for data visualization and predictions.
- Uses
lru_cachefor S3 efficiency and quick response times.
- Built using
-
Scheduled Retraining
- An Apache Airflow DAG runs weekly to refresh the model using new race data.
pip install -r requirements.txtBefore running the app, set your environment variables in a .env file or export them manually:
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=
TRACKVISION_BUCKET=
CORS_ORIGINS=uvicorn app:app --reloadEnsure Airflow is set up and the DAG is loaded, then trigger manually:
airflow dags trigger trackvision_weekly_model_trainingnpm run devYou can deploy the full TrackVision system as follows:
Use the included docker-compose.yml to spin up the backend, Airflow, and any other services.
docker-compose up --buildEnsure your .env is properly configured and included.
- Deploy to Railway, Render, or [AWS EC2]
- Ensure the container has access to your
.envvars and AWS credentials - If not using Docker, use Gunicorn + Uvicorn worker to serve FastAPI in production
- Deploy to Vercel or Netlify
- Update
CORS_ORIGINSin your backend to match the deployed frontend origin
- Run locally with Docker Compose, or
- Deploy to managed services like MWAA (Managed Workflows for Apache Airflow) or Astro
- Schedule the DAG (
trackvision_weekly_model_training) to retrain the model weekly
Adnan T. — @adnant1

