def test_equivalence_cython_python(trend, seasonal): mod = ExponentialSmoothing(housing_data, trend=trend, seasonal=seasonal) res = mod.fit() res.summary() # Smoke test params = res.params nobs = housing_data.shape[0] y = np.squeeze(np.asarray(housing_data)) m = 12 if seasonal else 0 lvals = np.zeros(nobs) b = np.zeros(nobs) s = np.zeros(nobs + m - 1) p = np.zeros(6 + m) max_seen = np.finfo(np.double).max alpha = params['smoothing_level'] beta = params['smoothing_slope'] gamma = params['smoothing_seasonal'] phi = params['damping_slope'] phi = 1.0 if np.isnan(phi) else phi l0 = params['initial_level'] b0 = params['initial_slope'] p[:6] = alpha, beta, gamma, l0, b0, phi if seasonal: p[6:] = params['initial_seasons'] xi = np.ones_like(p).astype(np.uint8) py_func = PY_SMOOTHERS[(seasonal, trend)] cy_func = SMOOTHERS[(seasonal, trend)] p_copy = p.copy() sse_cy = cy_func(p, xi, p_copy, y, lvals, b, s, m, nobs, max_seen) sse_py = py_func(p, xi, p_copy, y, lvals, b, s, m, nobs, max_seen) assert_allclose(sse_py, sse_cy)
def test_basin_hopping(reset_randomstate): mod = ExponentialSmoothing(housing_data, trend='add') res = mod.fit() res2 = mod.fit(use_basinhopping=True) # GH 5642 tol = 1e-6 if PLATFORM_OSX else 0.0 assert res2.sse <= res.sse + tol
def test_predict(self): fit1 = ExponentialSmoothing(self.aust, seasonal_periods=4, trend='add', seasonal='mul').fit() fit2 = ExponentialSmoothing(self.aust, seasonal_periods=4, trend='add', seasonal='mul').fit() # fit3 = ExponentialSmoothing(self.aust, seasonal_periods=4, trend='add', seasonal='mul').fit(remove_bias=True, use_basinhopping=True) assert_almost_equal(fit1.predict('2011-03-01 00:00:00', '2011-12-01 00:00:00'), [61.3083,37.3730,46.9652,51.5578], 3) assert_almost_equal(fit2.predict(end='2011-12-01 00:00:00'), [61.3083,37.3730,46.9652,51.5578], 3)
def test_hw_seasonal_buggy(self): fit3 = ExponentialSmoothing(self.aust, seasonal_periods=4, seasonal='add').fit(use_boxcox=True) assert_almost_equal(fit3.forecast(8), [59.91, 35.71, 44.64, 47.62, 59.91, 35.71, 44.64, 47.62], 2) fit4 = ExponentialSmoothing(self.aust, seasonal_periods=4, seasonal='mul').fit(use_boxcox=True) assert_almost_equal(fit4.forecast(8), [60.71, 35.70, 44.63, 47.55, 60.71, 35.70, 44.63, 47.55], 2)
def test_hw_seasonal(self): fit1 = ExponentialSmoothing(self.aust, seasonal_periods=4, trend='additive', seasonal='additive').fit(use_boxcox=True) fit2 = ExponentialSmoothing(self.aust, seasonal_periods=4, trend='add', seasonal='mul').fit(use_boxcox=True) assert_almost_equal(fit1.forecast(8), [61.34, 37.24, 46.84, 51.01, 64.47, 39.78, 49.64, 53.90], 2) assert_almost_equal(fit2.forecast(8), [60.97, 36.99, 46.71, 51.48, 64.46, 39.02, 49.29, 54.32], 2) fit5 = ExponentialSmoothing(self.aust, seasonal_periods=4, trend='mul', seasonal='add' ).fit(use_boxcox='log') fit6 = ExponentialSmoothing(self.aust, seasonal_periods=4, trend='multiplicative', seasonal='multiplicative' ).fit(use_boxcox='log')
index=new_index, columns=list(sat[i].columns)) #training datas train_data_x = {i: sat[i][["x"]] for i in sat.keys()} train_data_y = {i: sat[i][["y"]] for i in sat.keys()} train_data_z = {i: sat[i][["z"]] for i in sat.keys()} train_data_Vx = {i: sat[i][["Vx"]] for i in sat.keys()} train_data_Vy = {i: sat[i][["Vy"]] for i in sat.keys()} train_data_Vz = {i: sat[i][["Vz"]] for i in sat.keys()} #TripleExponentialSmoothing model model_x = { i: ExponentialSmoothing(train_data_x[i], trend="add", seasonal='add', seasonal_periods=24).fit(use_brute=False, use_basinhopping=True) for i in sat.keys() } model_y = { i: ExponentialSmoothing(train_data_y[i], trend="add", seasonal='add', seasonal_periods=24).fit(use_brute=False, use_basinhopping=True) for i in sat.keys() } model_z = {
def HoltExp(data_frame, ticker): # split dataset into testing and training sets - This wasn't working, now has been fixed limit = int(0.9 * data_frame.shape[0]) test = data_frame[limit:] # last 20% of values train = data_frame[:limit] # first 80% of values # Plot into graph # plt.plot(train.groupby(['date']) ['4. close'].mean(), color='blue', label='Train') # plt.plot(test.groupby(['date']) ['4. close'].mean(), color='red', label='Test') # plt.legend(loc='best') # plt.title('Training and Test Data') # plt.show() is_stationary = test_stationarity(train['4. close']) #-- SUMMARY OF LINES 118 - 194 ------------- # If the stock prices are not stationary, we remove the trends and seasonality if not is_stationary: # taking ln of training and testing closing values train_log = np.log(train['4. close']) test_log = np.log(test['4. close']) # plotting moving average moving_avg = train_log.rolling(24).mean() # plt.plot(train_log, label='Original') # plt.plot(moving_avg, color='red', label='Moving Average') # plt.title('Moving Average') # plt.show() # removing trend to make time series stationary train_log_moving_avg_diff = train_log - moving_avg train_log_moving_avg_diff.dropna( inplace=True ) # took average of first 24 values, so rolling mean is not defined for first 23 - drop values # test_stationarity(train_log_moving_avg_diff) # stabilise mean of time series - required for stationary time series train_log_diff = train_log - train_log.shift(1) test_stationarity(train_log_diff.dropna()) # fit Exponential Smoothing - fit model on the univariate series model = ExponentialSmoothing(np.array(train_log), trend='mul', seasonal=None, damped=True) fit = model.fit() # predict values on validation set forecast = fit.forecast(np.asarray( len(test))) # n_periods creates errors forecast = pd.DataFrame(forecast, index=test_log.index, columns=['Prediction']) forecast = np.exp(forecast) # Adjust for non-log values # Graph forecasts vs actual # plt.plot(train.groupby(['date']) ['4. close'].mean(), label='Train') # plt.plot(test.groupby(['date']) ['4. close'].mean(), label='Test') # plt.plot(forecast, color='red', label='Prediction') # plt.title(f'{ticker} Stock Price Prediction') # plt.xlabel('Time') # plt.ylabel('Actual Stock Price') # plt.legend(loc='upper left', fontsize=8) # plt.show() # check performance of model using RMSE as metric rms = np.sqrt(mean_squared_error(test_log, np.log(forecast))) else: model = ExponentialSmoothing(np.array(train['4. close']), trend='mul', seasonal=None, damped=True) fit = model.fit() # predict values on validation set forecast = fit.forecast(len(test)) # n_periods creates errors forecast = pd.DataFrame(forecast, index=test.index, columns=['Prediction']) # Graph forecasts vs actual # plt.plot(train.groupby(['date']) ['4. close'].mean(), label='Train') # plt.plot(test.groupby(['date']) ['4. close'].mean(), label='Test') # plt.plot(forecast, color='red', label='Prediction') # plt.title(f'{ticker} Stock Price Prediction') # plt.xlabel('Time') # plt.ylabel('Actual Stock Price') # plt.legend(loc='upper left', fontsize=8) # plt.show() # check performance of model using RMSE as metric rms = np.sqrt(mean_squared_error(test, forecast)) result = rating(forecast) result.append(rms) result.append(ticker) return tuple(result)
def get_feature_AddES_residuals(time_series, alpha, beta): predict = ExponentialSmoothing(time_series, trend='add').fit(smoothing_level=alpha, smoothing_slope=beta) return time_series - predict.fittedvalues
#data.set_index(t1, inplace=True) data.drop(['Year', 'Month'], axis=1, inplace=True) data.columns = ['assumption', 'time'] df = pd.DataFrame({ 'year': np.array(4 * [2018]), 'month': np.array(range(1, 5)), 'day': np.array(4 * [1]) }) df = pd.to_datetime(df) a = np.array(range(36, 40)) model = ExponentialSmoothing(np.asarray(data['assumption']), seasonal='mul', seasonal_periods=12).fit() pred = model.predict(start=a[0], end=a[-1]) plt.plot(data['time'], data['assumption'], label='Data') plt.plot(df, pred, label='Forecast') plt.legend(loc='best') fig = plt.figure() axes = fig.add_subplot(111) axes.plot(data['time'], data['assumption'], label='Data') axes.plot(df, pred, label='Forecast') axes.legend(loc='upper left', fontsize=7) fig.autofmt_xdate()
class ExpSmoothingForecaster(BaseSingleSeriesForecaster): """ Holt-Winters exponential smoothing forecaster. Default settings use simple exponential smoothing without trend and seasonality components. Parameters ---------- trend : str{"add", "mul", "additive", "multiplicative", None}, optional (default=None) Type of trend component. damped : bool, optional (default=None) Should the trend component be damped. seasonal : {"add", "mul", "additive", "multiplicative", None}, optional (default=None) Type of seasonal component. seasonal_periods : int, optional (default=None) The number of seasons to consider for the holt winters. smoothing_level : float, optional The alpha value of the simple exponential smoothing, if the value is set then this value will be used as the value. smoothing_slope : float, optional The beta value of the Holt's trend method, if the value is set then this value will be used as the value. smoothing_seasonal : float, optional The gamma value of the holt winters seasonal method, if the value is set then this value will be used as the value. damping_slope : float, optional The phi value of the damped method, if the value is set then this value will be used as the value. optimized : bool, optional Estimate model parameters by maximizing the log-likelihood use_boxcox : {True, False, 'log', float}, optional Should the Box-Cox transform be applied to the data first? If 'log' then apply the log. If float then use lambda equal to float. remove_bias : bool, optional Remove bias from forecast values and fitted values by enforcing that the average residual is equal to zero. use_basinhopping : bool, optional Using Basin Hopping optimizer to find optimal values check_input : bool, optional (default=True) - If True, input are checked. - If False, input are not checked and assumed correct. Use with caution. References ---------- [1] Hyndman, Rob J., and George Athanasopoulos. Forecasting: principles and practice. OTexts, 2014. """ def __init__(self, trend=None, damped=False, seasonal=None, seasonal_periods=None, smoothing_level=None, smoothing_slope=None, smoothing_seasonal=None, damping_slope=None, optimized=True, use_boxcox=False, remove_bias=False, use_basinhopping=False, check_input=True): # Model params self.trend = trend self.damped = damped self.seasonal = seasonal self.seasonal_periods = seasonal_periods # Fit params self.smoothing_level = smoothing_level self.optimized = optimized self.smoothing_slope = smoothing_slope self.smooting_seasonal = smoothing_seasonal self.damping_slope = damping_slope self.use_boxcox = use_boxcox self.remove_bias = remove_bias self.use_basinhopping = use_basinhopping super(ExpSmoothingForecaster, self).__init__(check_input=check_input) def _fit(self, y): """ Internal fit. Parameters ---------- y : pandas.Series Target time series to which to fit the forecaster. Returns ------- self : returns an instance of self. """ # Unnest series. y = y.iloc[0] # Fit forecaster. self.estimator = ExponentialSmoothing(y, trend=self.trend, damped=self.damped, seasonal=self.seasonal, seasonal_periods=self.seasonal_periods) self._fitted_estimator = self.estimator.fit(smoothing_level=self.smoothing_level, optimized=self.optimized, smoothing_slope=self.smoothing_slope, smoothing_seasonal=self.smooting_seasonal, damping_slope=self.damping_slope, use_boxcox=self.use_boxcox, remove_bias=self.remove_bias, use_basinhopping=self.use_basinhopping) return self
def test_debiased(): mod = ExponentialSmoothing(housing_data, trend='add') res = mod.fit() res2 = mod.fit(remove_bias=True) assert np.any(res.fittedvalues != res2.fittedvalues)
def test_invalid_start_param_length(): mod = ExponentialSmoothing(housing_data) with pytest.raises(ValueError): mod.fit(start_params=np.array([0.5]))
def test_no_params_to_optimize(): mod = ExponentialSmoothing(housing_data) with pytest.warns(EstimationWarning): mod.fit(smoothing_level=0.5, initial_level=housing_data.iloc[0])
def test_start_params(trend, seasonal): mod = ExponentialSmoothing(housing_data, trend='add', seasonal='add') res = mod.fit() res2 = mod.fit(start_params=res.mle_retvals.x) assert res2.sse <= res.sse
for year in start_year: # Obtain training data query_train = """select tradedate, closeprice from stock.stockprice where ticker = '{}' and date_part('year', tradedate) between {} and 2018""".format(ticker, year) X_train = pd.io.sql.read_sql(query_train, conn) for method in methods: # For holt-winters method if method == 'hw': try: # Train Model model = ExponentialSmoothing(X_train['closeprice'], trend='add', seasonal='add', seasonal_periods=4).fit() # Predict pred = model.forecast(X_test.shape[0]) X_test['yhat'] = pred.tolist() # Calculate R-square X_test['st'] = (X_test['closeprice'] - y_bar)**2 X_test['se'] = (X_test['closeprice'] - X_test['yhat'])**2 r_square = 1 - (X_test['se'].sum() / X_test['st'].sum()) # Store result result_ticker.append(((year, method), r_square)) preds[(year, method)] = X_test except: pass # For Facebook Prophet
virat_df = virat_df.assign(RunsInterpolated=df.interpolate(method='time')) decomposition = seasonal_decompose(\ virat_df.loc['2017-01-01':df.index.max()].RunsInterpolated) decomposition.plot() z.showplot(plt) import matplotlib from statsmodels.tsa.holtwinters import ExponentialSmoothing rcParams['figure.figsize'] = 8, 6 series = df.RunsInterpolated series[series == 0] = 1 train_size = int(len(series) * 0.8) train_size train = series[0:train_size] test = series[train_size + 1:] y_hat = test.copy() fit = ExponentialSmoothing( train ,seasonal_periods=730,\ trend=None, seasonal='add',).fit() y_hat['Holt_Winter_Add'] = fit.forecast(len(test)) plt.plot(test, label='Test') plt.plot(y_hat['Holt_Winter_Add'], label='Holt_Winter_Add') plt.legend(loc='best') z.showplot(plt) plt.gcf().clear() from sklearn.metrics import mean_squared_error from math import sqrt rms_add = sqrt(mean_squared_error(test, y_hat.Holt_Winter_Add)) print('RMSE for Holts Winter Additive Model:%f' % rms_add) #####Output##### # RMSE for Holts Winter Additive Model:40.490023 y_hat['Holt_Winter_Add'] = fit.forecast(len(test) + 180) print(
def MAPE(pred,org): temp = np.abs((pred-org))*100/org return np.mean(temp) ########################### Simple Exponential Method ses_model = SimpleExpSmoothing(Train["Sales"]).fit() pred_ses = ses_model.predict(start = Test.index[0],end = Test.index[-1]) MAPE(pred_ses,Test.Sales) # 17.041 ############### Holt method holt_model = Holt(Train["Sales"]).fit() pred_holt = holt_model.predict(start = Test.index[0],end = Test.index[-1]) MAPE(pred_holt,Test.Sales) # 101.99 ###### Holts winter exponential smoothing with additive seasonality with linear trend hw_model = ExponentialSmoothing(Train["Sales"],seasonal="add",trend="add",seasonal_periods=12,damped=True).fit() pred_hw = hw_model.predict(start = Test.index[0],end = Test.index[-1]) MAPE(pred_hw,Test.Sales) # 14.745 ##### Holts winter exponential smoothing with multiplicative seasonality and linear trend hwe_model_mul_add = ExponentialSmoothing(Train["Sales"],seasonal="mul",trend="add",seasonal_periods=12).fit() pred_hwe_mul_add = hwe_model_mul_add.predict(start = Test.index[0],end = Test.index[-1]) MAPE(pred_hwe_mul_add,Test.Sales) # 15 ########## predict for entire data hw_model_full = ExponentialSmoothing(plastic1["Sales"],seasonal="add",trend="add",seasonal_periods=12,damped=True).fit() pred_hw_full = hw_model_full.predict(start = plastic1.index[0],end = plastic1.index[-1]) MAPE(pred_hw_full,plastic1.Sales) # 2.86 ######### Visualization of Forecasted values for Test data set using different methods plt.plot(Train.index, Train["Sales"], label='Train',color="black")
def test_invalid_seasonal(seasonal): y = pd.Series(-np.ones(100), index=pd.date_range('2000-1-1', periods=100, freq='MS')) with pytest.raises(ValueError): ExponentialSmoothing(y, seasonal=seasonal, seasonal_periods=1)
def run_method(): # config plt.style.use('bmh') sns.set_style("whitegrid") plt.rc('xtick', labelsize=15) plt.rc('ytick', labelsize=15) warnings.filterwarnings("ignore") pd.set_option('max_colwidth', 100) pd.set_option('display.max_rows', 500) pd.set_option('display.max_columns', 500) color_pal = plt.rcParams['axes.prop_cycle'].by_key()['color'] color_cycle = cycle(plt.rcParams['axes.prop_cycle'].by_key()['color']) # 导入数据集: data = pd.read_csv(str(proj_root_dir / 'data/data_for_tsa.csv')) data['date'] = pd.to_datetime(data['date']) print(data.head()) train = data[data['date'] <= '2016-03-27'] test = data[(data['date'] > '2016-03-27') & (data['date'] <= '2016-04-24')] # plot data fig, ax = plt.subplots(figsize=(25, 5)) train.plot(x='date', y='demand', label='Train', ax=ax) test.plot(x='date', y='demand', label='Test', ax=ax) predictions = pd.DataFrame() predictions['date'] = test['date'] stats = pd.DataFrame(columns=['Model Name', 'Execution Time', 'RMSE']) # 开始调用具体方法 t0 = time.time() model_name = 'Triple Exponential Smoothing' # train tripleExpSmooth_model = ExponentialSmoothing(train['demand'], trend='add', seasonal='add', seasonal_periods=7).fit() t1 = time.time() - t0 # predict predictions[model_name] = tripleExpSmooth_model.forecast(28).values # visualize fig, ax = plt.subplots(figsize=(25, 4)) train[-28:].plot(x='date', y='demand', label='Train', ax=ax) test.plot(x='date', y='demand', label='Test', ax=ax) predictions.plot(x='date', y=model_name, label=model_name, ax=ax) # evaluate score = np.sqrt( mean_squared_error(predictions[model_name].values, test['demand'])) print('RMSE for {}: {:.4f}'.format(model_name, score)) stats = stats.append( { 'Model Name': model_name, 'Execution Time': t1, 'RMSE': score }, ignore_index=True) print("stats: %s" % (stats, )) plt.show()
def test_forecast(self): fit1 = ExponentialSmoothing(self.aust, seasonal_periods=4, trend='add', seasonal='add').fit() assert_almost_equal(fit1.forecast(steps=4), [60.9542,36.8505,46.1628,50.1272], 3)
@author: mac """ import numpy as np import pandas as pd import matplotlib from statsmodels.tsa.seasonal import seasonal_decompose from pylab import rcParams df = pd.read_csv('EnergyProduction.csv', index_col=0, parse_dates=True) df.index.freq = 'MS' df['SMA12'] = df['EnergyIndex'].rolling(window=12).mean() df.plot(figsize=(12, 5)) from statsmodels.tsa.holtwinters import SimpleExpSmoothing df['SES12'] = SimpleExpSmoothing(df['EnergyIndex']).fit( smoothing_level=2 / (12 + 1), optimized=False).fittedvalues.shift(-1) from statsmodels.tsa.holtwinters import ExponentialSmoothing df['TESmul-12'] = ExponentialSmoothing( df['EnergyIndex'], trend='mul', seasonal='mul', seasonal_periods=12).fit().fittedvalues.shift(-1) df[:'1972-01-01'].plot(figsize=(12, 5))
def train_es(train, test): y_hat = test.copy() model = ExponentialSmoothing(train[predict_label]) model_fit = model.fit() return model_fit, y_hat
from statsmodels.tsa.holtwinters import ExponentialSmoothing fit = ExponentialSmoothing(data, seasonal_periods=periodicity, trend='add', seasonal='add').fit(use_boxcox=True) fit.fittedvalues.plot(color='blue') fit.forecast(5).plot(color='green') plt.show()
# HWES example from statsmodels.tsa.holtwinters import ExponentialSmoothing from random import random # contrived dataset data = [x + random() for x in range(1, 100)] # fit model model = ExponentialSmoothing(data) model_fit = model.fit() # make prediction yhat = model_fit.predict(len(data), len(data)) print(yhat)
fit1 = Holt(np.asarray(train['Count'])).fit(smoothing_level=0.1, smoothing_slope=0.0001) predict = fit1.forecast(len(test)) submission['ID'] = test['ID'] submission['Count'] = predict # Converting the final submission to csv format submission.to_csv("submissions/1.csv", index=False) # Holt's Winter Model to predict time series # Takes into account both Seasonality and Trend fit1 = ExponentialSmoothing( np.asarray(train['Count']), seasonal_periods=7, trend='add', seasonal='add', ).fit() y_hat['Count'] = fit1.forecast(len(valid)) rmse.loc[len(rmse)] = "Holt's Winter Model @@7", sqrt( MSE(valid.Count, y_hat.Count)) # Visualize Holt Winter model predictions plt.figure(figsize=(40, 20)) plt.plot(train.Datetime, train['Count'], label='train') plt.plot(valid.Datetime, valid['Count'], label='validation') plt.plot(y_hat.Datetime, y_hat['Count'], label='Holts Winter Model Forecast') plt.xlabel('Datetime') plt.ylabel('Passenger count') plt.legend(loc='best')
cfg_list = exp_smoothing_configs(seasonal=[12]) cfg_list1 = exp_smoothing_configs(seasonal=[4]) # grid search scores = grid_search(data, cfg_list, n_test) scores1 = grid_search(data, cfg_list1, n_test1) print('done') # list top 3 configs for cfg, error in scores: print("以一年为周期:", cfg, error) for cfg, error in scores1: print("以四个月为周期:", cfg, error) fit7 = ExponentialSmoothing(data1, seasonal_periods=12, trend='add', damped=True, seasonal='add').fit(optimized=True, use_boxcox=False, remove_bias=False) fit8 = ExponentialSmoothing(data1, seasonal_periods=4, trend='add', damped=True, seasonal='add').fit(optimized=True, use_boxcox=False, remove_bias=True) print(list(fit7.forecast(12))) print(list(fit8.forecast(4))) l7, = plt.plot(list(fit7.fittedvalues) + list(fit7.forecast(12)), marker='.') l8, = plt.plot(list(fit8.fittedvalues) + list(fit8.forecast(4)),
import pandas as pd import numpy as np import matplotlib.pyplot as plt from statsmodels.tsa.holtwinters import ExponentialSmoothing import xlwings as xw print('Loading data...') wb = xw.Book('Holt_Winters_Data.xlsx').sheets['Tabelle1'] print('Loading completed') train = np.asarray(wb.range('C2:C41').value) model = ExponentialSmoothing(train, seasonal='mul', seasonal_periods=12).fit() pred = model.predict(start=0, end=47) plt.plot(np.arange(0,len(train)), train, label='Train') plt.plot(np.arange(0,len(pred)), pred, label='Holt-Winters') plt.legend(loc='best') plt.show()
#%% # remove l0,b0,s-12 states = pd.DataFrame(np.c_[l[1:], b[1:], s[12:]], \ columns=['level','slope','seasonal']) fig, [ax1,ax2,ax3] = plt.subplots(3, 1, figsize=(15,8)) states['level'].plot(ax=ax1) states['slope'].plot(ax=ax2) states['seasonal'].plot(ax=ax3) plt.show() #%% # set seasonal as additive or multiplicative # for more details please refer: # https://www.statsmodels.org/dev/generated/statsmodels.tsa.holtwinters.ExponentialSmoothing.html fit1 = ExponentialSmoothing(y, seasonal_periods=12, trend='add', seasonal='add').fit() fit2 = ExponentialSmoothing(y, seasonal_periods=12, trend='add', seasonal='mul').fit() #%% # symbol r $ and \ in the results variable are the latex symbols for visualization in notebook results = pd.DataFrame(index=[r"$\alpha$",\ r"$\beta$",\ r"$\phi$",\ r"$\gamma$",\ r"$l_0$",\ "$b_0$",\ "SSE"]) # ExponentialSmoothing() object has following attributes params = ['smoothing_level', \ 'smoothing_slope', \ 'damping_slope', \
company = "AAPL" data = yf.Ticker(company).history('10y').reset_index() tsdata = data["Close"] ts_ma = tsdata.rolling(30).mean() # plt.plot(tsdata) # plt.plot(ts_ma) # plt.show() simp_model = SimpleExpSmoothing(tsdata) simp_model_fit = simp_model.fit() # print(simp_model_fit.summary()) double_model = ExponentialSmoothing(tsdata, trend='add') double_model_fit = double_model.fit(use_boxcox=True) # print(double_model_fit.summary()) # print(double_model_fit.forecast(10)) # print(double_model_fit.predict(1250,1300)) plt.plot(tsdata) plt.plot(double_model_fit.fittedvalues) plt.show() print(double_model_fit.fcastvalues) log_ts = tsdata**(-1 / 3) print(log_ts)
pred_ses = ses_model.predict(start = test.index[0],end = test.index[-1]) #MAPE = MAPE(pred_ses,test.Sales) # 17.04 #RMSE = RMSE(pred_ses,test.Sales) # 264.56 print('Simple Exp Model - RMSE %d, MAPE %d', RMSE(pred_ses,test.Sales), MAPE(pred_ses,test.Sales)) #########################Holt Method########################################### # Holt method hw_model = Holt(train["Sales"]).fit() pred_hw = hw_model.predict(start = test.index[0],end = test.index[-1]) #MAPE = MAPE(pred_hw,test.Sales) # 101.95 #RMSE = RMSE(pred_hw,test.Sales) # 1570.11 print('Holt Model - RMSE %d, MAPE %d', RMSE(pred_hw,test.Sales), MAPE(pred_hw,test.Sales)) ################################################################################## # Holts winter exponential smoothing with additive seasonality and additive trend hwe_model_add_add = ExponentialSmoothing(train["Sales"],seasonal="add",trend="add",seasonal_periods=12,damped=True).fit() pred_hwe_add_add = hwe_model_add_add.predict(start = test.index[0],end = test.index[-1]) #MAPE(pred_hwe_add_add,test.Sales) # 14.42 #RMSE = RMSE(pred_hwe_add_add,test.Sales) # 214 print('Holts winter exponential smoothing - RMSE %d, MAPE %d', RMSE(pred_hwe_add_add,test.Sales), MAPE(pred_hwe_add_add,test.Sales)) ########################################################################3 # Holts winter exponential smoothing with multiplicative seasonality and additive trend hwe_model_mul_add = ExponentialSmoothing(train["Sales"],seasonal="mul",trend="add",seasonal_periods=12).fit() pred_hwe_mul_add = hwe_model_mul_add.predict(start = test.index[0],end = test.index[-1]) #MAPE(pred_hwe_mul_add,test.Sales) # MAPE - 15.002, RMSE - 243.544 print('Holts winter ES - Mult n Add - RMSE %d, MAPE %d', RMSE(pred_hwe_mul_add,test.Sales), MAPE(pred_hwe_mul_add,test.Sales)) ###########################Plot - Visualization ################################## #Visualization of Forecasted values for Test data set using different methods plt.plot(train.index, train["Sales"], label='Train',color="black")
def utility_hwes_predict(data,numofforecast=1,loga=False,show_mdl_detail=False): """ Holts Wİnter Exponential Smoothing Forecast model Parameters ---------- data : TYPE DESCRIPTION. numofforecast : TYPE, optional DESCRIPTION. The default is 1. loga : TYPE, optional DESCRIPTION. The default is False. show_mdl_detail : TYPE, optional DESCRIPTION. The default is False. Returns ------- None. """ from statsmodels.tsa.holtwinters import ExponentialSmoothing from sklearn.metrics import mean_squared_error as mse from math import sqrt import time import pandas as pd import numpy as np from tqdm import tqdm from itertools import product import warnings if loga==True: datalog=data.apply(np.log1p) else: datalog=data datalog=datalog.reset_index(drop=True) def optimize_HWES(data_column,parameters_list): results = [] best_aic = float('inf') #for param in tqdm(parameters_list): for param in parameters_list: try: import warnings with warnings.catch_warnings(): warnings.filterwarnings("ignore") model=ExponentialSmoothing(data_column,trend=param[0],damped=param[1]).fit() except: #print("model not built with params".format(param)) pass continue aic = model.aic #Save best model, AIC and parameters if aic < best_aic: best_model = model best_aic = aic best_param = param results.append([param, model.aic]) result_table = pd.DataFrame(results) result_table.columns = ['parameters', 'aic'] #Sort in ascending order, lower AIC is better result_table = result_table.sort_values(by='aic', ascending=True).reset_index(drop=True) return result_table #Set initial values and some bounds trend_p = ['mul'] #['mul','add'] damped_p=[False] #[False,True] #Create a list with all possible combinations of parameters parameters = product(trend_p,damped_p) parameters_list = list(parameters) len(parameters_list) result_table = optimize_HWES(datalog,parameters_list) #Set parameters that give the lowest AIC (Akaike Information Criteria) trend_p, damped_p= result_table.parameters[0] import warnings with warnings.catch_warnings(): warnings.filterwarnings("ignore") model = ExponentialSmoothing(datalog,trend=trend_p,damped=damped_p) model_fit = model.fit() yhat = model_fit.forecast(numofforecast) if show_mdl_detail==True: print(model_fit.summary()) if loga==True: yhat=np.exp(yhat)-1 #log1p yhat=yhat.reset_index(drop=True) yhat=yhat.rename("hwes_model") new_index=pd.Index(list(range(data[-1:].index.values[0]+1,data[-1:].index.values[0]+1+numofforecast))) yhat.index=new_index return yhat
from statsmodels.tsa.holtwinters import ExponentialSmoothing from Data_prep.Data_preparation import train_data, test_data import numpy as np from time import time from matplotlib import pyplot as plt # building Additive ES model test_size = len(test_data) add_es_model = ExponentialSmoothing(train_data, trend='add', seasonal='add', seasonal_periods=7) # fitting model timer_start = time() add_es_model_fit = add_es_model.fit() timer_end = time() # generating predictions add_es_pred = add_es_model_fit.forecast(test_size) add_es_residuals = add_es_pred - test_data # plotting predictions plt.figure(figsize=(10, 4)) plt.plot(test_data) plt.plot(add_es_pred) plt.title('Holt-Winters Exponential Smoothing - MSFT closing prices') plt.ylabel('Price', fontsize=16) plt.savefig('Additive ES model') plt.show()
sm.stats.acorr_ljungbox( arima_model.resid, lags=3 ) # all residuals are above 0.05 so no relationships between the residuals ## so in summary, Arima model with pdq=0,2,5 is pretty good with SSE of 3.4E8 ########## exponential smoothing # now we know the residual to beat is 4.3E8, let's see another type of model test = covid[covid.province == 'Ontario'] test.index = test.date data = test.cumulative_cases train_data, test_data = train_test(data, 30, 'n') # exponential smoothing damped exp_model = ExponentialSmoothing(train_data, trend='mul', seasonal=None, damped=True).fit() arima_res_plot(exp_model) expsm_pred_plot(exp_model, test_data) #sse=5.4E8 plt.title( 'Predicted vs actual Cumulative Cases \n damped exponential smoothing, Residual: 5.4E8' ) plt.savefig('cumulative_cases_pred_expsm_damped.png', format='png', dpi=300) expsm_pred_plot_all(exp_model, train_data, test_data) #holt holt_model = Holt(train_data, exponential=True).fit(optimized=True) arima_res_plot(holt_model) expsm_pred_plot(holt_model, test_data) #sse=1.5E9
import pandas as pd import numpy as np import matplotlib.pyplot as plt from statsmodels.tsa.holtwinters import ExponentialSmoothing df = pd.read_csv('airline_passengers.csv',index_col='Month',parse_dates=True) df.index.freq = 'MS' #månedlig frekvens. train_data = df.iloc[:108] # Goes up to but not including 108 test_data = df.iloc[108:] fitted_model = ExponentialSmoothing(train_data['Thousands of Passengers'],trend='mul',seasonal='mul',seasonal_periods=12).fit() test_predictions = fitted_model.forecast(36).rename('HW Forecast') train_data['Thousands of Passengers'].plot(legend=True,label='TRAIN') test_data['Thousands of Passengers'].plot(legend=True,label='TEST',figsize=(12,8)); test_predictions.plot(legend=True,label='PREDICTION'); plt.show() train_data['Thousands of Passengers'].plot(legend=True,label='TRAIN') test_data['Thousands of Passengers'].plot(legend=True,label='TEST',figsize=(12,8)) test_predictions.plot(legend=True,label='PREDICTION',xlim=['1958-01-01','1961-01-01']); plt.show() #Evaluation metrics from sklearn.metrics import mean_squared_error, mean_absolute_error
def triple_exponential_smoothing(season, y_test): # Accounts for level + trend + seasonality in the data # Three models with different parameters # Model 1: Additive trend + season with box-cox transformation tes_model = ExponentialSmoothing(y_test, seasonal_periods=season, trend='add', seasonal='add').fit(use_boxcox=True) y_pred_tes = tes_model.predict(31924).rename("TES") fig = plt.figure(figsize=(60, 8)) tes_model.fittedvalues.plot(color='grey') y_pred_tes.plot(color='grey', legend=True) fig.savefig('results/TES/final_output.jpg', bbox_inches='tight') plt.title("Holt-Winters' Method/Triple Exponential Smoothing") plt.show() # print("Predicted values: ", y_pred_tes, "\n") mse_tes = mean_squared_error(y_test[31923:-1], y_pred_tes) rmse_tes = mean_squared_error(y_pred_tes, y_test[31923:-1], squared=False) r2_tes = r2_score(y_test[31923:-1], y_pred_tes) np.savetxt('results/TES/predicted_values_model.txt', y_pred_tes) actual_test_result = y_test np.savetxt('results/TES/test_values.txt', actual_test_result) # #Three models with different parameters # # #Model 1: Additive trend + season with box-cox transformation # tes_model1 = ExponentialSmoothing(y_test, seasonal_periods=season, trend='add', seasonal='add').fit(use_boxcox=True) # y_pred_tes1 = tes_model1.predict(31924).rename("Model 1") # # #Model 2: Additive trend + Multiplicative season with box-cox transformation # tes_model2 = ExponentialSmoothing(y_test, seasonal_periods=season, trend='add', seasonal='mul').fit(use_boxcox=True) # y_pred_tes2 = tes_model2.predict(31924).rename("Model 2") # # #Model 3: Damped trend + Additive season with box-cox transformation # tes_model3 = ExponentialSmoothing(y_test, seasonal_periods=season, trend='add', seasonal='add', damped_trend=True).fit(use_boxcox=True) # y_pred_tes3 = tes_model3.predict(31924).rename("Model 3") # # # Model 4: Damped trend + Multiplicative season with box-cox transformation # tes_model4 = ExponentialSmoothing(y_test, seasonal_periods=season, trend='add', seasonal='mul', # damped_trend=True).fit() # y_pred_tes4 = tes_model4.predict(31924).rename("Model 4") # # fig = plt.figure(figsize=(60, 8)) # tes_model1.fittedvalues.plot(color='blue') # y_pred_tes1.plot(color='blue', legend=True) # tes_model2.fittedvalues.plot(color='red') # y_pred_tes2.plot(color='red', legend=True) # tes_model3.fittedvalues.plot(color='green') # y_pred_tes3.plot(color='green', legend=True) # tes_model4.fittedvalues.plot(color='yellow') # y_pred_tes4.plot(color='yellow', legend=True) # fig.savefig('results/TES/final_output.jpg', bbox_inches='tight') # plt.title("Holt-Winters' Method/Triple Exponential Smoothing") # plt.show() # # print("Predicted values (Model 1): ", y_pred_tes1, "\n") # print("Predicted values (Model 2): ", y_pred_tes2, "\n") # print("Predicted values (Model 3): ", y_pred_tes3, "\n") # print("Predicted values (Model 4): ", y_pred_tes4, "\n") # mse_tes1 = mean_squared_error(y_test[31923:-1], y_pred_tes1) # mse_tes2 = mean_squared_error(y_test[31923:-1], y_pred_tes2) # mse_tes3 = mean_squared_error(y_test[31923:-1], y_pred_tes3) # mse_tes4 = mean_squared_error(y_test[31923:-1], y_pred_tes4) # # np.savetxt('results/TES/predicted_values_model1.txt', y_pred_tes1) # np.savetxt('results/TES/predicted_values_model2.txt', y_pred_tes2) # np.savetxt('results/TES/predicted_values_model3.txt', y_pred_tes3) # np.savetxt('results/TES/predicted_values_model4.txt', y_pred_tes4) # actual_test_result = y_test # np.savetxt('results/TES/test_values.txt', actual_test_result) # # return mse_tes1, mse_tes2, mse_tes3, mse_tes4 return mse_tes, rmse_tes, r2_tes, y_pred_tes
#for seas in np.arange(2, 53) : # model=ExponentialSmoothing(data,trend="add",damped=True,seasonal="add",seasonal_periods=seas) ## model=ExponentialSmoothing(data,trend="mul",damped=True,seasonal="mul",seasonal_periods=seas) # d.append((seas,model.fit().aic)) # #modelADD_seasRange=pd.DataFrame(d,columns=["param","aic"]) #modelADD_seasRange["aic"].idxmin() #29 31 2018.771262 #modelADD_seasRange["aic"].idxmax() #47 49 2163.182370 # #modelMUL_seasRange=pd.DataFrame(d,columns=["param","aic"]) #modelMUL_seasRange["aic"].idxmin() #29 31 1999.103765 #modelMUL_seasRange["aic"].idxmax() #47 49 2251.367739 # ##modelMIX_seasRange=pd.DataFrame(d,columns=["param","aic"]) NaN # model = ExponentialSmoothing(data, trend="add",damped=True,seasonal="add",seasonal_periods=52) #model = ExponentialSmoothing(data, trend="add",damped=False,seasonal="add",seasonal_periods=52) # DUMPING the trend increase the values, which is good for the negative ones # fit model # smoothing_level (alpha): the smoothing coefficient for the level. # smoothing_slope (beta): the smoothing coefficient for the trend. # smoothing_seasonal (gamma): the smoothing coeff for the seasonal component. # damping_slope (phi): the coefficient for the damped trend. model_fit = model.fit(optimized=True) model_fit.summary() #Dep. Variable: endog No. Observations: 114 #Model: ExponentialSmoothing SSE 2621538254.974 #Optimized: True AIC 2046.394 #Trend: Additive BIC 2202.358
def HWES(data1): from statsmodels.tsa.holtwinters import ExponentialSmoothing model = ExponentialSmoothing(bbp) model_fit = model.fit() HWESresult = model_fit.predict(len(bbp), len(bbp)) print('The period and the prediction from the HWES Model is:', HWESresult)
def test_2d_data(): with pytest.raises(ValueError): ExponentialSmoothing(pd.concat([housing_data, housing_data], 1)).fit()
return np.mean(temp) # Simple Exponential Method ses_model = SimpleExpSmoothing(Train["Sales"]).fit() pred_ses = ses_model.predict(start=Test.index[0], end=Test.index[-1]) MAPE(pred_ses, Test.Sales) # 53.98 # Holt method hw_model = Holt(Train["Sales"]).fit() pred_hw = hw_model.predict(start=Test.index[0], end=Test.index[-1]) MAPE(pred_hw, Test.Sales) # 53.42 # Holts winter exponential smoothing with additive seasonality and additive trend hwe_model_add_add = ExponentialSmoothing(Train["Sales"], seasonal="add", trend="add", seasonal_periods=10).fit() pred_hwe_add_add = hwe_model_add_add.predict(start=Test.index[0], end=Test.index[-1]) MAPE(pred_hwe_add_add, Test.Sales) # 52.73 hwe_model_add_add = ExponentialSmoothing(coke["Sales"], seasonal="add", trend="add", seasonal_periods=10).fit() pred_hwe_add_add = hwe_model_add_add.predict(start=coke.index[0], end=coke.index[-1]) pred_hwe_add_add # Holts winter exponential smoothing with multiplicative seasonality and additive trend hwe_model_mul_add = ExponentialSmoothing(Train["Sales"],
def test_ndarray(self): fit1 = ExponentialSmoothing(self.aust.values, seasonal_periods=4, trend='add', seasonal='mul').fit() assert_almost_equal(fit1.forecast(4), [61.3083,37.3730,46.9652,51.5578], 3)
def exp(train_set, test_set, params): model = ExponentialSmoothing(train_set, trend='add', seasonal='add', seasonal_periods=365) fit_model = model.fit(smoothing_seasonal=params['smoothing_seasonal'], smoothing_level=params['smoothing_level']) return fit_model.forecast(len(test_set)), None
def test_hw_seasonal(self): fit1 = ExponentialSmoothing(self.aust, seasonal_periods=4, trend='additive', seasonal='additive').fit(use_boxcox=True) fit2 = ExponentialSmoothing(self.aust, seasonal_periods=4, trend='add', seasonal='mul').fit(use_boxcox=True) fit3 = ExponentialSmoothing(self.aust, seasonal_periods=4, seasonal='add').fit(use_boxcox=True) fit4 = ExponentialSmoothing(self.aust, seasonal_periods=4, seasonal='mul').fit(use_boxcox=True) fit5 = ExponentialSmoothing(self.aust, seasonal_periods=4, trend='mul', seasonal='add' ).fit(use_boxcox='log') fit6 = ExponentialSmoothing(self.aust, seasonal_periods=4, trend='multiplicative', seasonal='multiplicative' ).fit(use_boxcox='log') assert_almost_equal(fit1.forecast(8), [61.34,37.24,46.84,51.01,64.47,39.78,49.64,53.90], 2) assert_almost_equal(fit2.forecast(8), [60.97,36.99,46.71,51.48,64.46,39.02,49.29,54.32], 2) assert_almost_equal(fit3.forecast(8), [59.91,35.71,44.64,47.62,59.91,35.71,44.64,47.62], 2) assert_almost_equal(fit4.forecast(8), [60.71,35.70,44.63,47.55,60.71,35.70,44.63,47.55], 2) assert_almost_equal(fit5.forecast(1), [78.53], 2) assert_almost_equal(fit6.forecast(1), [54.82], 2)
def test_basin_hopping(reset_randomstate): mod = ExponentialSmoothing(housing_data, trend='add') res = mod.fit() res2 = mod.fit(use_basinhopping=True) assert res2.sse <= res.sse