Python Tutorial: Forecasting
2019-09-01 22:04 nuswgg 阅读(464) 评论(0) 编辑 收藏 举报8.1 Fit an ARIMA model to a timeseries.
a) Plot the timeseries.
# Read in new data set
air = pd.read_csv('/Users/air.csv')
air["DATE"] = pd.to_datetime(air["DATE"], infer_datetime_format = True)
air.index = air["DATE"].values
plt.plot(air.index, air["AIR"])
plt.show()
b) Fit an ARIMA model and predict 2 years (24 months).
import pyflux as pf
# ar = 12 is necessary to indicate the seasonality of data
model = pf.ARIMA(data = air, ar = 12, ma = 1, integ = 0, target = 'AIR',family = pf.Normal())
x = model.fit("MLE")
model.plot_predict(h = 24)
8.2 Fit a Simple Exponential Smoothing model to a timeseries.
a) Plot the timeseries.
# Read in new data set
usecon = pd.read_csv('/Users/usecon.csv')
petrol = usecon["PETROL"]
plt.plot(petrol)
plt.show()
b) Fit a Simple Exponential Smoothing model, predict 2 years (24 months) out and plot predictions.
Currently, there is not a good package in Python to fit a simple exponential smoothing model. The formula for fitting an exponential smoothing model is not difficult, so we can do it by creating our own functions in Python.
The simplest form of exponential smoothing is given by, (where t > 0):
s0 = x0
st = α xt + (1 - α) st-1
Therefore, we can implement a simple exponential smoothing model as follows:
def simple_exp_smoothing(data, alpha, n_preds):
# Eq1:
output = [data[0]]
# Smooth given data plus we want to predict 24 units
# past the end
for i in range(1, len(data) + n_preds):
# Eq2:
if (i < len(data)):
output.append(alpha * data[i] + (1 - alpha) * data[i-1])
else:
output.append(alpha * output[i-1] + (1 - alpha) * output[i-2])
return output
pred = simple_exp_smoothing(petrol, 0.9999, 24)
plt.plot(pd.DataFrame(pred), color = "red")
plt.plot(petrol, color = "blue")
plt.show()
8.3 Fit a Holt-Winters model to a timeseries.
a) Plot the timeseries.
vehicle = usecon["VEHICLES"]
plt.plot(vehicle)
plt.show()
b) Fit a Holt-Winters additive model, predict 2 years (24 months) out and plot predictions.
Currently, there is not a good package in Python to fit a Holt-Winters additive model. The formula for fitting a Holt-Winters additive model is not difficult, so we can do it by creating our own functions in Python.
The following is an implementation of the Holt-Winters additive model given at triple exponential smoothing code.
def initial_trend(series, slen):
sum = 0.0
for i in range(slen):
sum += float(series[i+slen] - series[i]) / slen
return sum / slen
def initial_seasonal_components(series, slen):
seasonals = {}
season_averages = []
n_seasons = int(len(series)/slen)
# compute season averages
for j in range(n_seasons):
season_averages.append(sum(series[slen*j:slen*j+slen])/float(slen))
# compute initial values
for i in range(slen):
sum_of_vals_over_avg = 0.0
for j in range(n_seasons):
sum_of_vals_over_avg += series[slen*j+i]-season_averages[j]
seasonals[i] = sum_of_vals_over_avg/n_seasons
return seasonals
def triple_exponential_smoothing_add(series, slen, alpha, beta, gamma,
n_preds):
result = []
seasonals = initial_seasonal_components(series, slen)
for i in range(len(series)+n_preds):
if i == 0: # initial values
smooth = series[0]
trend = initial_trend(series, slen)
result.append(series[0])
continue
if i >= len(series): # we are forecasting
m = i - len(series) + 1
result.append((smooth + m*trend) + seasonals[i%slen])
else:
val = series[i]
last_smooth, smooth = smooth, alpha*(val-seasonals[i%slen])
+ (1-alpha)*(smooth+trend)
trend = beta * (smooth-last_smooth) + (1-beta)*trend
seasonals[i%slen] = gamma*(val-smooth) +
(1-gamma)*seasonals[i%slen]
result.append(smooth+trend+seasonals[i%slen])
return result
add_preds = triple_exponential_smoothing_add(vehicle, 12, 0.5731265, 0,
0.7230956, 24)
plt.plot(pd.DataFrame(add_preds), color = "red")
plt.plot(vehicle, color = "blue")
plt.show()
8.4 Fit a Facebook Prophet forecasting model to a timeseries.
from fbprophet import Prophet
air = pd.read_csv("/Users/air.csv")
air_df = pd.DataFrame()
air_df["ds"] = pd.to_datetime(air["DATE"], infer_datetime_format = True)
air_df["y"] = air["AIR"]
m = Prophet(yearly_seasonality = True, weekly_seasonality = False)
m.fit(air_df)
future = m.make_future_dataframe(periods = 24, freq = "M")
forecast = m.predict(future)
m.plot(forecast)