(Zusatz) In der zweiten Hälfte dieses Artikels habe ich einen Korrekturartikel über Random Rorest Regression veröffentlicht. Siehe auch hier. Was Sie bei der Analyse von Zeitreihendaten (einschließlich Reflexion) nicht tun sollten
Bei der Durchführung von Zeitreihendatenanalysen mit Python ist möglicherweise das von StatsModels für die statistische Modellierung bereitgestellte Modul zur Analyse von Zeitreihen (tsa) die erste Option. Darüber hinaus verfügt die maschinelle Lernbibliothek Scikit-learn über Decision Tree Regression und Random Forest Regression, die Regressionen basierend auf verschiedenen Konzepten durchführen. Daher wollte ich diese ebenfalls ausprobieren und vergleichen.
(Programmierumgebung: Python 2.7.11, Pandas 0.18.0, StatsModels 0.6.1, Scikit-learn 0.17.1.)
Wenn Sie die Literatur zur Zeitreihendatenanalyse öffnen, werden die Erklärungen häufig in der folgenden Reihenfolge angezeigt.
Abkürzung | Erläuterung |
---|---|
AR | Selbstrückkehr(Auto Regression)Modell- |
MA | gleitender Durchschnitt(Moving Average)Modell- |
ARMA | Selbstkehrendes Modell mit gleitendem Durchschnitt |
ARIMA | Modell des gleitenden Durchschnitts der Selbstrückgabesumme |
Einzelheiten zu jedem Modell finden Sie in Wikipedia usw. Grundsätzlich ist ** ARMA ** ein Modell, das ** AR ** und ** MA ** enthält, und ** ARIMA ** ist * Da es sich um ein Modell handelt, das * ARMA ** enthält, können alle oben genannten vier Modelle unterstützt werden, wenn ** ARIMA ** als Bibliothek unterstützt wird. StatsModels bietet jedoch ** AR **, ** ARMA **, ** ARIMA ** als APIs.
http://statsmodels.sourceforge.net/stable/tsa.html
Dieses Mal wurde "Nil" als zu analysierende Daten verwendet.
Nile River flows at Ashwan 1871-1970 This dataset contains measurements on the annual flow of the Nile as measured at Ashwan for 100 years from 1871-1970. There is an apparent changepoint near 1898.
Dies sind die jährlichen Daten des Nilflusses in Afrika und die Beispieldaten, die in der StatsModel-Bibliothek erstellt wurden.
In vielen Fällen ist "Stationarität" eine Voraussetzung für die Anwendung des Modells im Self-Return-Modell. Da das obige Diagramm jedoch keine monotone Zunahme oder Abnahme zeigt, haben wir uns für die Anwendung des ** ARMA ** -Modells entschieden. Machen.
Da es sich um Zeitreihendaten für etwa 100 Jahre handelt, werden wir 70 Jahre für die erste Hälfte als Daten für die Anpassung (für die Ausbildung) und 30 Jahre für die zweite Hälfte als Daten für die Modellprüfung zuweisen. Es ist notwendig, die Reihenfolge (p, q) des ARMA-Modells auszuwählen. Zeichnen wir zunächst das ACF-Diagramm (Autokorrelationsfunktionsdiagramm) und das PACF-Diagramm (partielles Autokorrelationsdiagramm), die auch als Cholerogramme bezeichnet werden.
def load_data():
df_read = sm.datasets.nile.load_pandas().data
s_date = pd.Series(
[pd.to_datetime(str(int(y_str))) for y_str in df_read['year']]
)
df = df_read.set_index(s_date)
df = df.drop('year', axis=1)
return df
df_nile = load_data()
# Plot Time Series Data
ax = df_nile['volume'].plot(figsize=(8,4), grid=True)
ax.set_xlabel('year')
ax.set_ylabel('volume x 10^8 m^3')
plt.show()
# Data Split (70: 30)
# ACF, PACF
fig = plt.figure(figsize=(12,8))
ax1 = fig.add_subplot(211)
fig = sm.graphics.tsa.plot_acf(df_train.values, lags=40, ax=ax1)
ax2 = fig.add_subplot(212)
fig = sm.graphics.tsa.plot_pacf(df_train.values, lags=40, ax=ax2)
Fig. ACF and PACF plot of "Nile" data
In ARMA (p, q) kann q = [0, 1, 2, 3] aus dem ACF-Diagramm (oben) und p = [0, 1] aus dem PACF-Diagramm (unten) ausgewählt werden ( Irgendwie verstehe ich. Unter Berücksichtigung der Tatsache, dass ARMA (p = 1, q = 3) berücksichtigt wird und die Informationen vom Dienstprogramm zur Auftragsauswahl ausgegeben werden, ist das Ergebnis vorerst wie folgt.
info_criteria = sm.tsa.stattools.arma_order_select_ic(
df_train.values, ic=['aic', 'bic']
)
print(info_criteria.aic_min_order)
print(info_criteria.bic_min_order)
ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
"Check mle_retvals", ConvergenceWarning)
>>> (1, 1)
>>> (1, 0)
Beachten Sie, dass eine Warnung zur Konvergenz angezeigt wird. Basierend auf der Warnung haben wir Informationen erhalten, dass ARMA (1, 1) von AIC (Modellauswahlreferenzwert) und AMMA (1, 0) von BIC (Modellauswahlreferenzwert) gut ist. Passen wir daher diese beiden Modelle an die Daten an.
arma_10 = sm.tsa.ARMA(df_train, (1, 0)).fit()
arma_11 = sm.tsa.ARMA(df_train, (1, 1)).fit()
Dies wurde ohne besonderen Fehler oder Warnung verarbeitet. Die Rückgabewerte arma_10 und arma_11 sind nach dem Anpassen Modellobjekte (ARMAResults-Klasse). Vorerst habe ich auch Modelle höherer Ordnung ARMA (1, 2) und ARMA (1, 3) ausprobiert.
arma_12 = sm.tsa.ARMA(df_train, (1, 2)).fit()
arma_13 = sm.tsa.ARMA(df_train, (1, 3)).fit()
(Ausgelassen, Traceback-Informationen usw.)
ValueError: The computed initial AR coefficients are not stationary
You should induce stationarity, choose a different model order, or you can
pass your own start_params.
Der obige Wertefehler ist aufgetreten. (Obwohl in der Fehlermeldung stationär erwähnt wird ...) Es gibt ein Problem mit der Konvergenz bei der Berechnung von Parametern, und es ist schwierig, auf ARMA (1, 2) und ARMA (1, 3) anzuwenden. Gibt es. In Zukunft wird diese Ursache möglicherweise eingehend untersucht, aber dieses Mal lautet das Thema ARMA vs. Random Forest Regressor. Daher werden wir die Verwendung von ARMA (1, 0) und ARMA (1, 1) in Betracht ziehen, die angepasst werden können. Vorgehen.
Überprüfen Sie zunächst den Wert von AIC.
print('ARMA(1,0): AIC = %.2f' % arma_10.aic)
print('ARMA(1,1): AIC = %.2f' % arma_11.aic)
>>> ARMA(1,0): AIC = 910.94
>>> ARMA(1,1): AIC = 908.92
Der AIC-Wert ist im ARMA-Modell (1, 1) kleiner.
Als nächstes werden die Modellschätzungen für den Trainingsdatenabschnitt (70 Jahre) und die Modellschätzungen für den nachfolgenden Testabschnitt (30 Jahre) berechnet.
# in-sample predict
arma_10_inpred = arma_10.predict(start='1871-01-01', end='1940-01-01')
arma_11_inpred = arma_11.predict(start='1871-01-01', end='1940-01-01')
# out-of-sample predict
arma_10_outpred = arma_10.predict(start='1941-01-01', end='1970-01-01')
arma_11_outpred = arma_11.predict(start='1941-01-01', end='1970-01-01')
Sowohl die AIC-Berechnung als auch die Schätzwertberechnung können nach der Methode der ARMA-Modellergebnisklasse (ARMAResults-Klasse) erhalten werden. Zeichnen Sie die Werte der Originaldaten und die geschätzten Werte zusammen.
# plot data and predicted values
def plot_ARMA_results(origdata, pred10in, pred10out, pred11in, pred11out):
px = origdata.index
py1 = origdata.values
plt.plot(px, py1, 'b:', label='orig data')
px_in = pred10in.index
plt.plot(px_in, pred10in.values, 'g')
plt.plot(px_in, pred11in.values, 'c')
px_out = pred10out.index
plt.plot(px_out, pred10out.values, 'g', label='ARMA(1,0)')
plt.plot(px_out, pred11out.values, 'c', label='ARMA(1,1)')
plt.legend()
plt.grid(True)
plt.show()
plot_ARMA_results(df_nile, arma_10_inpred, arma_10_outpred,
arma_11_inpred, arma_11_outpred)
Fig. Nile data - original data and ARMA estimated data
Der Trainingsabschnitt (In-Sample) ist von 1870 bis 1940, und der Testabschnitt (Out-of-Sample) ist danach. Es ist ein wenig schwer zu verstehen, aber irgendwie scheint ARMA (1,1) näher an den tatsächlichen Daten zu sein. MSE (Mean Squared Error) wird aus den Residuen für den späteren Modellvergleich erhalten.
# Residue (mse for train)
arma_10_mse_tr = np.array([r ** 2 for r in arma_10.resid]).mean()
arma_11_mse_tr = np.array([r ** 2 for r in arma_11.resid]).mean()
# Residue (mse for test)
arma_10_mse_te = np.array([(df_test.values[i] - arma_10_outpred[i]) **2
for i in range(30)]).mean()
arma_11_mse_te = np.array([(df_test.values[i] - arma_11_outpred[i]) **2
for i in range(30)]).mean()
Die Grundlage der Random Forest-Regression ist die Decision Tree Regression. Es scheint, dass der Entscheidungsbaumalgorithmus selbst grob verstanden werden muss, aber in diesem Artikel wird die Erklärung weggelassen und die Funktion von Scikit-learn wird als Black Box behandelt. Es gibt ein Beispiel im Scikit-Lerndokument, aber das Ergebnis des Versuchs wird unten gezeigt.
Fig. Decision Tree Regression Example
Das Merkmal ist, dass es in eine gestufte gerade Linie passt. Diesmal handelt es sich um univariate Zeitreihendaten, aber ich habe versucht, den aktuellen Wert anhand einiger früherer Daten als Modell zu schätzen. Speziell,
Volume_current ~ Volume_Lag1 + Volume_Lag2 + Volume_Lag3
Dies ist das Modell. Ich wollte die Trainingsdaten und Testdaten wie beim letzten Mal (70, 30) machen, aber da NaN bei der Berechnung des Lag-Werts erscheint, dropna () den ersten Teil und setze die Datenlänge auf (67, 30). tat.
Zunächst werden Daten vorverarbeitet.
df_nile['lag1'] = df_nile['volume'].shift(1)
df_nile['lag2'] = df_nile['volume'].shift(2)
df_nile['lag3'] = df_nile['volume'].shift(3)
df_nile = df_nile.dropna()
X_train = df_nile[['lag1', 'lag2', 'lag3']][:67].values
X_test = df_nile[['lag1', 'lag2', 'lag3']][67:].values
y_train = df_nile['volume'][:67].values
y_test = df_nile['volume'][67:].values
Verwenden Sie Random Forest Regressor von Scikit-learn.
from sklearn.ensemble import RandomForestRegressor
r_forest = RandomForestRegressor(
n_estimators=100,
criterion='mse',
random_state=1,
n_jobs=-1
)
r_forest.fit(X_train, y_train)
y_train_pred = r_forest.predict(X_train)
y_test_pred = r_forest.predict(X_test)
Die geschätzten Werte sind in der folgenden Abbildung dargestellt.
Fig. Nile data - original data and Random Forest Regression results
Berechnen Sie abschließend MSE.
# check residue (mse)
train_resid = y_train - y_train_pred
RFR_mse_train = np.array([r ** 2 for r in train_resid]).mean()
test_resid = y_test - y_test_pred
RFR_mse_test = np.array([r ** 2 for r in test_resid]).mean()
Vergleichen Sie die MSE (Mean Squared Error) jedes Modells.
Model | MSE of in-samle (train) | MSE of out-of-sample (test) |
---|---|---|
ARMA(1,0) | 24111.0 | 18684.4 |
ARMA(1,1) | 22757.3 | 16625.8 |
Random F. Regressor | 3470.1 | 15400.3 |
(MSE : smaller ... better)
Beim Vergleich von ARMA-Modellen mit unterschiedlichen Ordnungen ist ersichtlich, dass ARMA (1,1) sowohl im Trainingsabschnitt als auch im Testabschnitt eine kleinere MSE und eine bessere Genauigkeit aufweist, was mit dem Vergleich der zuvor erhaltenen AIC-Werte übereinstimmt. Es gibt.
Im Vergleich zwischen dem ARMA-Modell und dem Random Forest-Regressionsmodell ist die MSE der Random Forest-Regression klein, mit einem großen Unterschied im Trainingsabschnitt. Die Random Forest-Regression ist im Testabschnitt ebenfalls gering, der Unterschied beträgt jedoch etwa 7%. Die zufällige Waldregression ist hinsichtlich der Genauigkeit vorteilhaft, es sollte jedoch berücksichtigt werden, dass das ARMA-Modell, auf das das statistische Modell angewendet wird, zusätzlich zum vorhergesagten Medianwert Informationen zum Konfidenzintervall (z. B. 95% -Konfidenzintervall) erhalten kann. Ist fertig. Ich möchte es entsprechend dem Zweck richtig verwenden.
(Beim Vergleich der Diagramme der ARMA- und Random Forest-Regression war ich erneut überrascht, dass die Linien sehr unterschiedlich aussehen. Beachten Sie auch, dass keines der Modelle ausreichende Parameteranpassungen hatte. Bitte gib mir.)
Recommended Posts