Saltar al contenido

Pronóstico utilizando la causalidad de Granger y el modelo auto-regresivo vectorial

septiembre 23, 2021
112VqcJcuJjzzS8dYGw3nCg

MODELADO PREDICTIVO Y ANÁLISIS ESTADÍSTICO

Pronóstico utilizando la causalidad de Granger y el modelo auto-regresivo vectorial

Modelo econométrico y datos de series de tiempo

Sarit Maitra

7 de oct de 2019·11 min de lectura

FORECASTING de Oro y Petróleo han atraído la mayor atención de académicos, inversores y agencias gubernamentales como. Estos dos productos son conocidos por su influencia sustancial en la economía global. Mostraré aquí, cómo usar Prueba de causalidad de Granger para probar las relaciones de múltiples variables en la serie de tiempo y Modelo vectorial auto regresivo (VAR) para pronosticar el futuro Oro y Petróleo precios de los datos históricos de Precios del oro, precios de la plata, precios del petróleo crudo, índice bursátil, tasa de interés y tasa en USD.

los Oro precios are estrechamente relacionado con otros productos básicos. Una caminata en Petróleo los precios tendrán un impacto positivo en Oro precios y viceversa. Históricamente, hemos visto que, cuando hay un alza en las acciones, Oro los precios bajan.

  • Formulación de problemas de predicción de series de tiempo
  • Predicción de series de tiempo de series de tiempo univariadas y multivariadas
  • Solicitar VAR a este problema

Entendamos cómo se formula una serie de tiempo multivariante. A continuación se muestran las ecuaciones K simples de series de tiempo multivariadas donde cada ecuación es un rezago de la otra serie. X es la serie exógena aquí. El objetivo es ver si la serie se ve afectada por su propio pasado y también por el pasado de la otra serie.

Este tipo de series nos permite modelar la dinámica de la propia serie y también la interdependencia de otras series. Exploraremos esta interdependencia a través de Análisis de causalidad de Granger.

Análisis exploratorio:

Carguemos los datos y hagamos un análisis con visualización para conocer los conocimientos de los datos. El análisis de datos exploratorios es bastante extenso en series de tiempo multivariadas. Cubriré algunas áreas aquí para obtener información sobre los datos. Sin embargo, es recomendable realizar todas las pruebas estadísticas para asegurar nuestra comprensión clara de la distribución de datos.

Fijemos las fechas de todas las series.

Los valores de NaN en los datos se completan con los datos de días anteriores. Después de realizar un procesamiento previo necesario, el conjunto de datos ahora se limpia para un análisis más detallado.

# Plot
fig, axes = plt.subplots(nrows=3, ncols=2, dpi=120, figsize=(10,6))
for i, ax in enumerate(axes.flatten()):
data = dataset[dataset.columns[i]]
ax.plot(data, color=’red’, linewidth=1)
ax.set_title(dataset.columns[i])
ax.xaxis.set_ticks_position(‘none’)
ax.yaxis.set_ticks_position(‘none’)
ax.spines[“top”].set_alpha(0)
ax.tick_params(labelsize=6)
plt.tight_layout();

De los gráficos anteriores, podemos concluir visiblemente que, todas las series contienen raíz unitaria con tendencia estocástica que muestra un patrón sistemático que es impredecible.

Para extraer la máxima información de nuestros datos, es importante tener una distribución normal o gaussiana de los datos. Para comprobarlo, hemos realizado una prueba de normalidad basada en la intuición de hipótesis nula y alternativa.

