Forecasting Commodity Prices with Alternative Time Series Methods Using Python
BURAK OVACIK
Indirect Sourcing Lead @ GE Aerospace | Strategic Sourcing and Procurement
Forecasting commodity prices is a critical task for procurement team reliant on raw. Commodity prices can be highly volatile due to supply-demand imbalances, seasonal trends, and geopolitical influences. By employing time series forecasting techniques, stakeholders can anticipate price changes, manage risks, and improve budgeting and planning. In Python, Exponential Smoothing and SARIMA (Seasonal ARIMA) are two popular time series models used for forecasting, each with unique strengths.
Key Concepts in Forecasting Commodity Prices
Applications and Benefits
Commodity price forecasting aids businesses in decision-making areas like procurement. By applying alternative time series methods in Python, analysts can compare model accuracy, identify the best-fitting approach, and produce reliable predictions to guide business strategies. This method also enables industries to adapt to market fluctuations and prepare for potential price changes.
This Python code performs time series forecasting for multiple commodity prices using two forecasting methods: Exponential Smoothing and SARIMA (Seasonal ARIMA). Here’s a breakdown of what each section of the code does:
1. Import Required Libraries
2. Load the Data File
3. Data Cleaning
4. Define Commodities for Forecasting
5. Forecast Parameters
6. Apply Forecasting Models (Exponential Smoothing and SARIMA)
7. Plot the Forecasts
Summary
This code loads, cleans, and processes commodity price data, then forecasts the next 12 months of prices for selected commodities using two methods. The code concludes by visually comparing these forecasts to the historical data, allowing users to assess trends and seasonal patterns in each commodity's price.
PYTHON CODE:
# Required imports
import pandas as pd
import statsmodels.api as sm
from statsmodels.tsa.holtwinters import ExponentialSmoothing
import matplotlib.pyplot as plt
# Load the data file
file_path = '/Users/bovacik/Downloads/Monthly_Comoddity_Prices.csv' # Update with the correct path
monthly_prices_df = pd.read_csv(file_path, delimiter=";", engine='python')
# Step 1: Clean the column names by stripping extra spaces and formatting issues
monthly_prices_df.columns = monthly_prices_df.columns.str.strip()
# Step 2: Convert numeric values to proper float format
for col in monthly_prices_df.columns[1:]:
if monthly_prices_df[col].dtype == 'object':
# Remove any non-numeric characters except comma and dot
monthly_prices_df[col] = monthly_prices_df[col].replace({r'[^\d,]': ''}, regex=True)
# Replace commas with dots and convert to float
monthly_prices_df[col] = monthly_prices_df[col].str.replace(",", ".").astype(float)
# Step 3: Convert 'Period' to datetime format
monthly_prices_df['Period'] = pd.to_datetime(monthly_prices_df['Period'], format='%b.%y', errors='coerce')
# Step 4: Define the selected commodities for forecasting
selected_commodities = [
"Crude oil Brent", "Natural gas Europe", "Cocoa",
"Aluminum", "Copper", "Lead", "Nickel", "Zinc", "Platinum"
]
# Step 5: Set up forecast parameters and dictionaries to store results
forecast_steps = 12
forecasts_exp_smoothing = {}
forecasts_sarima = {}
# Step 6: Forecasting with Exponential Smoothing and SARIMA for each commodity
for col in selected_commodities:
try:
# Prepare the time series data
commodity_df = monthly_prices_df[['Period', col]].dropna()
commodity_series = commodity_df.set_index('Period')[col]
# Exponential Smoothing
model_exp_smoothing = ExponentialSmoothing(commodity_series, seasonal='add', seasonal_periods=12)
fit_exp_smoothing = model_exp_smoothing.fit()
forecast_exp_smoothing = fit_exp_smoothing.forecast(steps=forecast_steps)
forecasts_exp_smoothing[col] = forecast_exp_smoothing
# SARIMA (Seasonal ARIMA)
model_sarima = sm.tsa.SARIMAX(commodity_series, order=(1, 1, 1), seasonal_order=(1, 1, 1, 12))
fit_sarima = model_sarima.fit(disp=False)
forecast_sarima = fit_sarima.forecast(steps=forecast_steps)
forecasts_sarima[col] = forecast_sarima
except Exception as e:
print(f"Forecasting failed for {col}: {e}")
# Step 7: Plot the forecasts
for col in selected_commodities:
if col in forecasts_exp_smoothing and col in forecasts_sarima:
plt.figure(figsize=(12, 6))
# Plot historical data
commodity_df = monthly_prices_df[['Period', col]].dropna()
plt.plot(commodity_df['Period'], commodity_df[col], label='Historical Data', color='black', linewidth=2)
# Plot Exponential Smoothing forecast
forecast_dates = pd.date_range(commodity_df['Period'].iloc[-1], periods=forecast_steps+1, freq='M')[1:]
plt.plot(forecast_dates, forecasts_exp_smoothing[col], color='blue', linestyle='--', marker='o', label='Exp. Smoothing Forecast')
# Plot SARIMA forecast
plt.plot(forecast_dates, forecasts_sarima[col], color='red', linestyle='-', marker='x', label='SARIMA Forecast')
# Add plot details
plt.title(f'{col} - 12-Month Price Forecast')
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend(loc='upper left')
plt.grid(True)
plt.tight_layout()
plt.show()
References