ARMA model¶

We will deploy an ARMA(2,1) model. During the implementation we tried different orders of AR and MA. With those values we had the best performance so that to not overfit or underfit to the training set.

In [ ]:
from statsmodels.tsa.arima_model import ARMA
preds=[]
for l in timeseries1[test_ix]['price'].index:
    data=timeseries1['price'][timeseries1.index<l]
    model=ARMA(data, order=(2, 1))   #Here is where you tell ARMA what the order is
    arma=model.fit()
    
    preds.append(arma.forecast()[0])
    
y_pred=np.array(preds).T[0]

Functions to plot observed and predicted values and functions for errors¶

In [68]:
def plotprediction(series, pred_series, labels=["original", "predicted"], x_axis=None, plot_intervals=False, scale=1.96, plot_anomalies=False, title="prediction"):

    plt.figure(figsize=(15,5))
    plt.title(title)
    if x_axis is None:
        x_axis=series.index
    
    plt.plot(x_axis, pred_series, "g", label=labels[1])
    plt.plot(x_axis, series, label=labels[0])
    

    # Plot confidence intervals for smoothed values

    plt.legend(loc="upper left")
    plt.grid(True)

def mean_absolute_percentage_error(y_true, y_pred): 
    return np.mean(np.abs((y_true - y_pred) / y_true)) * 100

def print_stats(y_test, y_preds, title="You forgot the title!"):
    print(title+": ")
    print("\tr^2=%f"%r2_score(y_test,y_preds))
    print("\tMAE=%f"%mean_absolute_error(y_test,y_preds))
    print("\tMAPE=%f"%mean_absolute_percentage_error(y_test,y_preds))
In [69]:
print_stats(timeseries1[test_ix]['price'],y_pred,title= "ARMA(2,1)")
ARMA(2,1): 
	r^2=0.384368
	MAE=6252.096824
	MAPE=27.456184
In [70]:
plotprediction(timeseries1[test_ix]['price'], y_pred, labels=['observed', 'prediction'], title="observed vs prediction")

Train model to the whole dataset¶

In [71]:
date_idx = pd.date_range(timeseries1.index[-1]+ datetime.timedelta(days=1), periods=31, freq='D')
# Create new dataframe to store the predicted values
proje = pd.DataFrame(index=date_idx, columns=["price"])
timeseries_new = pd.concat([timeseries1,proje])
In [72]:
test_idx =timeseries_new[timeseries_new.isna().values].index
preds=[]
for l in test_idx:
    data=timeseries_new['price'][timeseries_new.index<l]
    model=ARMA(data, order=(2, 1))   #Here is where you tell ARMA what the order is
    arma=model.fit()
    
    preds.append(arma.forecast()[0])
    timeseries_new.loc[l,"price"]=arma.forecast()[0]
    
y_pred=np.array(preds).T[0]

Plot one month prediction with ARIMA¶

In [ ]:
fig = px.line(timeseries_new, x=timeseries_new.index, y=['price'], title = '1-Month Prediction')
fig.add_vrect(
    x0=test_idx[0], x1=test_idx[-1],
    fillcolor="LightSalmon", opacity=0.5,
    layer="below", line_width=0,
)
fig.show()

image.png

In [ ]: