Najm_NSR / app.py
XPMaster's picture
Update app.py
24d2e79
raw
history blame
No virus
4.39 kB
import streamlit as st
import pandas as pd
from io import BytesIO
from itertools import product
from statsmodels.tsa.holtwinters import ExponentialSmoothing
import plotly.express as px
st.set_page_config(layout="wide")
# Function to run the Exponential Smoothing Model
def run_exp_smoothing(city_data, trend, damped_trend, seasonal, seasonal_period):
try:
model = ExponentialSmoothing(city_data, trend=trend, damped_trend=damped_trend, seasonal=seasonal, seasonal_periods=seasonal_period)
model_fit = model.fit(optimized=True)
return model_fit.forecast(steps=6), model_fit.aic
except Exception as e:
st.error(f"An error occurred during model fitting: {e}")
return None, None
def create_data():
data = pd.read_csv('accident_count.csv', parse_dates=True, index_col=0)
data.index = pd.to_datetime(data.index, format='%Y%m')
data = data.groupby('City').resample('M').sum().reset_index()
data.index = data['Accident Month Bracket']
data = data.drop(['Accident Month Bracket'],axis=1)
data.index = data.index.strftime('%Y-%m')
return data
# Function to convert DataFrame to Excel
def to_excel(df):
output = BytesIO()
writer = pd.ExcelWriter(output, engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1')
writer.save()
processed_data = output.getvalue()
return processed_data
# Initialize session state for best parameters
if 'best_params' not in st.session_state:
st.session_state.best_params = {'trend': None, 'damped_trend': False, 'seasonal': None, 'seasonal_period': 12}
st.title("Exponential Smoothing Forecasting")
# Data preparation
data = create_data()
unique_cities = data['City'].unique()
# Creating tabs for each city
tabs = st.tabs([city for city in unique_cities])
for tab, city in zip(tabs, unique_cities):
with tab:
# Sliders for parameter adjustment, using session state values as defaults
trend = st.select_slider('Select Trend', options=['add', 'mul', None], value=st.session_state.best_params['trend'],key=city+'1')
damped_trend = False
seasonal = st.select_slider('Select Seasonal', options=['add', 'mul', None], value=st.session_state.best_params['seasonal'],key=city+'2')
seasonal_period = st.slider('Seasonal Period', 1, 24, value=st.session_state.best_params['seasonal_period'],key=city+'3')
city_data = data[data['City'] == city]['Accident Count']
forecast, aic = run_exp_smoothing(city_data, trend, damped_trend, seasonal, seasonal_period)
if forecast is not None:
st.write(f"Best Parameters with AIC: {aic}")
st.write(f"Trend: {trend}, Damped Trend: {damped_trend}, Seasonal: {seasonal}, Seasonal Period: {seasonal_period}")
forecast_index = pd.date_range(start=city_data.index[-1], periods=7, freq='M')[1:]
forecast_index = forecast_index.to_period('M') # Convert to period index with monthly frequency
forecast_df = pd.DataFrame(forecast, columns=['Forecast'])
forecast_df = forecast_df.round(0)
st.table(forecast_df)
fig = px.line(forecast_df, x=forecast_df.index, y="Forecast")
st.plotly_chart(fig)
# Grid search button
if st.button(f'Run Grid Search for {city}'):
best_aic = float('inf')
best_params = None
for param_set in product(['add', 'mul', None], [False], ['add', 'mul', None], [12]):
_, temp_aic = run_exp_smoothing(city_data, *param_set)
if temp_aic and temp_aic < best_aic:
best_aic = temp_aic
best_params = param_set
# Updating session state with the best parameters
st.session_state.best_params = {
'trend': best_params[0],
'damped_trend': best_params[1],
'seasonal': best_params[2],
'seasonal_period': best_params[3]
}
st.write(f"Best Parameters for {city}: {best_params} with AIC: {best_aic}")
# Export to Excel button
if st.button(f'Export {city} to Excel'):
df_to_export = forecast_df
excel_data = to_excel(df_to_export)
st.download_button(label='πŸ“₯ Download Excel', data=excel_data, file_name=f'{city}_forecast.xlsx', mime='application/vnd.ms-excel')