def holt_pred_test(steps, path, func): index_name, my_trend = parse_csv(path) if func == 'additive': future, alpha, beta, gamma, rmse = additive(my_trend[-5 * 52:-steps], 52, steps) if func == 'multi': future, alpha, beta, gamma, rmse = multiplicative( my_trend[-5 * 52:-steps], 52, steps) y_pred = np.array(future) y_true = np.array(my_trend[-steps:]) metrics_result = { 'sarima_MAE': metrics.mean_absolute_error(y_true, y_pred), 'sarima_MSE': metrics.mean_squared_error(y_true, y_pred), 'sarima_MAPE': np.mean(np.abs((y_true - y_pred) / y_true)) * 100 } p1 = plt.plot(my_trend[-steps:], '*-') p2 = plt.plot(future) # p1 = plt.plot(index_name,my_trend,'r-') # p2 = plt.plot(index_name_future,future,'g-') plt.ylabel('Search Intensity') plt.xlabel('Year') plt.title('Search Prediction of ' + path.split('/')[-1][:-4]) plt.legend((p1[0], p2[0]), ["Actual", "Predicted"], loc=1) plt.grid(True) # print metrics_result['sarima_MAPE'] return metrics_result['sarima_MAPE']
def holt_pred(steps,path): index_name,my_trend = parse_csv(path) if my_trend == []: return index_name_future = pd.date_range(index_name[-1],periods=steps+1,freq = 'W')[1:] future, alpha, beta, gamma, rmse = additive(my_trend[-5*52:],52,steps) return index_name,index_name_future,my_trend,future
def mase(y_pred, y_true, method='naive', X_test=None, constant=None): """ Mean absolute scaled error. MAE error of your predictions, normalized by MAE error of different methods predictions. Parameters ----------- y_pred : sequence Predictions you want to compare to with different methods. y_true: sequence True values method: {'naive', 'exp_smooth', 'mean', 'median', 'constant'} The method used to generate y_method which is predictions to compare to predictions of your method X_test: pd.Dataframe object, optional Must be provided when using all methods but naive and constant constant: int, optional Must be provided if method arg is set to constant Returns -------- mase_score : range(0,1) The score, that is computed as following - mae(y_true, y_pred)/mae(y_true, y_method). For example if method is 'naive' and mase score is 0.25, that means that your method is 4 times more accurate, then the naive one. """ y_method = y_pred if method is 'naive': y_method = y_true.shift() y_method.fillna(y_method.mean(), inplace=True) if method is not 'naive': if X_test is None: print('You should provide X_test to evaluate predict') X_test.drop([label for label in X_test.columns if 'lag_' in label], inplace=True, axis=1) if method is 'exp_smooth': num_lags = len(X_test.columns) y_method = [ hw.additive(list(lags[1].values), num_lags, 1)[0][0] for lags in X_test.iterrows() ] if method is 'mean': y_method = X_test.mean(axis=1).values if method is 'median': y_method = X_test.mean(axis=1).values if method is 'constant': y_method = np.full(y_true.shape, constant) return mae(y_true, y_pred) / mae(y_true, y_method) # todo fix division by zero
def fit(self, x, y=None): results = holtwinters.additive(x, self.periodicity, self.forecasts, alpha=self.kwargs.get('alpha'), beta=self.kwargs.get('beta'), gamma=self.kwargs.get('gamma')) self.params = { 'alpha': results[1], 'beta': results[2], 'gamma': results[3] } self.rmse = results[4] return { 'alpha': results[1], 'beta': results[2], 'gamma': results[3], 'RMSE': self.rmse }
def forecast(self, fc_steps): ''' Returns a pandas series containing the forecast of the data fc_steps steps out Arguments: fc_steps: How many steps out the Forecaster should predict Returns: A pandas series containing the forecasts ''' results = hw.additive(self.ts.tolist(), self.m, fc_steps, self.alpha, self.beta, self.gamma) fc = map((lambda x: 0 if math.ceil(x) < 0 else math.ceil(x)), results[0]) start = self.ts.index.max() end = start + relativedelta.relativedelta(hours=fc_steps) date_index = pd.date_range(start, end, freq='H') return pd.Series(fc, index=date_index[1:])
def holt_pred_test(steps,path,func): index_name,my_trend = parse_csv(path) if func == 'additive': future, alpha, beta, gamma, rmse = additive(my_trend[-5*52:-steps],52,steps) if func == 'multi': future, alpha, beta, gamma, rmse = multiplicative(my_trend[-5*52:-steps],52,steps) y_pred = np.array(future) y_true = np.array(my_trend[-steps:]) metrics_result = {'sarima_MAE':metrics.mean_absolute_error(y_true, y_pred),'sarima_MSE':metrics.mean_squared_error(y_true, y_pred), 'sarima_MAPE':np.mean(np.abs((y_true - y_pred) / y_true)) * 100} p1 = plt.plot(my_trend[-steps:],'*-') p2 = plt.plot(future) # p1 = plt.plot(index_name,my_trend,'r-') # p2 = plt.plot(index_name_future,future,'g-') plt.ylabel('Search Intensity') plt.xlabel('Year') plt.title('Search Prediction of '+path.split('/')[-1][:-4]) plt.legend((p1[0], p2[0]), ["Actual","Predicted"], loc=1) plt.grid(True) # print metrics_result['sarima_MAPE'] return metrics_result['sarima_MAPE']
773, 592, 627, 725, 854, 661] if __name__ == '__main__': forecastCount = 12 x = np.array([i for i in range(0, len(data)+forecastCount)]) linearfc = np.zeros([1,len(data)+forecastCount]) additivefc = np.zeros([1,len(data)+forecastCount]) multiplefc = np.zeros([1,len(data)+forecastCount]) for i in range(2, len(data)): forecast, alpha, beta, rmse = hw.linear(data[:i], 1) linearfc[0, i:i+len(forecast)] = forecast if i>4: forecast, alpha, beta, gamma, rmse = hw.additive(data[:i], m=4, fc=1) additivefc[0, i:i+len(forecast)] = forecast forecast, alpha, beta, gamma, rmse = hw.multiplicative(data[:i], m=4, fc=1) multiplefc[0, i:i+len(forecast)] = forecast else: forecast, alpha, beta, gamma, rmse = hw.additive(data[:i], m=1, fc=1) additivefc[0, i:i+len(forecast)] = forecast forecast, alpha, beta, gamma, rmse = hw.multiplicative(data[:i], m=1, fc=1) multiplefc[0, i:i+len(forecast)] = forecast # Linear forecast, alpha, beta, rmse = hw.linear(data, forecastCount) linearfc[0,-forecastCount:] = forecast
def predict(self, X): return holtwinters.additive(X, self.periodicity, self.forecasts, **self.params)[0]
plt.ylabel('house price') plt.title('Additive Holt winters forecasts') # use the data from Apr 2007 to Mar 2017 as training set, Apr 2017 to Mar 2018 as testing set from holtwinters import linear from holtwinters import additive from holtwinters import multiplicative # Now we define how many predictions we wish to predict fc = 12 # One year forecasting # Now we define season length h = 12 #split the original time series by train set and test set train = y[:-12] test = y[-12:] x1 = x[:-12] #the additive method forecasting y_smoothed_additive, y_forecast_vals_additive, alpha, beta, gamma,rmse = hw.additive(train.tolist(), fc=fc, m=h) plt.plot(np.hstack((x1,xp)),y_smoothed_additive[:-1], c = 'red',label="Additive forecasts") plt.plot(xp,test,c = 'green',label='test set') plt.legend() print(alpha,beta,gamma) #the multiplicative method forecasting plt.figure(figsize = (12,8)) plt.plot(x,y,label='train set') plt.xlabel('time span') plt.ylabel('house price') plt.title('Multiplicative Holt winters forecasts') y_smoothed_mult, y_forecast_vals_Multi, alpha, beta, gamma,rmse = hw.multiplicative(train.tolist(), fc=fc, m=h) plt.plot(np.hstack((x1,xp)),y_smoothed_mult[:-1], c = 'red',label="Multiplicitive forecasts") plt.plot(xp,test,c = 'green',label='test set') plt.legend() print(alpha,beta,gamma)
plt.plot(xp, t_smoothed[:-1], '-r', label='Smoothed') plt.title('Visitor Arrivals (2010-2016): alpha = ' + str(np.round(alpha, 2)) + ', gamma = ' + str(np.round(gamma, 2))) plt.xlabel('Year') plt.ylabel('Number of Visitors') plt.legend(loc=2) # The second part # Now we define how many predictions we wish to predict fc = 12 # One year forecasting M = 12 # Number of seasons # Let us try the Holt-Winters's Additive Method, # We are not going to define alpha, beta and gamma and the program will find the best s_smoothed, Ys, s, alpha, beta, gamma, rmse = ht.additive(ts, M, fc, alpha=None, beta=None, gamma=None) # The output Ys contains the fc predictions # alpha, beta, gamma are the optimal parameter values found by the program # rmse is the RMSE of the one-step prediction #preparing the second figure fig4 = plt.figure() plt.plot(x, ts, label='Observed') plt.plot(xp, s_smoothed[:-1], '-r', label='Smoothed') plt.title('Visitor Arrivals (2010-2016): alpha = ' + str(np.round(alpha, 2)) + ', beta = ' + str(np.round(beta, 2)) + ', gamma = ' + str(np.round(gamma, 2))) plt.xlabel('Year') plt.ylabel('Number of Visitors') plt.legend(loc=2)
# In[369]: test.NDVI_rec.plot() # In[640]: data = test.NDVI_rec.as_matrix() data = data.tolist() fcast_days = 900 # In[685]: #middle_predictions, alpha, beta, gamma, rmse = hw.multiplicative(data,365, fcast_days, alpha = 0.04, beta = 0.0, gamma=0.01) middle_predictions, alpha, beta, gamma, rmse = hw.additive(signal.detrend(test.NDVI_rec).tolist(), 365, fcast_days, alpha = 0.0001, beta = 0.0001, gamma=0.95) # In[686]: pred_error_level = 0.95 cum_error = [beta+alpha] for k in range(1,fcast_days): cum_error.append(cum_error[k-1] + k*beta + alpha) cum_error = np.array(cum_error) #Use some numpy multiplication to get the intervals var = cum_error * rmse**2 # find the correct ppf on the normal distribution (two-sided) p = abs(scipy.stats.norm.ppf((1 - pred_error_level)/2)) interval = np.sqrt(var) * p
] if __name__ == '__main__': forecastCount = 12 x = np.array([i for i in range(0, len(data) + forecastCount)]) linearfc = np.zeros([1, len(data) + forecastCount]) additivefc = np.zeros([1, len(data) + forecastCount]) multiplefc = np.zeros([1, len(data) + forecastCount]) for i in range(2, len(data)): forecast, alpha, beta, rmse = hw.linear(data[:i], 1) linearfc[0, i:i + len(forecast)] = forecast if i > 4: forecast, alpha, beta, gamma, rmse = hw.additive(data[:i], m=4, fc=1) additivefc[0, i:i + len(forecast)] = forecast forecast, alpha, beta, gamma, rmse = hw.multiplicative(data[:i], m=4, fc=1) multiplefc[0, i:i + len(forecast)] = forecast else: forecast, alpha, beta, gamma, rmse = hw.additive(data[:i], m=1, fc=1) additivefc[0, i:i + len(forecast)] = forecast forecast, alpha, beta, gamma, rmse = hw.multiplicative(data[:i], m=1,