File size: 5,722 Bytes
40094ce
c7efea2
 
2cef665
09e0298
20c54a1
9fa0a4d
a6043ed
f6880ae
 
 
 
a6043ed
40094ce
d480317
3fd0943
ce1c969
 
 
88c217f
a795fca
20c54a1
cd438b1
20c54a1
f374886
 
 
f65696e
f374886
 
 
 
a6043ed
20c54a1
 
 
 
 
 
a6043ed
 
a07de77
2ae7b31
20c54a1
 
 
57d144c
20c54a1
 
 
 
 
 
 
 
57d144c
20c54a1
 
 
 
 
e491f6b
dc2e65a
4766cef
2ae7b31
 
de42a1d
62af3cd
20c54a1
 
f6880ae
 
 
 
 
 
 
 
 
09e0298
 
 
 
 
ba873da
0762c9b
 
09e0298
 
85e975a
29b3cdb
67d904d
a441f7d
dd12914
5ea550a
 
88802cc
dd12914
 
85e975a
 
29b3cdb
34babee
a441f7d
dd12914
5ea550a
88802cc
 
dd12914
 
 
5ea550a
 
 
 
 
 
 
 
 
 
afd4840
09e0298
 
 
9c4faf8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import streamlit as st
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objs as go
from pmdarima import auto_arima
from utils import calc_seasonality

@st.cache
def convert_df(df):
    return df.to_csv().encode('utf-8')

st.title('Forecasting time series')

uploaded_file = st.file_uploader("Choose a CSV file", accept_multiple_files=False)

if uploaded_file is not None:
     dataframe = pd.read_csv(uploaded_file)
     st.write(dataframe)
     series = st.text_input("Write the name of the variable you want to forecast")
     date = st.text_input('Write the first date')
     # freq = st.text_input('Write the frequency')
     freq = st.selectbox('Select the frequency', 
                          ('Y', 'Q', 'M', 'W', 'D', 'NULL'))
              
     if series is not None and freq is not None:

          horizons = int(st.text_input("Write the number of horizons", value="10"))
          seasonality = calc_seasonality(freq)
          st.write(f'Seasonality: {seasonality}')              

     
          series_train = pd.DataFrame(
                                            {
                                             'ds': pd.date_range(start=date, periods=dataframe.shape[0], freq=freq),
                                             'y': dataframe[series].values
                                            },
                                            index=pd.Index([0] * dataframe.shape[0], name='unique_id')
                                          )              
              
          fig = px.line(series_train, x='ds', y='y', title=f'{series}')
          st.plotly_chart(fig)
          with st.spinner('Wait for it...'):
              if freq != 'NULL':

                  fcst = auto_arima(
                                       series_train['y'], 
                                       seasonality=True, 
                                       freq=freq, 
                                       n_jobs=1,
                                       max_p=12,
                                       max_q=12
                                      )
              else:
                  fcst = auto_arima(
                                       series_train['y'], 
                                       seasonality=False, 
                                       n_jobs=1,
                                       max_p=12,
                                       max_q=12
                                      )
              fcst.fit(series_train['y'])    
              forecasts, ci_05 = fcst.predict(horizons, return_conf_int=True, alpha=0.05)
              _, ci_10 = fcst.predict(horizons, return_conf_int=True, alpha=0.1)
          st.success('Done!')
            
          st.write(forecasts)
          forecasts_df = pd.DataFrame({'ds':pd.date_range(start=series_train['ds'].iloc[-1], periods=horizons, freq=freq),
                                       'mean':forecasts, 'low_ci_05':ci_05[:,0], 'low_ci_10':ci_10[:,0],
                                       'hi_ci_05':ci_05[:,1], 'hi_ci_10':ci_10[:,1]})
          csv = convert_df(forecasts)

          st.download_button(
             label="Download data as CSV",
             data=csv,
             file_name='forecast.csv',
             mime='text/csv',
          )
                  
          fig_forecast = go.Figure([
                       go.Scatter(
                           name=series,
                           x=series_train['ds'],
                           y=series_train['y'],
                           mode='lines',
                           marker=dict(color='blue'),
                           line=dict(width=1),
                           showlegend=True
                       ),
                       go.Scatter(
                           name='PI-95%',
                           x=np.concatenate([forecasts_df['ds'].values,forecasts_df['ds'].values[::-1]]), # x, then x reversed
                           y=pd.concat([forecasts_df['hi_ci_05'],forecasts_df['low_ci_05'][::-1]]), # upper, then lower reversed
                            fill='toself',
                            fillcolor='rgba(63, 232, 39, 0.52)',
                            line=dict(color='rgba(63, 232, 39, 0.52)'),
                            opacity=0.3,
                            hoverinfo="skip",
                            showlegend=True
                       ),
                       go.Scatter(
                           name='PI-90%',
                           x=np.concatenate([forecasts_df['ds'].values,forecasts_df['ds'].values[::-1]]), # x, then x reversed
                           y=pd.concat([forecasts_df['hi_ci_10'],forecasts_df['low_ci_10'][::-1]]), # upper, then lower reversed
                            fill='toself',
                            fillcolor='rgba(63, 232, 39, 0.26)',
                            line=dict(color='rgba(63, 232, 39, 0.26)'),
                            opacity=0.5,
                            hoverinfo="skip",
                            showlegend=True
                       ),
                       go.Scatter(
                           name=f'auto_arima_season_length-{seasonality}_mean',
                           x=forecasts_df['ds'],
                           y=forecasts_df['mean'],
                           mode='lines',
                           marker=dict(color='green'),
                           line=dict(width=1),
                           showlegend=True
                       ),
                        ])
          fig_forecast.update_layout(
                       yaxis_title=series,
                       title=f'Forecasting {series}'
                   )
          st.plotly_chart(fig_forecast)