!pip install --upgrade --force-reinstall --no-cache-dir numpy==1.23.5 pmdarima sktime tensorflow==2.12.0rc0 keras-tuner
import itertools
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import seasonal_decompose, STL
from statsmodels.stats.diagnostic import acorr_ljungbox
import statsmodels.graphics.api as smgraphics
from statsmodels.tsa.stattools import adfuller
from statsmodels.tsa.statespace.sarimax import SARIMAX
from scipy.stats import boxcox
from scipy.special import inv_boxcox
from pmdarima import auto_arima
import warnings
from sktime.forecasting.compose import (TransformedTargetForecaster, make_reduction)
from sktime.forecasting.model_selection import (ExpandingWindowSplitter, ForecastingGridSearchCV)
from sktime.performance_metrics.forecasting import MeanAbsolutePercentageError
from sktime.forecasting.trend import PolynomialTrendForecaster
from sktime.transformations.series.detrend import Deseasonalizer, Detrender
from sktime.forecasting.base import ForecastingHorizon
from xgboost import XGBRegressor
import numpy as np
import tensorflow as tf
from keras.models import Sequential
from keras.layers import Dense,LSTM, Dropout, InputLayer
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_absolute_percentage_error
from sklearn.preprocessing import MinMaxScaler
import keras_tuner as kt
from keras.regularizers import l1_l2
from keras.optimizers import Adam, SGD, RMSprop
from keras.callbacks import EarlyStopping
# Suppress specific warnings.
warnings.filterwarnings("ignore", category=FutureWarning)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', None)
isbn = pd.read_excel("/content/ISBN List.xlsx", sheet_name=None)
uk_weekly = pd.read_excel("/content/UK Weekly Trended Timeline from 200101_202429.xlsx", sheet_name=None)
isbn_Educational = pd.DataFrame(isbn["Y Childrens, YA & Educational"])
isbn_Trade = pd.DataFrame(isbn['T Adult Non-Fiction Trade'])
isbn_Specialist = pd.DataFrame(isbn['S Adult Non-Fiction Specialist'])
isbn_Fiction = pd.DataFrame(isbn['F - Adult Fiction'])
uk_weekly_Educational = pd.DataFrame(uk_weekly["Y Children's, YA & Educational"])
uk_weekly_Fiction = pd.DataFrame(uk_weekly['F Adult Fiction'])
uk_weekly_Trade = pd.DataFrame(uk_weekly['T Adult Non-Fiction Trade'])
uk_weekly_Specialist = pd.DataFrame(uk_weekly['S Adult Non-Fiction Specialist'])
isbn_names = {"isbn_Educational": isbn_Educational, "isbn_Trade": isbn_Trade, "isbn_Specialist": isbn_Specialist,
"isbn_Fiction": isbn_Fiction}
uk_weekly_name = {"uk_weekly_Educational":uk_weekly_Educational, "uk_weekly_Trade": uk_weekly_Trade,
"uk_weekly_Specialist": uk_weekly_Specialist,"uk_weekly_Fiction": uk_weekly_Fiction}
def explore(dataframe_name):
for i, data in dataframe_name.items():
print(f"{' '.join(i.split('_'))} have the follwing properties")
print("------------------------------------------------------------------------------------------")
print(f"Shape \n {data.shape}")
print("------------------------------------------------------------------------------------------")
print(data.info())
print("------------------------------------------------------------------------------------------")
print(data.describe())
print("******************************************************************************************")
explore(uk_weekly_name)
uk weekly Educational have the follwing properties ------------------------------------------------------------------------------------------ Shape (55286, 13) ------------------------------------------------------------------------------------------ <class 'pandas.core.frame.DataFrame'> RangeIndex: 55286 entries, 0 to 55285 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ISBN 55286 non-null int64 1 Title 55286 non-null object 2 Author 50113 non-null object 3 Interval 55286 non-null int64 4 End Date 55286 non-null datetime64[ns] 5 Volume 55286 non-null int64 6 Value 55286 non-null float64 7 ASP 55193 non-null float64 8 RRP 54856 non-null float64 9 Binding 55286 non-null object 10 Imprint 55286 non-null object 11 Publisher Group 55286 non-null object 12 Product Class 55286 non-null object dtypes: datetime64[ns](1), float64(3), int64(3), object(6) memory usage: 5.5+ MB None ------------------------------------------------------------------------------------------ ISBN Interval End Date \ count 5.528600e+04 55286.000000 55286 mean 9.780811e+12 200744.123720 2007-09-04 13:22:46.523170304 min 9.780002e+12 200101.000000 2001-01-06 00:00:00 25% 9.780441e+12 200318.000000 2003-05-03 00:00:00 50% 9.780721e+12 200601.000000 2006-01-07 00:00:00 75% 9.780753e+12 201023.000000 2010-06-05 00:00:00 max 9.781904e+12 202429.000000 2024-07-20 00:00:00 std 5.779893e+08 561.901387 NaN Volume Value ASP RRP count 55286.000000 55286.000000 55193.000000 54856.000000 mean 530.412564 2743.474619 5.556607 6.921442 min -269.000000 -1348.460000 -11.010000 0.100000 25% 18.000000 90.835000 4.406400 4.990000 50% 151.000000 784.520000 4.962700 6.500000 75% 493.000000 2435.630000 5.990000 7.990000 max 193645.000000 483767.750000 40.000000 25.000000 std 2314.946914 10668.029749 2.709133 3.219413 ****************************************************************************************** uk weekly Trade have the follwing properties ------------------------------------------------------------------------------------------ Shape (65344, 13) ------------------------------------------------------------------------------------------ <class 'pandas.core.frame.DataFrame'> RangeIndex: 65344 entries, 0 to 65343 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ISBN 65344 non-null int64 1 Title 65344 non-null object 2 Author 60655 non-null object 3 Interval 65344 non-null int64 4 End Date 65344 non-null datetime64[ns] 5 Volume 65344 non-null int64 6 Value 65344 non-null float64 7 ASP 65274 non-null float64 8 RRP 65210 non-null float64 9 Binding 65344 non-null object 10 Imprint 65344 non-null object 11 Publisher Group 65344 non-null object 12 Product Class 65344 non-null object dtypes: datetime64[ns](1), float64(3), int64(3), object(6) memory usage: 6.5+ MB None ------------------------------------------------------------------------------------------ ISBN Interval End Date \ count 6.534400e+04 65344.000000 65344 mean 9.780467e+12 200884.679603 2009-01-30 21:32:22.360430848 min 9.780003e+12 200101.000000 2001-01-06 00:00:00 25% 9.780140e+12 200347.000000 2003-11-22 00:00:00 50% 9.780416e+12 200731.000000 2007-08-04 00:00:00 75% 9.780718e+12 201317.000000 2013-04-27 00:00:00 max 9.781904e+12 202429.000000 2024-07-20 00:00:00 std 3.994394e+08 611.839318 NaN Volume Value ASP RRP count 65344.000000 6.534400e+04 65274.000000 65210.000000 mean 376.208849 3.081678e+03 9.206646 12.781906 min -74.000000 -4.372600e+02 -77.460000 1.000000 25% 7.000000 5.921750e+01 6.767075 8.990000 50% 38.000000 3.285200e+02 7.986300 10.990000 75% 239.000000 1.902920e+03 10.470900 15.990000 max 80620.000000 1.056257e+06 32.010000 30.000000 std 1591.597425 1.664461e+04 4.683351 6.206623 ****************************************************************************************** uk weekly Specialist have the follwing properties ------------------------------------------------------------------------------------------ Shape (32827, 13) ------------------------------------------------------------------------------------------ <class 'pandas.core.frame.DataFrame'> RangeIndex: 32827 entries, 0 to 32826 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ISBN 32827 non-null int64 1 Title 32827 non-null object 2 Author 28077 non-null object 3 Interval 32827 non-null int64 4 End Date 32827 non-null datetime64[ns] 5 Volume 32827 non-null int64 6 Value 32827 non-null float64 7 ASP 32731 non-null float64 8 RRP 27429 non-null float64 9 Binding 32827 non-null object 10 Imprint 32827 non-null object 11 Publisher Group 32827 non-null object 12 Product Class 32827 non-null object dtypes: datetime64[ns](1), float64(3), int64(3), object(6) memory usage: 3.3+ MB None ------------------------------------------------------------------------------------------ ISBN Interval End Date \ count 3.282700e+04 32827.000000 32827 mean 9.780743e+12 200450.247479 2004-09-24 01:00:03.180308864 min 9.780003e+12 200101.000000 2001-01-06 00:00:00 25% 9.780341e+12 200218.000000 2002-05-04 00:00:00 50% 9.780672e+12 200340.000000 2003-10-04 00:00:00 75% 9.780765e+12 200602.000000 2006-01-14 00:00:00 max 9.781904e+12 202429.000000 2024-07-20 00:00:00 std 5.613454e+08 342.780391 NaN Volume Value ASP RRP count 32827.000000 32827.000000 32731.000000 27429.000000 mean 87.351296 1176.246431 13.479478 16.302991 min -86.000000 -863.620000 -5.765000 2.950000 25% 5.000000 49.545000 8.429300 9.990000 50% 41.000000 456.540000 12.020600 12.990000 75% 114.000000 1451.050000 17.132050 19.950000 max 4378.000000 39125.560000 46.690000 69.990000 std 143.989186 2137.410382 7.445967 10.155029 ****************************************************************************************** uk weekly Fiction have the follwing properties ------------------------------------------------------------------------------------------ Shape (73767, 13) ------------------------------------------------------------------------------------------ <class 'pandas.core.frame.DataFrame'> RangeIndex: 73767 entries, 0 to 73766 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ISBN 73767 non-null int64 1 Title 73767 non-null object 2 Author 73500 non-null object 3 Interval 73767 non-null int64 4 End Date 73767 non-null datetime64[ns] 5 Volume 73767 non-null int64 6 Value 73767 non-null float64 7 ASP 73683 non-null float64 8 RRP 73767 non-null float64 9 Binding 73767 non-null object 10 Imprint 73767 non-null object 11 Publisher Group 73767 non-null object 12 Product Class 73767 non-null object dtypes: datetime64[ns](1), float64(3), int64(3), object(6) memory usage: 7.3+ MB None ------------------------------------------------------------------------------------------ ISBN Interval End Date \ count 7.376700e+04 73767.000000 73767 mean 9.780393e+12 200877.213347 2009-01-03 22:50:01.049249536 min 9.780002e+12 200101.000000 2001-01-06 00:00:00 25% 9.780140e+12 200410.000000 2004-03-06 00:00:00 50% 9.780341e+12 200735.000000 2007-09-01 00:00:00 75% 9.780554e+12 201229.000000 2012-07-21 00:00:00 max 9.781860e+12 202429.000000 2024-07-20 00:00:00 std 3.179225e+08 592.264956 NaN Volume Value ASP RRP count 73767.000000 73767.000000 73683.000000 73767.000000 mean 381.227473 2448.109140 7.157384 9.566535 min -20.000000 -96.420000 -4.010000 2.500000 25% 9.000000 62.270000 6.200400 7.990000 50% 55.000000 383.900000 6.892600 8.990000 75% 192.000000 1331.300000 7.730400 9.990000 max 51175.000000 385543.990000 60.000000 25.000000 std 1541.015144 9746.887969 2.323545 3.012778 ******************************************************************************************
def initial_processing(dataframe_name):
for i, data in dataframe_name.items():
data.set_index("End Date", inplace = True)
data.sort_index(inplace = True)
data["ISBN"] = data["ISBN"].astype("str")
data.resample("W").sum().fillna(0, inplace = True)
initial_processing(uk_weekly_name)
def plot_isbn(dataframe_name):
data2024_07_01 = {}
unique_after2024_07_01 = []
cutoff = pd.Timestamp('2024-07-01')
for i, data in dataframe_name.items():
for isbncutoff in data[data.index > cutoff]["ISBN"].unique():
unique_after2024_07_01.append(isbncutoff)
plt.figure(figsize=(12,8))
plt.plot(data[data["ISBN"] == isbncutoff]["Volume"])
plt.title(f"Sales Volume Over Time for ISBN {isbncutoff}")
plt.xlabel("Sales Date")
plt.ylabel("Volume")
plt.show()
print(unique_after2024_07_01)
plot_isbn(uk_weekly_name)
['9781841462400', '9780006647553', '9780440864141', '9780241003008', '9781841460406', '9780744523232', '9781841462301', '9780440864554', '9781841461502', '9780752844299', '9781841460307', '9781841462509', '9780752846576', '9780099422587', '9780340696767', '9780099285823', '9780552145954', '9780552997034', '9780593048153', '9780140275421', '9780091816971', '9781841150437', '9780006531203', '9780140281293', '9780091867775', '9780749395698', '9780140259506', '9780719559792', '9780140276619', '9780340766057', '9780099286578', '9780099428558', '9780140294231', '9780224060875', '9780330355667', '9780340786055', '9780099286387', '9780552998482', '9780261103252', '9780099771517', '9780349114033', '9780552998727', '9780552997348', '9780006514213', '9780140276336', '9780140285215', '9780552998000', '9780747268161', '9780140295962', '9780552998444', '9780349113609', '9780349112763', '9780099244721', '9780749397548', '9780006512134', '9780722532935', '9780006514091', '9780007101887', '9780552145060', '9780006550433', '9780552145053']
books = ["very hungry caterpillar", "alchemist"]
def filter_books(isbn_books, weekly_sales, books):
lookedup_isbn = {}
for i in books:
for (key1, data1), (key2, data2) in zip(isbn_books.items(), weekly_sales.items()):
data1["ISBN"] = data1["ISBN"].astype("str")
result = data1[data1["Title"].str.lower().str.contains(i)]["ISBN"]
if not result.empty:
data2_result = data2[data2["ISBN"].isin(list(result))]
data2_result.index = data2_result.index + pd.Timedelta(days=1)
lookedup_isbn[i.split()[-1]] = data2_result.groupby(data2_result.index).sum().asfreq('W').fillna(0)["Volume"]
return lookedup_isbn
selected_books = filter_books(isbn_names, uk_weekly_name, books)
Category | Rows | Columns |
---|---|---|
Educational | 55,286 | 13 |
Trade | 65,344 | 13 |
Specialist | 32,827 | 13 |
Fiction | 73,767 | 13 |
Column | Educational | Trade | Specialist | Fiction |
---|---|---|---|---|
Author | 5,173 | 4,689 | 4,750 | 267 |
ASP | 93 | 70 | 96 | 84 |
RRP | 430 | 134 | 5,398 | 0 |
Metric | Educational | Trade | Specialist | Fiction |
---|---|---|---|---|
Volume | 530 | 376 | 87 | 381 |
Value (£) | 2,743 | 3,082 | 1,176 | 2,448 |
ASP (£) | 5.56 | 9.21 | 13.48 | 7.16 |
RRP (£) | 6.92 | 12.78 | 16.30 | 9.57 |
2001-01-06
to 2024-07-20
Volume
and End Date
, used as the time series index for analysis.End Date
has been set as the index and resampled to weekly intervals.alchemist = pd.DataFrame(selected_books['alchemist'])
caterpillar = pd.DataFrame(selected_books['caterpillar'])
print(type(alchemist["Volume"].index))
print(alchemist.index.freq)
print(alchemist.index.inferred_freq)
<class 'pandas.core.indexes.datetimes.DatetimeIndex'> <Week: weekday=6> W-SUN
cutoff = pd.Timestamp('2012-01-01')
alchemist_cutoff = alchemist[alchemist.index > cutoff]
caterpillar_cutoff = caterpillar[caterpillar.index > cutoff]
two_books = {"The Alchemist": alchemist_cutoff, "The Very Hungry Caterpillar": caterpillar_cutoff}
explore(two_books)
The Alchemist have the follwing properties ------------------------------------------------------------------------------------------ Shape (655, 1) ------------------------------------------------------------------------------------------ <class 'pandas.core.frame.DataFrame'> DatetimeIndex: 655 entries, 2012-01-08 to 2024-07-21 Freq: W-SUN Data columns (total 1 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Volume 655 non-null float64 dtypes: float64(1) memory usage: 10.2 KB None ------------------------------------------------------------------------------------------ Volume count 655.000000 mean 528.102290 std 227.965588 min 0.000000 25% 415.500000 50% 508.000000 75% 606.000000 max 2201.000000 ****************************************************************************************** The Very Hungry Caterpillar have the follwing properties ------------------------------------------------------------------------------------------ Shape (655, 1) ------------------------------------------------------------------------------------------ <class 'pandas.core.frame.DataFrame'> DatetimeIndex: 655 entries, 2012-01-08 to 2024-07-21 Freq: W-SUN Data columns (total 1 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Volume 655 non-null float64 dtypes: float64(1) memory usage: 10.2 KB None ------------------------------------------------------------------------------------------ Volume count 655.000000 mean 1348.909924 std 710.689315 min 0.000000 25% 723.000000 50% 1324.000000 75% 1758.500000 max 3905.000000 ******************************************************************************************
plt.figure(figsize=(15,8))
alchemist_cutoff["Volume"].plot(label='Alchemist')
caterpillar_cutoff["Volume"].plot(label='Caterpillar')
plt.title('Sales Volume for both Alchemist and Caterpillar')
plt.xlabel('Date')
plt.ylabel('Volume')
plt.legend()
plt.show()
def decomposition(data, pd):
data_stl = STL(data , period=pd)
data_fit = data_stl.fit()
residual = data_fit.resid
#data_fit.plot();
print('Ljung-Box test output\n', acorr_ljungbox(residual), '...\n')
return residual
print("Decomposition for The Very Hungry Caterpillar")
residual_cat = decomposition(caterpillar_cutoff, 52)
print("\n Decomposition for The Alchemist")
residual_alch = decomposition(alchemist_cutoff, 52)
Decomposition for The Very Hungry Caterpillar Ljung-Box test output lb_stat lb_pvalue 1 370.471831 1.477278e-82 2 563.416272 4.525964e-123 3 655.510867 9.300685e-142 4 703.722530 5.447512e-151 5 735.165914 1.221569e-156 6 745.231614 1.044323e-157 7 746.925241 5.238363e-157 8 747.070784 5.223687e-156 9 747.322418 4.603664e-155 10 752.384656 3.530257e-155 ... Decomposition for The Alchemist Ljung-Box test output lb_stat lb_pvalue 1 322.397402 4.352123e-72 2 493.431912 7.122324e-108 3 598.685446 1.942542e-129 4 669.332329 1.521385e-143 5 712.116376 1.178602e-151 6 735.396404 1.390001e-155 7 743.813088 2.457366e-156 8 745.613803 1.076019e-155 9 748.310139 2.822442e-155 10 763.421832 1.500879e-157 ...
def acf_pacf_plot(data):
smgraphics.tsa.plot_acf(data, lags=52);
smgraphics.tsa.plot_pacf(data, lags=52);
print("ACF and PACF Plot for The Very Hungry Caterpillar using Decomposition Residual")
acf_pacf_plot(residual_cat)
plt.show()
print("\n ACF and PACF Plot for The Alchemist using Decomposition Residual")
acf_pacf_plot(residual_alch)
plt.show()
ACF and PACF Plot for The Very Hungry Caterpillar using Decomposition Residual
ACF and PACF Plot for The Alchemist using Decomposition Residual
print("ACF and PACF Plot for The Very Hungry Caterpillar using Volume")
acf_pacf_plot(caterpillar_cutoff)
plt.show()
print("\n ACF and PACF Plot for The Alchemist using Volume")
acf_pacf_plot(alchemist_cutoff)
plt.show()
ACF and PACF Plot for The Very Hungry Caterpillar using Volume
ACF and PACF Plot for The Alchemist using Volume
def stationarity(data):
p_value = 0.05
adf_result = adfuller(data['Volume'])
if adf_result[1] < p_value:
print("The Data in it's original form is stationary it has a p-value of:", adf_result[1])
else:
seasonal_diff = data['Volume'].diff(1).dropna()
adf_result_seasonal_diff = adfuller(seasonal_diff)
if adf_result_seasonal_diff[1] < p_value:
print('The data after difference is now stationary with a p-value of:', adf_result_seasonal_diff[1])
else:
print("The data is still not stationary, it has a p-value of:", adf_result_seasonal_diff[1])
print("Stationarity testing for The Very Hungry Caterpillar")
stationarity(caterpillar_cutoff)
print("\n Stationarity testing for The Alchemist")
stationarity(alchemist_cutoff)
Stationarity testing for The Very Hungry Caterpillar The Data in it's original form is stationary it has a p-value of: 0.029614783911209044 Stationarity testing for The Alchemist The Data in it's original form is stationary it has a p-value of: 4.139950997174928e-13
val_size = 32
def plot_arima(val_df, forecast):
forecast_index = val_df.index
forecast_series = pd.Series(forecast, index=forecast_index)
plt.figure(figsize=(15, 8))
ax = plt.gca()
val_df.plot(ax=ax, color='green', label='Validation (Actual)')
forecast_series.plot(ax=ax, color='red', label='Forecast')
plt.title(' Validation, and Forecast')
plt.xlabel('Date')
plt.ylabel('Value')
plt.legend()
print(f'MAE for the next 32 weeks forcast is, {mean_absolute_error(val_df["Volume"], forecast)}')
print(f'MAPE for the next 32 forcast is, {mean_absolute_percentage_error(val_df["Volume"], forecast)}')
plt.show()
def auto(data, m , size):
train_df, val_df = data.iloc[:-size], data.iloc[-size:]
model = auto_arima(train_df, seasonal=True, m=m, stationary=False, trace=False, error_action='ignore', suppress_warnings=True, information_criterion='aic',
scoring='mse', stepwise=True)
print(model.summary())
forecast, conf_int = model.predict(size, return_conf_int=True, alpha=0.05)
fitted = model.predict_in_sample()
plot_arima(val_df, forecast)
auto(alchemist_cutoff, 52, val_size)
SARIMAX Results =========================================================================================== Dep. Variable: y No. Observations: 623 Model: SARIMAX(1, 1, 2)x(2, 0, [], 52) Log Likelihood -3804.646 Date: Tue, 27 May 2025 AIC 7623.292 Time: 13:33:31 BIC 7654.322 Sample: 01-08-2012 HQIC 7635.352 - 12-10-2023 Covariance Type: opg ============================================================================== coef std err z P>|z| [0.025 0.975] ------------------------------------------------------------------------------ intercept -0.0154 0.163 -0.095 0.925 -0.334 0.304 ar.L1 0.7663 0.052 14.793 0.000 0.665 0.868 ma.L1 -1.0745 0.058 -18.422 0.000 -1.189 -0.960 ma.L2 0.1201 0.045 2.678 0.007 0.032 0.208 ar.S.L52 0.4296 0.026 16.401 0.000 0.378 0.481 ar.S.L104 0.2961 0.026 11.497 0.000 0.246 0.347 sigma2 1.139e+04 360.075 31.619 0.000 1.07e+04 1.21e+04 =================================================================================== Ljung-Box (L1) (Q): 0.04 Jarque-Bera (JB): 1329.94 Prob(Q): 0.84 Prob(JB): 0.00 Heteroskedasticity (H): 2.95 Skew: 0.54 Prob(H) (two-sided): 0.00 Kurtosis: 10.08 =================================================================================== Warnings: [1] Covariance matrix calculated using the outer product of gradients (complex-step). MAE for the next 32 weeks forcast is, 155.07091806095434 MAPE for the next 32 forcast is, 0.2975146917185349
auto(caterpillar_cutoff, 52, val_size)
SARIMAX Results =============================================================================================== Dep. Variable: y No. Observations: 623 Model: SARIMAX(2, 1, 1)x(1, 0, [1, 2], 52) Log Likelihood -4482.088 Date: Tue, 27 May 2025 AIC 8978.177 Time: 14:49:20 BIC 9009.207 Sample: 01-08-2012 HQIC 8990.237 - 12-10-2023 Covariance Type: opg ============================================================================== coef std err z P>|z| [0.025 0.975] ------------------------------------------------------------------------------ ar.L1 0.8131 0.034 23.604 0.000 0.746 0.881 ar.L2 -0.0665 0.032 -2.052 0.040 -0.130 -0.003 ma.L1 -0.9646 0.013 -74.651 0.000 -0.990 -0.939 ar.S.L52 0.6274 0.086 7.312 0.000 0.459 0.796 ma.S.L52 -0.3466 0.089 -3.884 0.000 -0.521 -0.172 ma.S.L104 0.1031 0.051 2.018 0.044 0.003 0.203 sigma2 1.041e+05 3031.737 34.324 0.000 9.81e+04 1.1e+05 =================================================================================== Ljung-Box (L1) (Q): 0.01 Jarque-Bera (JB): 5951.93 Prob(Q): 0.94 Prob(JB): 0.00 Heteroskedasticity (H): 5.46 Skew: 0.91 Prob(H) (two-sided): 0.00 Kurtosis: 18.05 =================================================================================== Warnings: [1] Covariance matrix calculated using the outer product of gradients (complex-step). MAE for the next 32 weeks forcast is, 353.1408830193634 MAPE for the next 32 forcast is, 0.1863215351859458
period = 52
.Book | MAE | MAPE |
---|---|---|
The Alchemist | 155 | 30% |
The Very Hungry Caterpillar | 353 | 19% |
def meachine_learning_xgboost(sp=52, degree=1):
regressor = XGBRegressor(base_score=0.5,
n_estimators=400,
min_child_weight=1,
max_depth=10,
learning_rate=0.1,
booster='gbtree',
tree_method='exact',
reg_alpha=0,
subsample=0.5,
validate_parameters=1,
colsample_bylevel=1,
colsample_bynode=1,
colsample_bytree=1,
gamma=0,
eval_metric="mae",
)
forecaster = TransformedTargetForecaster(
[
("deseasonalize", Deseasonalizer(model="additive", sp=sp)),
("detrend", Detrender(forecaster=PolynomialTrendForecaster(degree=degree))),
(
"forecast",
make_reduction(regressor, window_length=52, strategy="recursive"),
),
]
)
return forecaster
def grid_search_predictor(train, test1, predictor, param_grid):
cv = ExpandingWindowSplitter(initial_window=int(len(train) * 0.7))
gscv = ForecastingGridSearchCV(
predictor, strategy="refit", cv=cv, param_grid=param_grid,
scoring=MeanAbsolutePercentageError(symmetric=True),
error_score="raise"
)
future_horizon = np.arange(len(test1)) + 1
gscv.fit(train)
print(f"Best parameters: {gscv.best_params_}")
predictions1 = gscv.predict(fh=future_horizon)
return predictions1
param_grid = {"forecast__window_length": [26, 52, 60, 78],
"forecast__estimator__max_depth": [3, 5, 10, 15]}
def plot_prediction(test1, forcast1):
plt.figure(figsize=(15,8))
#train.plot(c="blue")
test1.plot(c ="green")
forcast1.plot(c = "red")
print(f"MAE for the next 32 weeks forcast is, {mean_absolute_error(test1, forcast1)}")
print(f"MAPE for the next 32 forcast is, {mean_absolute_percentage_error(test1, forcast1)}")
print("***********************************************************************************")
predictor = meachine_learning_xgboost(degree=5)
alchemist_train, alchemist_test = alchemist[:-val_size], alchemist[-val_size:]
alchemist_train.index = pd.PeriodIndex(alchemist_train.index, freq='W')
alchemist_test.index = pd.PeriodIndex(alchemist_test.index, freq='W')
predictions1= grid_search_predictor( (alchemist_train["Volume"]), (alchemist_test["Volume"]),
predictor, param_grid)
Best parameters: {'forecast__estimator__max_depth': 5, 'forecast__window_length': 78}
plot_prediction((alchemist_test["Volume"]), predictions1 )
MAE for the next 32 weeks forcast is, 404.6617338888266 MAPE for the next 32 forcast is, 0.8247771223330276 ***********************************************************************************
predictor2 = meachine_learning_xgboost(degree=5)
caterpillar_train, caterpillar_test = caterpillar[:-val_size], caterpillar[-val_size:]
caterpillar_train.index = pd.PeriodIndex(caterpillar_train.index, freq='W')
caterpillar_test.index = pd.PeriodIndex(caterpillar_test.index, freq='W')
predictions1 = grid_search_predictor(caterpillar_train["Volume"], caterpillar_test["Volume"],
predictor2, param_grid)
Best parameters: {'forecast__estimator__max_depth': 15, 'forecast__window_length': 52}
plot_prediction(caterpillar_test["Volume"], predictions1)
MAE for the next 32 weeks forcast is, 387.05080382864935 MAPE for the next 32 forcast is, 0.1951807988572985 ***********************************************************************************
lookback = 52
forecast = 32
def input_output1(data, lookback, forecast):
input_seq = []
output_seq = []
for i in range(len(data) - lookback - forecast + 1):
input_seq.append(data[i:i + lookback])
output_seq.append(data[i + lookback:i + lookback + forecast])
return np.array(input_seq), np.array(output_seq)
alchemist_scaler = MinMaxScaler(feature_range=(0,1))
alchemist_transform = alchemist_scaler.fit_transform(alchemist)
caterpillar_scaler = MinMaxScaler(feature_range=(0,1))
caterpillar_transform = caterpillar_scaler.fit_transform(caterpillar)
alchemist_input_seq, alchemist_output_seq = input_output1(alchemist_transform, lookback, forecast)
caterpillar_input_seq, caterpillar_output_seq = input_output1(caterpillar_transform, lookback, forecast)
def lstm_timeseries(hp, lookback, forecast):
model = Sequential()
model.add(InputLayer(input_shape=(lookback, 1)))
num_layers = hp.Int("num_layers", min_value = 1, max_value =4, step = 1)
units = hp.Int("units", min_value = 32, max_value = 128, step = 32)
activation = hp.Choice("activation", values = ["relu", "tanh", "swish"])
dropout_rate = hp.Float("dropout_rate", min_value = 0.1, max_value = 0.5, step = 0.1)
reg = hp.Float('reg', min_value=1e-4, max_value=1e-2, sampling='log')
optimizer_choice = hp.Choice("optimizer_choice", values = ["adam", "sgd", "rmsprop"])
optimizer = {
"adam": Adam(),
"sgd": SGD(),
"rmsprop": RMSprop()
}[optimizer_choice]
for i in range(num_layers):
return_seq = True if i < num_layers - 1 else False
model.add(LSTM(units= units, activation = activation, kernel_regularizer= l1_l2(reg), return_sequences = return_seq))
model.add(Dropout(dropout_rate))
model.add(Dense(forecast))
model.compile(loss='mean_absolute_error', optimizer=optimizer, metrics= ["mae"])
return model
def search_best_model(input_train, output_train, project_name):
train_size = int(len(input_train)* 0.8)
x_train, x_val = input_train[:train_size], input_train[train_size:]
y_train, y_val = output_train[:train_size], output_train[train_size:]
tuner = kt.RandomSearch(lambda hp: lstm_timeseries(hp, lookback, forecast),
objective = "val_loss",
max_trials=10,
executions_per_trial=1,
directory='dir',
project_name= project_name)
early_stop = EarlyStopping(monitor="val_loss", patience=5, restore_best_weights=True)
tuner.search(x_train, y_train, epochs=200, batch_size=32, validation_data=(x_val, y_val), callbacks=[early_stop], verbose=1)
best_model = tuner.get_best_models(num_models=1)[0]
return best_model
def plot_lstm_result(actual, result):
plt.figure(figsize=(12,8))
plt.plot(actual, label='Actual', c = "green")
plt.plot(result, label='Predicted', c = "red")
print(f"MAE for the next 32 weeks forcast is, {mean_absolute_error(actual, result)}")
print(f"MAPE for the next 32 forcast is, {mean_absolute_percentage_error(actual, result)}")
plt.show()
predict_alchemist_next32 = alchemist_transform[- lookback:]
predict_alchemist_next32 = predict_alchemist_next32.reshape(1, lookback, 1)
alchemist_model = search_best_model(alchemist_input_seq, alchemist_output_seq, "model_a")
prediction_result = alchemist_model.predict(predict_alchemist_next32)
prediction_result = alchemist_scaler.inverse_transform(prediction_result)
Trial 10 Complete [00h 02m 34s] val_loss: 0.03139953687787056 Best val_loss So Far: 0.028060106560587883 Total elapsed time: 00h 23m 27s 1/1 [==============================] - 0s 247ms/step
alchemist_prediction = pd.DataFrame({"Date": alchemist[- val_size:].index, "Volume": prediction_result.flatten()})
alchemist_prediction.set_index("Date", inplace = True)
plot_lstm_result(alchemist[- val_size:], alchemist_prediction)
MAE for the next 32 weeks forcast is, 206.83562850952148 MAPE for the next 32 forcast is, 0.3541896030075633
predict_caterpillar_next32 = caterpillar_transform[- lookback:]
predict_caterpillar_next32 = predict_caterpillar_next32.reshape(1, lookback, 1)
caterpillar_model = search_best_model(caterpillar_input_seq, caterpillar_output_seq, "model_b")
caterpillar_prediction_result = caterpillar_model.predict(predict_caterpillar_next32)
caterpillar_prediction_result = caterpillar_scaler.inverse_transform(caterpillar_prediction_result)
Trial 10 Complete [00h 18m 23s] val_loss: 0.6193820238113403 Best val_loss So Far: 0.10460196435451508 Total elapsed time: 00h 54m 04s 1/1 [==============================] - 0s 366ms/step
caterpillar_prediction = pd.DataFrame({"Date": caterpillar[- val_size:].index, "Volume": caterpillar_prediction_result.flatten()})
caterpillar_prediction.set_index("Date", inplace = True)
plot_lstm_result(caterpillar[- val_size:], caterpillar_prediction)
MAE for the next 32 weeks forcast is, 504.5280418395996 MAPE for the next 32 forcast is, 0.24724440109298584
Book | LSTM MAE | LSTM MAPE | XGBoost MAE | XGBoost MAPE |
---|---|---|---|---|
The Alchemist | 196 | 29% | 404 | 83% |
The Very Hungry Caterpillar | 574 | 26% | 387 | 20% |
def hybrid_sarima(data, p, d, q, P, D, Q, S):
model_sarima = SARIMAX(endog= data, order=(p, d, q), seasonal_order=(P, D, Q, S))
model_sarima_fit = model_sarima.fit(maxiter=500, disp=False)
print(model_sarima_fit)
return model_sarima_fit
hybrid_alchemist_train, hybrid_alchemist_test = alchemist[:-val_size], alchemist[-val_size:]
hybrid_caterpillar_train, hybrid_caterpillar_test = caterpillar[:-val_size], caterpillar[-val_size:]
sarima_alchemist_model = hybrid_sarima(hybrid_alchemist_train, 1, 1, 2, 2, 0, 0, 52)
sarima_caterpillar_model = hybrid_sarima(hybrid_caterpillar_train, 2, 1, 1, 1, 0, [1, 2], 52)
<statsmodels.tsa.statespace.sarimax.SARIMAXResultsWrapper object at 0x7db15d627b50>
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters. warn('Non-stationary starting autoregressive parameters' /usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters. warn('Non-invertible starting MA parameters found.'
<statsmodels.tsa.statespace.sarimax.SARIMAXResultsWrapper object at 0x7db15d653a10>
hybrid_alchemist_scaler = MinMaxScaler(feature_range=(0,1))
hybrid_alchemist_scaled = hybrid_alchemist_scaler.fit_transform (pd.DataFrame(sarima_alchemist_model.resid))
hybrid_caterpillar_scaler = MinMaxScaler(feature_range=(0,1))
hybrid_caterpillar_scaled = hybrid_caterpillar_scaler.fit_transform(pd.DataFrame(sarima_caterpillar_model.resid))
hybrid_alchemist_input, hybrid_alchemist_output = input_output1(hybrid_alchemist_scaled, lookback, forecast)
hybrid_caterpillar_input, hybrid_caterpillar_output = input_output1(hybrid_caterpillar_scaled, lookback, forecast)
lstm_alchemist_model = search_best_model(hybrid_alchemist_input, hybrid_alchemist_output, "model_c")
lstm_caterpillar_model = search_best_model(hybrid_caterpillar_input, hybrid_caterpillar_output, "model_d")
Trial 10 Complete [00h 08m 50s] val_loss: 0.28357160091400146 Best val_loss So Far: 0.05631991848349571 Total elapsed time: 00h 36m 42s
sarima_hybrid_result_alchemist = sarima_alchemist_model.get_forecast(len(hybrid_alchemist_test)).predicted_mean
sarima_hybrid_result_caterpillar = sarima_caterpillar_model.get_forecast(len(hybrid_caterpillar_test)).predicted_mean
lstm_hybrid_result_alchemist = hybrid_alchemist_scaler.inverse_transform(lstm_alchemist_model.predict(hybrid_alchemist_scaled[-lookback:].reshape(1, lookback, 1)))
lstm_hybrid_result_caterpillar = hybrid_alchemist_scaler.inverse_transform(lstm_caterpillar_model.predict(hybrid_caterpillar_scaled[-lookback:].reshape(1,lookback,1)))
1/1 [==============================] - 0s 186ms/step 1/1 [==============================] - 0s 467ms/step
alchemist_hybrid_df = pd.DataFrame({"Original Volume": hybrid_alchemist_test['Volume'], "LSTM + SARIMAX": lstm_hybrid_result_alchemist.flatten() + sarima_hybrid_result_alchemist,
"LSTM": lstm_hybrid_result_alchemist.flatten(), "SARIMAX": sarima_hybrid_result_alchemist})
plot_lstm_result(alchemist_hybrid_df['Original Volume'], alchemist_hybrid_df['LSTM + SARIMAX'])
MAE for the next 32 weeks forcast is, 172.478822418803 MAPE for the next 32 forcast is, 0.3191276734873695
caterpillar_hybrid_df = pd.DataFrame({"Original Volume": hybrid_caterpillar_test['Volume'], "LSTM + SARIMAX": lstm_hybrid_result_caterpillar.flatten() + sarima_hybrid_result_caterpillar,
"LSTM": lstm_hybrid_result_caterpillar.flatten(), "SARIMAX": sarima_hybrid_result_caterpillar})
plot_lstm_result(caterpillar_hybrid_df['Original Volume'], caterpillar_hybrid_df['LSTM + SARIMAX'])
MAE for the next 32 weeks forcast is, 517.1055934317556 MAPE for the next 32 forcast is, 0.3004058804758878
percentage = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
pairings = list(itertools.product(percentage, repeat = 2))
parallel_alchemist = pd.DataFrame({"SARIMA": pd.DataFrame(sarima_hybrid_result_alchemist)["predicted_mean"],
"LSTM": alchemist_prediction['Volume']})
parallel_caterpillar = pd.DataFrame({"SARIMA": pd.DataFrame(sarima_hybrid_result_caterpillar)["predicted_mean"],
"LSTM": caterpillar_prediction['Volume']})
def best_weightage(sarima_prediction, lstm_prediction, actual):
parallel_best = []
mape = 100
for pair in pairings:
combined = ((pair[0]* sarima_prediction) + (pair[1]* lstm_prediction))
if mean_absolute_percentage_error(actual, combined) < mape:
mape = mean_absolute_percentage_error(actual, combined)
parallel_best = pair
combined_best = ((parallel_best[0]* sarima_prediction) + (parallel_best[1]* lstm_prediction))
return parallel_best, combined_best
alchemist_best_weightage, parallel_alchemist_combined = best_weightage(parallel_alchemist["SARIMA"], parallel_alchemist["LSTM"], alchemist[- val_size:]["Volume"])
caterpillar_best_weightage, parallel_caterpillar_combined = best_weightage(parallel_caterpillar["SARIMA"], parallel_caterpillar["LSTM"], caterpillar[- val_size:]["Volume"])
plot_lstm_result(alchemist[- val_size:]["Volume"], parallel_alchemist_combined)
MAE for the next 32 weeks forcast is, 188.80709457312167 MAPE for the next 32 forcast is, 0.248985302918793
plot_lstm_result(caterpillar[- val_size:]["Volume"], parallel_caterpillar_combined)
MAE for the next 32 weeks forcast is, 346.18424311371456 MAPE for the next 32 forcast is, 0.17325468482225337
Book | Sequential MAE | Sequential MAPE | Parallel MAE | Parallel MAPE |
---|---|---|---|---|
The Alchemist | 172 | 32% | 118 | 24% |
The Very Hungry Caterpillar | 517 | 30% | 346 | 17% |
monthly = 12
next_8months = 8
monthly_alchemist_df = alchemist.resample("M").sum()
monthly_caterpillar_df = caterpillar.resample("M").sum()
plt.figure(figsize=(15,8))
plt.plot(monthly_alchemist_df[monthly_alchemist_df.index > pd.Timestamp("2019-01-01")])
plt.plot(monthly_caterpillar_df[monthly_caterpillar_df.index > pd.Timestamp("2019-01-01")])
[<matplotlib.lines.Line2D at 0x7db016b5b090>]
print(monthly_alchemist_df.index.freq)
print(monthly_alchemist_df.index.inferred_freq)
<MonthEnd> ME
monthly_param_grid = {"forecast__window_length": [3, 6, 12, 24, 48, 60, 96],
"forecast__estimator__max_depth": [3, 5, 10, 15]}
monthly_predictor = meachine_learning_xgboost(sp = monthly, degree=5)
alchemist_monthly_train, alchemist_monthly_test, = monthly_alchemist_df[:- next_8months], monthly_alchemist_df[-next_8months:]
alchemist_monthly_train.index = pd.PeriodIndex(alchemist_monthly_train.index, freq='M')
alchemist_monthly_test.index = pd.PeriodIndex(alchemist_monthly_test.index, freq='M')
predictions1= grid_search_predictor(
(alchemist_monthly_train["Volume"]), (alchemist_monthly_test["Volume"]), monthly_predictor, monthly_param_grid)
Best parameters: {'forecast__estimator__max_depth': 3, 'forecast__window_length': 60}
alchemist_monthly_test.index = alchemist_monthly_test.index.to_timestamp(freq='M')
plot_lstm_result(alchemist_monthly_test["Volume"], predictions1)
MAE for the next 32 weeks forcast is, 699.7449794132554 MAPE for the next 32 forcast is, 0.34185199931935517
monthly_predictor2 = meachine_learning_xgboost(sp = monthly, degree=5)
caterpillar_monthly_train, caterpillar_monthly_test, = monthly_caterpillar_df[:- next_8months], monthly_caterpillar_df[-next_8months:]
caterpillar_monthly_train.index = pd.PeriodIndex(caterpillar_monthly_train.index, freq='M')
caterpillar_monthly_test.index = pd.PeriodIndex(caterpillar_monthly_test.index, freq='M')
predictions3 = grid_search_predictor(
(caterpillar_monthly_train["Volume"]), (caterpillar_monthly_test["Volume"]), monthly_predictor2, monthly_param_grid)
caterpillar_monthly_test.index = caterpillar_monthly_test.index.to_timestamp(freq='M')
plot_lstm_result(caterpillar_monthly_test["Volume"], predictions3)
Best parameters: {'forecast__estimator__max_depth': 3, 'forecast__window_length': 60} MAE for the next 32 weeks forcast is, 2349.7801125306532 MAPE for the next 32 forcast is, 0.24289293120752836
auto(monthly_alchemist_df, monthly, next_8months)
/usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn(
SARIMAX Results =========================================================================================== Dep. Variable: y No. Observations: 275 Model: SARIMAX(1, 1, 2)x(2, 0, [], 12) Log Likelihood -2433.862 Date: Wed, 28 May 2025 AIC 4881.724 Time: 13:03:42 BIC 4907.016 Sample: 01-31-2001 HQIC 4891.876 - 11-30-2023 Covariance Type: opg ============================================================================== coef std err z P>|z| [0.025 0.975] ------------------------------------------------------------------------------ intercept -0.9956 2.098 -0.475 0.635 -5.107 3.115 ar.L1 0.8514 0.043 19.605 0.000 0.766 0.936 ma.L1 -1.3218 0.068 -19.564 0.000 -1.454 -1.189 ma.L2 0.3290 0.059 5.597 0.000 0.214 0.444 ar.S.L12 0.4901 0.036 13.616 0.000 0.420 0.561 ar.S.L24 0.0969 0.054 1.802 0.072 -0.009 0.202 sigma2 3.238e+06 1.35e+05 23.966 0.000 2.97e+06 3.5e+06 =================================================================================== Ljung-Box (L1) (Q): 0.40 Jarque-Bera (JB): 4471.35 Prob(Q): 0.53 Prob(JB): 0.00 Heteroskedasticity (H): 0.06 Skew: 2.56 Prob(H) (two-sided): 0.00 Kurtosis: 22.12 =================================================================================== Warnings: [1] Covariance matrix calculated using the outer product of gradients (complex-step). MAE for the next 32 weeks forcast is, 701.2787020345199 MAPE for the next 32 forcast is, 0.278878890867559
/usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn(
auto(monthly_caterpillar_df, 12, next_8months)
/usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn(
SARIMAX Results ============================================================================================ Dep. Variable: y No. Observations: 275 Model: SARIMAX(1, 0, 4)x(1, 0, [1], 12) Log Likelihood -2466.475 Date: Wed, 28 May 2025 AIC 4950.949 Time: 13:04:51 BIC 4983.500 Sample: 01-31-2001 HQIC 4964.013 - 11-30-2023 Covariance Type: opg ============================================================================== coef std err z P>|z| [0.025 0.975] ------------------------------------------------------------------------------ intercept 1258.7035 1384.431 0.909 0.363 -1454.732 3972.139 ar.L1 -0.4917 1.512 -0.325 0.745 -3.456 2.472 ma.L1 1.0677 1.502 0.711 0.477 -1.876 4.011 ma.L2 0.6316 0.850 0.743 0.458 -1.035 2.298 ma.L3 0.4216 0.491 0.859 0.391 -0.541 1.384 ma.L4 0.1437 0.330 0.435 0.663 -0.503 0.791 ar.S.L12 0.8803 0.039 22.655 0.000 0.804 0.956 ma.S.L12 -0.4364 0.086 -5.099 0.000 -0.604 -0.269 sigma2 3.465e+06 2.74e+05 12.661 0.000 2.93e+06 4e+06 =================================================================================== Ljung-Box (L1) (Q): 0.36 Jarque-Bera (JB): 12.38 Prob(Q): 0.55 Prob(JB): 0.00 Heteroskedasticity (H): 0.95 Skew: 0.23 Prob(H) (two-sided): 0.80 Kurtosis: 3.93 =================================================================================== Warnings: [1] Covariance matrix calculated using the outer product of gradients (complex-step). [2] Covariance matrix is singular or near-singular, with condition number 5.47e+14. Standard errors may be unstable. MAE for the next 32 weeks forcast is, 1997.430827032542 MAPE for the next 32 forcast is, 0.1860452061994639
/usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn( /usr/local/lib/python3.11/dist-packages/sklearn/utils/deprecation.py:151: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8. warnings.warn(
Book | XGBoost MAE | XGBoost MAPE | Auto ARIMA MAE | Auto ARIMA MAPE |
---|---|---|---|---|
The Alchemist | 699 | 34% | 701 | 27% |
The Very Hungry Caterpillar | 2349 | 24% | 1997 | 19% |