|
|
import streamlit as st |
|
|
import pandas as pd |
|
|
import plotly.graph_objs as go |
|
|
from statsmodels.tsa.arima.model import ARIMA |
|
|
from statsmodels.tsa.stattools import adfuller |
|
|
|
|
|
|
|
|
st.set_page_config(page_title="ARIMA Forecasting with Streamlit", layout="wide") |
|
|
|
|
|
|
|
|
st.title("📈 Time Series Forecasting with ARIMA for Vegetable Prices") |
|
|
|
|
|
|
|
|
st.sidebar.header("User Configuration") |
|
|
file_path = st.sidebar.text_input("Enter the path to your CSV file", 'arima.csv') |
|
|
|
|
|
p = st.sidebar.number_input("ARIMA Parameter p (AR term)", min_value=0, max_value=5, value=1) |
|
|
d = st.sidebar.number_input("ARIMA Parameter d (Differencing)", min_value=0, max_value=2, value=1) |
|
|
q = st.sidebar.number_input("ARIMA Parameter q (MA term)", min_value=0, max_value=5, value=1) |
|
|
|
|
|
|
|
|
try: |
|
|
data = pd.read_csv(file_path) |
|
|
data['Date'] = pd.to_datetime(data['Date'], format='%d-%m-%Y', errors='coerce') |
|
|
data = data.dropna(subset=['Date', 'Average']) |
|
|
commodities = data['Commodity'].unique() |
|
|
except FileNotFoundError: |
|
|
st.error("Data file not found. Please check the file path and try again.") |
|
|
st.stop() |
|
|
|
|
|
|
|
|
selected_commodity = st.sidebar.selectbox("Select a Vegetable Commodity", commodities) |
|
|
|
|
|
|
|
|
commodity_data = data[data['Commodity'] == selected_commodity].sort_values('Date') |
|
|
|
|
|
|
|
|
st.subheader(f"Data Overview and Stationarity Check for '{selected_commodity}'") |
|
|
st.write(commodity_data.head()) |
|
|
|
|
|
|
|
|
adf_result = adfuller(commodity_data['Average']) |
|
|
is_stationary = adf_result[1] < 0.05 |
|
|
|
|
|
|
|
|
with st.expander(f"Augmented Dickey-Fuller Test Results for '{selected_commodity}'", expanded=False): |
|
|
st.write(f"ADF Statistic: {adf_result[0]:.4f}") |
|
|
st.write(f"p-value: {adf_result[1]:.4f}") |
|
|
st.write("Critical Values:") |
|
|
for key, value in adf_result[4].items(): |
|
|
st.write(f" {key}: {value:.4f}") |
|
|
st.success(f"The time series is {'stationary' if is_stationary else 'not stationary'} (p-value {'<' if is_stationary else '>='} 0.05).") |
|
|
|
|
|
|
|
|
st.subheader(f"ARIMA Model Fitting and Summary for '{selected_commodity}'") |
|
|
model = ARIMA(commodity_data['Average'], order=(p, d, q)) |
|
|
model_fit = model.fit() |
|
|
|
|
|
|
|
|
with st.expander("ARIMA Model Summary", expanded=False): |
|
|
st.write(model_fit.summary()) |
|
|
|
|
|
|
|
|
last_date = commodity_data['Date'].max() |
|
|
forecast_end_date = pd.to_datetime('2025-12-31') |
|
|
forecast_periods = (forecast_end_date - last_date).days |
|
|
|
|
|
|
|
|
forecast = model_fit.get_forecast(steps=forecast_periods) |
|
|
forecast_index = pd.date_range(start=last_date + pd.Timedelta(days=1), periods=forecast_periods) |
|
|
forecast_values = forecast.predicted_mean |
|
|
conf_int = forecast.conf_int() |
|
|
|
|
|
|
|
|
st.subheader(f"Forecast Visualization for '{selected_commodity}' until {forecast_end_date.date()}") |
|
|
fig = go.Figure() |
|
|
|
|
|
|
|
|
fig.add_trace(go.Scatter( |
|
|
x=commodity_data['Date'], |
|
|
y=commodity_data['Average'], |
|
|
mode='lines+markers', |
|
|
name='Historical Data', |
|
|
line=dict(color='royalblue', width=2) |
|
|
)) |
|
|
|
|
|
|
|
|
fig.add_trace(go.Scatter( |
|
|
x=forecast_index, |
|
|
y=forecast_values, |
|
|
mode='lines+markers', |
|
|
name='Forecast', |
|
|
line=dict(color='red', width=2, dash='dash'), |
|
|
hovertemplate='Date: %{x}<br>Price: %{y:.2f}<extra></extra>' |
|
|
)) |
|
|
|
|
|
|
|
|
fig.add_trace(go.Scatter( |
|
|
x=forecast_index.tolist() + forecast_index[::-1].tolist(), |
|
|
y=conf_int.iloc[:, 0].tolist() + conf_int.iloc[:, 1][::-1].tolist(), |
|
|
fill='toself', |
|
|
fillcolor='rgba(173, 216, 230,0.2)', |
|
|
line=dict(color='rgba(255,255,255,0)'), |
|
|
name='Confidence Interval' |
|
|
)) |
|
|
|
|
|
|
|
|
fig.update_layout( |
|
|
title=f"ARIMA Forecast for '{selected_commodity}' Prices until 2025", |
|
|
xaxis_title='Date', |
|
|
yaxis_title='Average Price (in Kg)', |
|
|
legend=dict(x=0.01, y=0.99), |
|
|
template='plotly_white', |
|
|
hovermode='x unified' |
|
|
) |
|
|
|
|
|
|
|
|
st.plotly_chart(fig, use_container_width=True) |
|
|
|
|
|
|
|
|
st.subheader(f"Forecasted Prices for '{selected_commodity}' until 2025") |
|
|
forecast_table = pd.DataFrame({ |
|
|
'Date': forecast_index, |
|
|
'Forecasted Price': forecast_values, |
|
|
'Lower Confidence Interval': conf_int.iloc[:, 0], |
|
|
'Upper Confidence Interval': conf_int.iloc[:, 1] |
|
|
}) |
|
|
st.dataframe(forecast_table) |
|
|
|
|
|
st.info("Adjust the ARIMA parameters in the sidebar to see different results.") |
|
|
|