<jupyter_start><jupyter_text>Time series analysis comprises methods for analyzing time series data in order to extract meaningful statistics and other characteristics of the data. Time series forecasting is the use of a model to predict future values based on previously observed values.<jupyter_code>import warnings
import itertools
import numpy as np
import matplotlib.pyplot as plt
warnings.filterwarnings("ignore")
plt.style.use('fivethirtyeight')
import pandas as pd
import statsmodels.api as sm
import matplotlib
matplotlib.rcParams['axes.labelsize'] = 14
matplotlib.rcParams['xtick.labelsize'] = 12
matplotlib.rcParams['ytick.labelsize'] = 12
matplotlib.rcParams['text.color'] = 'k'
df = pd.read_csv('C:/Users/<NAME>/Downloads/hotel_sales.csv')

hotel_sales=pd.DataFrame(df)
hotel_sales.head()
hotel_sales['date'].min(), hotel_sales['date'].max()
hotel.isnull().sum()
hotel = hotel.groupby('date')['sales'].sum().reset_index()
hotel= hotel_sales[['date','sales']]
hotel['date'] = hotel['date'].astype('datetime64[ns]') 
hotel = hotel.set_index('date')
hotel.index
y = hotel['sales'].resample('MS').mean()
y['2017':]<jupyter_output><empty_output><jupyter_text>Some distinguishable patterns appear when we plot the data. The time-series has seasonality pattern, such as sales are always low at the end of the year and high at start to mid year. There is always an upward trend within any single year with high during( I believe summer) and then low during winters.<jupyter_code>#Indexing with Time Series Data
y.plot(figsize=(15, 6))
plt.show()<jupyter_output><empty_output><jupyter_text>Visualizing our data using a method called time-series decomposition that allows us to decompose our time series into three distinct components: trend, seasonality, and noise.<jupyter_code>from pylab import rcParams
rcParams['figure.figsize'] = 18, 8
decomposition = sm.tsa.seasonal_decompose(y, model='additive')
fig = decomposition.plot()
plt.show()<jupyter_output><empty_output><jupyter_text>The plot above clearly shows that the sales of hotel is unstable, along with its obvious seasonality.  Time series forecasting with ARIMAWe are going to apply one of the most commonly used method for time-series forecasting, known as ARIMA, which stands for Autoregressive Integrated Moving Average.<jupyter_code>p = d = q = range(0, 2)
pdq = list(itertools.product(p, d, q))
seasonal_pdq = [(x[0], x[1], x[2], 12) for x in list(itertools.product(p, d, q))]
print('Examples of parameter combinations for Seasonal ARIMA...')
print('SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[1]))
print('SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[2]))
print('SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[3]))
print('SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[4]))<jupyter_output>Examples of parameter combinations for Seasonal ARIMA...
SARIMAX: (0, 0, 1) x (0, 0, 1, 12)
SARIMAX: (0, 0, 1) x (0, 1, 0, 12)
SARIMAX: (0, 1, 0) x (0, 1, 1, 12)
SARIMAX: (0, 1, 0) x (1, 0, 0, 12)<jupyter_text>Our goal here is to use a “grid search” to find the optimal set of parameters that yields the best performance for our model.<jupyter_code>for param in pdq:
    for param_seasonal in seasonal_pdq:
        try:
            mod = sm.tsa.statespace.SARIMAX(y,
                                            order=param,
                                            seasonal_order=param_seasonal,
                                            enforce_stationarity=False,
                                            enforce_invertibility=False)

            results = mod.fit()

            print('ARIMA{}x{}12 - AIC:{}'.format(param, param_seasonal, results.aic))
        except:
            continue<jupyter_output>ARIMA(0, 0, 0)x(0, 0, 0, 12)12 - AIC:1130.4037531077595
ARIMA(0, 0, 0)x(0, 0, 1, 12)12 - AIC:853.1597514257696
ARIMA(0, 0, 0)x(0, 1, 0, 12)12 - AIC:664.0299784454763
ARIMA(0, 0, 0)x(0, 1, 1, 12)12 - AIC:1407.429495003226
ARIMA(0, 0, 0)x(1, 0, 0, 12)12 - AIC:616.3249731932115
ARIMA(0, 0, 0)x(1, 0, 1, 12)12 - AIC:593.7117287336861
ARIMA(0, 0, 0)x(1, 1, 0, 12)12 - AIC:463.7836926371424
ARIMA(0, 0, 0)x(1, 1, 1, 12)12 - AIC:1409.6430936838156
ARIMA(0, 0, 1)x(0, 0, 0, 12)12 - AIC:1045.0275672758003
ARIMA(0, 0, 1)x(0, 0, 1, 12)12 - AIC:787.5245783644909
ARIMA(0, 0, 1)x(0, 1, 0, 12)12 - AIC:603.3384784866627
ARIMA(0, 0, 1)x(0, 1, 1, 12)12 - AIC:1080.6250526641454
ARIMA(0, 0, 1)x(1, 0, 0, 12)12 - AIC:585.1857606182627
ARIMA(0, 0, 1)x(1, 0, 1, 12)12 - AIC:557.444323931321
ARIMA(0, 0, 1)x(1, 1, 0, 12)12 - AIC:445.6042523300363
ARIMA(0, 0, 1)x(1, 1, 1, 12)12 - AIC:1101.490929501753
ARIMA(0, 1, 0)x(0, 0, 0, 12)12 - AIC:873.0963701494139
ARIMA(0, 1, 0)x(0, 0, 1, 12)12 - AIC:661.3491181924542
ARIMA(0[...]<jupyter_text>The above output suggests that SARIMAX(1, 1, 1)x(1, 1, 0, 12) yields the lowest AIC value of 390.12. Therefore we should consider this to be optimal option.<jupyter_code>mod = sm.tsa.statespace.SARIMAX(y,
                                order=(1, 1, 1),
                                seasonal_order=(1, 1, 0, 12),
                                enforce_stationarity=False,
                                enforce_invertibility=False)

results = mod.fit()

print(results.summary().tables[1])
hotel
#Forecasting for 2019

futura = results.forecast(steps=12)
#Exporting to csv

futura.to_csv("future2019.csv")
futura.head()
results.plot_diagnostics(figsize=(16, 8))
plt.show()<jupyter_output><empty_output><jupyter_text>Validating forecastsTo help us understand the accuracy of our forecasts, we compare predicted sales to real sales of the time series, and we set forecasts to start at 2018–01–01 to the end of the data.<jupyter_code>pred = results.get_prediction(start=pd.to_datetime('2017-01-01'), dynamic=False)
pred_ci = pred.conf_int()

ax = y['2014':].plot(label='observed')
pred.predicted_mean.plot(ax=ax, label='One-step ahead Forecast', alpha=.7, figsize=(14, 7))

ax.fill_between(pred_ci.index,
                pred_ci.iloc[:, 0],
                pred_ci.iloc[:, 1], color='k', alpha=.2)

ax.set_xlabel('Date')
ax.set_ylabel('Hotel Sales')
plt.legend()

plt.show()
y_forecasted = pred.predicted_mean
y_truth = y['2017-01-01':]

# Compute the mean square error
mse = ((y_forecasted - y_truth) ** 2).mean()
print('The Mean Squared Error of our forecasts is {}'.format(round(mse, 2)))
@The Mean Squared Error of our forecasts is 4496.62
print('The Root Mean Squared Error of our forecasts is {}'.format(round(np.sqrt(mse), 2)))<jupyter_output>The Root Mean Squared Error of our forecasts is 67.06<jupyter_text>Root Mean Square Error (RMSE) tells us that our model was able to forecast the average daily furniture sales in the test set within 67.06 of the real sales. In my opinion, this is a pretty good model so far.<jupyter_code>pred_uc = results.get_forecast(steps=100)
pred_ci = pred_uc.conf_int()

ax = y.plot(label='observed', figsize=(14, 7))
pred_uc.predicted_mean.plot(ax=ax, label='Forecast')
ax.fill_between(pred_ci.index,
                pred_ci.iloc[:, 0],
                pred_ci.iloc[:, 1], color='k', alpha=.25)
ax.set_xlabel('Date')
ax.set_ylabel('Hotel Sales')

plt.legend()
plt.show()
pred_uc
import pickle

with open('timeserieskaran','wb') as f:
    pickle.dump(mod,f)
#Advice to the  HigherManagement.




This hotel is definitely reaching new heights in the coming years. There is an upward trend in the sales. Ofcourse there is some seasonality involved but looking at the sales goin in positive direction.

The management should look into the fact that why sales are going down at the end of the year and also why there is a sudden drop in sales during mid year, right after summer I believe(July)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13012803762738437, 'fraction_numerical': 0.08309380715965509, 'mean_word_length': 4.1375838926174495, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '406372', 'license': 'Apache-2.0', 'n_tokens_mistral': 3187, 'n_tokens_neox': 2706, 'n_words': 793, 'path': 'TimeSeriesKaranTupe.ipynb', 'repo_name': 'ktupe/RewardsNetwork', 'size': '7658'}