As a data scientist working with time series data in the F1 racing domain, I've often found myself torn between choosing the right library and technique for building accurate forecasting models. Recently, I had the opportunity to work with the Open F1 Race Data API, which provides a wealth of information on F1 race meetings, including dates, locations, and results. In this post, I'll walk you through how I used a combination of Prophet and statsmodels to build a highly accurate time series forecasting model for F1 racing data, and what I learned along the way.
Key Takeaways
- Prophet is well-suited for long-term trend forecasting and seasonal decomposition, while statsmodels excels at short-term forecasting and anomaly detection.
- Combining the forecasts from Prophet and statsmodels can produce a more accurate and robust time series forecasting model.
- It's essential to carefully evaluate the performance of each model and adjust the hyperparameters accordingly to achieve the best results.
The Problem
The problem I faced was building an accurate time series forecasting model for F1 racing data, which is inherently noisy and subject to various external factors such as weather, track conditions, and team performance. I needed a model that could capture both the long-term trends and short-term fluctuations in the data.
Data and Sources
I used the Open F1 Race Data API, specifically the endpoint https://api.openf1.org/v1/meetings?year=2024, to retrieve a list of F1 race meetings for the 2024 season. Data accessed on 2024-09-01.
Loading the Data
To load the data, I used the `requests` library to send a GET request to the API endpoint and retrieve the JSON response.
import requests
response = requests.get("https://api.openf1.org/v1/meetings?year=2024")
data = response.json()
Step 1 — Data Preprocessing
In this step, I preprocessed the data by converting the date fields to a suitable format and extracting the relevant features.
import pandas as pd
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])
df['day_of_week'] = df['date'].dt.dayofweek
Step 2 — Prophet Modeling
In this step, I used Prophet to build a model for long-term trend forecasting and seasonal decomposition.
from prophet import Prophet
model = Prophet()
model.fit(df)
future = model.make_future_dataframe(periods=30)
forecast = model.predict(future)
Step 3 — Statsmodels Modeling
In this step, I used statsmodels to build a model for short-term forecasting and anomaly detection.
from statsmodels.tsa.arima.model import ARIMA
model = ARIMA(df['value'], order=(1,1,1))
model_fit = model.fit()
forecast = model_fit.forecast(steps=30)
Step 4 — Model Combination
In this step, I combined the forecasts from Prophet and statsmodels to produce a more accurate and robust time series forecasting model.
combined_forecast = (forecast_prophet + forecast_statsmodels) / 2
Complete Script
The full runnable script combining all steps:
#!/usr/bin/env python3
import requests
import pandas as pd
from prophet import Prophet
from statsmodels.tsa.arima.model import ARIMA
def load_data():
response = requests.get("https://api.openf1.org/v1/meetings?year=2024")
data = response.json()
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])
df['day_of_week'] = df['date'].dt.dayofweek
return df
def prophet_modeling(df):
model = Prophet()
model.fit(df)
future = model.make_future_dataframe(periods=30)
forecast = model.predict(future)
return forecast
def statsmodels_modeling(df):
model = ARIMA(df['value'], order=(1,1,1))
model_fit = model.fit()
forecast = model_fit.forecast(steps=30)
return forecast
def combine_forecasts(forecast_prophet, forecast_statsmodels):
combined_forecast = (forecast_prophet + forecast_statsmodels) / 2
return combined_forecast
if __name__ == "__main__":
df = load_data()
forecast_prophet = prophet_modeling(df)
forecast_statsmodels = statsmodels_modeling(df)
combined_forecast = combine_forecasts(forecast_prophet, forecast_statsmodels)
print(combined_forecast)
Expected Output
The script will output the combined forecast, which can be used for further analysis or visualization.
Limitations and Tradeoffs
This approach assumes that the data is stationary and that the trends and seasonality are consistent over time. However, in practice, the data may be non-stationary, and the trends and seasonality may change over time. Additionally, the choice of hyperparameters for the models can significantly impact the performance of the forecasting model.
Frequently Asked Questions
How do I choose the right hyperparameters for the models?
The choice of hyperparameters depends on the specific characteristics of the data and the goals of the forecasting model. It's essential to carefully evaluate the performance of each model and adjust the hyperparameters accordingly to achieve the best results.
Can I use this approach for other types of time series data?
Yes, this approach can be used for other types of time series data, but it's essential to carefully evaluate the assumptions and limitations of the approach and adjust the models and hyperparameters accordingly.
How do I handle missing values in the data?
Missing values can be handled using various techniques such as interpolation, imputation, or deletion, depending on the characteristics of the data and the goals of the forecasting model.
What I'd Change
In conclusion, while this approach has shown promising results, I would change the way I handle non-stationarity in the data and explore more advanced techniques for hyperparameter tuning to further improve the performance of the forecasting model. Additionally, I would consider using more advanced models such as LSTM or GRU for short-term forecasting and anomaly detection. Next Steps: Try applying this approach to other types of time series data and explore more advanced techniques for hyperparameter tuning and model selection.