stat,p = stats.normaltest(dataset.Gold)
print("Statistics = %.3f, p=%.3f" % (stat,p))
alpha = 0.05
if p> alpha:
print('Data looks Gaussian (fail to reject null hypothesis)')
else:
print('Data looks non-Gaussian (reject null hypothesis')
output: Statistics = 658.293, p=0.000 Data looks Gaussian (reject null hypothesis

Estas dos distribuciones nos dan cierta intuición sobre la distribución de nuestros datos. La curtosis de este conjunto de datos es -0,95. Dado que este valor es menor que 0, se considera un conjunto de datos de cola ligera. Tiene tantos datos en cada cola como en el pico. La asimetría moderada se refiere al valor entre -1 y -0,5 o 0,5 y 1.

plt.figure(figsize=(14,6))
plt.subplot(1,2,1)
dataset['Gold'].hist(bins=50)
plt.title('Gold')
plt.subplot(1,2,2)
stats.probplot(dataset['Gold'], plot=plt);
dataset.Gold.describe().T

La gráfica de probabilidad normal también muestra que los datos están lejos de estar distribuidos normalmente.

Autocorrelación:

La autocorrelación o la correlación en serie pueden ser un problema importante en el análisis de datos históricos si no sabemos cómo buscarlos.

# plots the autocorrelation plots for each stock's price at 50 lags
for i in dataset:
plt_acf(dataset[i], lags = 50)
plt.title('ACF for %s' % i)
plt.show()

Vemos aquí, en los gráficos anteriores, la autocorrelación de +1, que representa una correlación positiva perfecta, lo que significa que un aumento observado en una serie de tiempo conduce a un aumento proporcional en la otra serie de tiempo. Definitivamente necesitamos aplicar la transformación y neutralizar esto para hacer que la serie sea estacionaria. Mide relaciones lineales; incluso si la autocorrelación es minúscula, todavía puede haber una relación no lineal entre una serie de tiempo y una versión retrasada de sí misma.

Datos de entrenamiento y prueba:

El modelo VAR se ajustará en X_train y luego se utilizará para pronosticar las próximas 15 observaciones. Estos pronósticos se compararán con el presente real en los datos de prueba.

n_obs=15
X_train, X_test = dataset[0:-n_obs], dataset[-n_obs:]
print(X_train.shape, X_test.shape)
(5114, 6) (15, 6)

Transformación:

Aplicar la primera diferenciación en el set de entrenamiento para hacer estacionaria toda la serie. Sin embargo, este es un proceso iterativo en el que, después de la primera diferenciación, es posible que la serie siga siendo no estacionaria. Tendremos que aplicar una segunda diferencia o transformación logarítmica para estandarizar la serie en tales casos.

Comprobación de estacionariedad:

def augmented_dickey_fuller_statistics(time_series):
result = adfuller(time_series.values)
print('ADF Statistic: %f' % result[0])
print('p-value: %f' % result[1])
print('Critical Values:')
for key, value in result[4].items():
print('t%s: %.3f' % (key, value))
print('Augmented Dickey-Fuller Test: Gold Price Time Series')
augmented_dickey_fuller_statistics(X_train_transformed['Gold'])
print('Augmented Dickey-Fuller Test: Silver Price Time Series')
augmented_dickey_fuller_statistics(X_train_transformed['Silver'])
print('Augmented Dickey-Fuller Test: Oil Price Time Series')
augmented_dickey_fuller_statistics(X_train_transformed['Oil'])
print('Augmented Dickey-Fuller Test: Interest_rate Time Series')
augmented_dickey_fuller_statistics(X_train_transformed['Interest_rate'])
print('Augmented Dickey-Fuller Test: Stock_Index Time Series')
augmented_dickey_fuller_statistics(X_train_transformed['Stock_Index'])
print('Augmented Dickey-Fuller Test: USD_Index Time Series')
augmented_dickey_fuller_statistics(X_train_transformed['USD_Index'])
fig, axes = plt.subplots(nrows=3, ncols=2, dpi=120, figsize=(10,6))
for i, ax in enumerate(axes.flatten()):
d = X_train_transformed[X_train_transformed.columns[i]]
ax.plot(d, color='red', linewidth=1)
# Decorations
ax.set_title(dataset.columns[i])
ax.xaxis.set_ticks_position('none')
ax.yaxis.set_ticks_position('none')
ax.spines['top'].set_alpha(0)
ax.tick_params(labelsize=6)
plt.tight_layout();

Prueba de causalidad de Granger:

La definición formal de causalidad de Granger puede explicarse como si los valores pasados ​​de x ayudan en la predicción de yt, condicional a que ya se hayan contabilizado los efectos sobre yt de los valores pasados ​​de y (y quizás de los valores pasados ​​de otras variables). Si lo hacen, se dice que la x «causa Granger» y. Entonces, la base detrás de VAR es que cada una de las series de tiempo en el sistema se influye entre sí.

Causalidad de Granger Prueba la hipótesis nula de que los coeficientes de valores pasados ​​en la ecuación de regresión son cero. Entonces, si el valor p obtenido de la prueba es menor que el nivel de significancia de 0.05, entonces, puede rechazar con seguridad la hipótesis nula. Esto se ha realizado en el conjunto de datos original.

Debajo del código tomado de desbordamiento de pila.

maxlag=12
test = 'ssr-chi2test'
def grangers_causality_matrix(X_train, variables, test = 'ssr_chi2test', verbose=False):
dataset = pd.DataFrame(np.zeros((len(variables), len(variables))), columns=variables, index=variables)
for c in dataset.columns:
for r in dataset.index:
test_result = grangercausalitytests(X_train[[r,c]], maxlag=maxlag, verbose=False)
p_values = [round(test_result[i+1][0][test][1],4) for i in range(maxlag)]
if verbose: print(f'Y = {r}, X = {c}, P Values = {p_values}')
min_p_value = np.min(p_values)
dataset.loc[r,c] = min_p_value
dataset.columns = [var + '_x' for var in variables]
dataset.index = [var + '_y' for var in variables]
return dataset
grangers_causality_matrix(dataset, variables = dataset.columns)

La fila son la respuesta (y) y las columnas son la serie de predictores (x).

  • Si tomamos el valor 0.0000 en (fila 1, columna 2), se refiere al valor p de la prueba de Causalidad de Granger para Silver_x que causa Gold_y. El 0,0000 en (fila 2, columna 1) se refiere al valor p de Gold_y que causa Silver_x y así sucesivamente.
  • Podemos ver que, en el caso de Interesar y Dólar estadounidense variables, no podemos rechazar la hipótesis nula, p. ej. Dólar estadounidense Y Plata, USD y petróleo. Nuestras variables de interés son Oro y Petróleo aquí. Entonces, para Oro, todos las variables causan pero para Dólar estadounidense no causa ningún efecto en Petróleo.

Entonces, mirando los p-Values, podemos suponer que, excepto USD, todas las demás variables (series de tiempo) en el sistema se causan indistintamente entre sí. Esto justifica el enfoque de modelado VAR para este sistema de predicciones de múltiples series de tiempo.

Modelo VAR:

VAR requiere la estacionariedad de la serie, lo que significa que la media de la serie no cambia con el tiempo (podemos averiguarlo en el gráfico dibujado junto a la Prueba de Dickey-Fuller aumentada).

Entendamos la intuición matemática del modelo VAR.

Aquí, cada serie está modelada por su propio retraso y el retraso de otras series. y {1, t-1, y {2, t-1}…. son el rezago de las series de tiempo y1, y2,…. respectivamente. Las ecuaciones anteriores se denominan modelo VAR (1), porque cada ecuación es de orden 1, es decir, contiene hasta un rezago de cada uno de los predictores (y1, y2,… ..). Dado que los términos y en las ecuaciones están interrelacionados, las y se consideran variables endógenas, en lugar de predictores exógenos. Para frustrar el problema de la inestabilidad estructural, se utilizó el marco VAR eligiendo la longitud del rezago según AIC.

Entonces, ajustaré el modelo VAR en el conjunto de entrenamiento y luego usaré el modelo ajustado para pronosticar las próximas 15 observaciones. Estos pronósticos se compararán con el presente real en los datos de prueba. He tomado el retraso máximo (15) para identificar los retrasos requeridos para el modelo VAR.

mod = smt.VAR(X_train_transformed)
res = mod.fit(maxlags=15, ic='aic')
print(res.summary())

Las mayores correlaciones son 0,38 (plata y oro) y -0,19 (petróleo y USD); sin embargo, son lo suficientemente pequeños como para ignorarlos en este caso.

Parcela residual:

El gráfico residual parece normal con una media constante en todo momento, aparte de una gran fluctuación durante 2009, 2011, 2014, etc.

y_fitted = res.fittedvalues
plt.figure(figsize = (15,5))
plt.plot(residuals, label='resid')
plt.plot(y_fitted, label='VAR prediction')
plt.xlabel('Date')
plt.xticks(rotation=45)
plt.ylabel('Residuals')
plt.grid(True)

Estadística de Durbin-Watson:

La estadística de Durbin-Watson está relacionada con la autocorrelación.

La estadística de Durbin-Watson siempre tendrá un valor entre 0 y 4. Un valor de 2.0 significa que no se detectó autocorrelación en la muestra. Los valores de 0 a menos de 2 indican autocorrelación positiva y los valores de 2 a 4 indican autocorrelación negativa. Una regla general es que los valores estadísticos de prueba en el rango de 1,5 a 2,5 son relativamente normales. Cualquier valor fuera de este rango podría ser motivo de preocupación.

Un precio de la acción que muestre una autocorrelación positiva indicaría que el precio de ayer tiene una correlación positiva con el precio de hoy, por lo que si la acción cayó ayer, también es probable que baje hoy. Una acción que tiene una autocorrelación negativa, por otro lado, tiene una influencia negativa sobre sí misma a lo largo del tiempo, de modo que si cayó ayer, hay una mayor probabilidad de que suba hoy.

No hay…

close