Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import pandas as pd | |
| import pmdarima as pm | |
| from pmdarima import auto_arima | |
| import plotly.graph_objs as go | |
| def forecast_time_series(file): | |
| # Load data | |
| data = pd.read_csv(file.name, skiprows=2) | |
| period_type = data.columns[0] | |
| data[period_type] = pd.to_datetime(data[period_type]) | |
| data.set_index(period_type, inplace=True) | |
| # Fit the SARIMAX model automatically | |
| model = auto_arima(data) | |
| # Forecasting | |
| n_periods = 24 # Number of periods to forecast | |
| forecast, conf_int = model.predict(n_periods=n_periods, return_conf_int=True) | |
| # Create a DataFrame with the forecast and confidence intervals | |
| forecast_index = pd.date_range(start=data.index[-1], periods=n_periods + 1, freq=data.index.inferred_freq)[1:] | |
| forecast_df = pd.DataFrame(forecast, index=forecast_index, columns=['Forecast']) | |
| conf_int_df = pd.DataFrame(conf_int, index=forecast_index, columns=['Lower CI', 'Upper CI']) | |
| forecast_df = pd.concat([forecast_df, conf_int_df], axis=1) | |
| # Calculate the YoY change | |
| sum_last_12_original = data.iloc[-12:, 0].sum() | |
| sum_first_12_forecast = forecast_df['Forecast'].iloc[:12].sum() | |
| yoy_change = (sum_first_12_forecast - sum_last_12_original) / sum_last_12_original | |
| # Create an interactive plot with Plotly | |
| fig = go.Figure() | |
| fig.add_trace(go.Scatter(x=data.index, y=data.iloc[:, 0], mode='lines', name='Original Series')) | |
| fig.add_trace(go.Scatter(x=forecast_df.index, y=forecast_df['Forecast'], mode='lines', name='Forecast', line=dict(color='red'))) | |
| fig.add_trace(go.Scatter( | |
| x=forecast_df.index, | |
| y=forecast_df['Lower CI'], | |
| fill=None, | |
| mode='lines', | |
| line=dict(color='pink'), | |
| showlegend=False | |
| )) | |
| fig.add_trace(go.Scatter( | |
| x=forecast_df.index, | |
| y=forecast_df['Upper CI'], | |
| fill='tonexty', | |
| mode='lines', | |
| line=dict(color='pink'), | |
| name='Confidence Interval' | |
| )) | |
| fig.update_layout( | |
| title='Original Time Series and Forecast with Confidence Intervals', | |
| xaxis_title='Date', | |
| yaxis_title='Values', | |
| legend=dict( | |
| orientation='h', | |
| yanchor='bottom', | |
| y=1.02, | |
| xanchor='right', | |
| x=1 | |
| ), | |
| hovermode='x unified' | |
| ) | |
| # Combine original data and forecast data into one DataFrame for export | |
| combined_df = pd.concat([data, forecast_df], axis=0) | |
| combined_file = 'combined_data.csv' | |
| combined_df.to_csv(combined_file) | |
| # Return plot file path and YoY change | |
| return fig, f'Year-over-Year Change in Sum of Values: {yoy_change:.2%}', combined_file | |
| # Create Gradio interface using Blocks | |
| with gr.Blocks(theme=gr.themes.Monochrome()) as interface: | |
| gr.Markdown("# Time Series Forecasting") | |
| gr.Markdown("Upload a CSV file with a time series to forecast the next 24 periods and see the YoY % change. Download the combined original and forecast data.") | |
| with gr.Row(): | |
| file_input = gr.File(label="Upload Time Series CSV") | |
| with gr.Row(): | |
| plot_output = gr.Plot(label="Time Series + Forecast Chart") | |
| with gr.Row(): | |
| yoy_output = gr.Text(label="YoY % Change") | |
| with gr.Row(): | |
| csv_output = gr.File(label="Download Combined Data CSV") | |
| file_input.change(forecast_time_series, inputs=file_input, outputs=[plot_output, yoy_output, csv_output]) | |
| # Launch the interface | |
| interface.launch() | |