格蘭傑因果模型(Granger Causality Model)是時間序列分析中的一種重要工具,用於檢測兩個變數之間的動態因果關係。該模型由經濟學家克萊夫·格蘭傑於1969年提出,旨在確定一個時間序列變數能否透過其過去的資訊來有效預測另一個變數的變化。格蘭傑因果模型並不代表實際的因果關係,而是透過比較不同迴歸模型中殘差的大小,判斷某一變數的歷史值是否顯著提升了另一變數的預測精度。具體來說,如果引入某一變數的過去值能顯著提高對目標變數的預測效果,則認為該變數格蘭傑導致了目標變數。
格蘭傑因果檢驗在經濟學、金融學等領域廣泛應用,尤其在分析股票市場、貨幣政策和宏觀經濟變數間的相互作用時提供了理論依據。它為研究者提供了一種有效的工具來識別時間序列之間的潛在因果聯絡,併為經濟決策和金融風險管理提供了重要的參考。然而,格蘭傑因果模型只適用於平穩的時間序列,且“因果性”僅指預測能力,實際的因果關係仍需其他工具來驗證。
一、格蘭傑因果檢驗原理
格蘭傑因果檢驗是一種用於確定時間序列變數之間因果關係的統計方法。它基於時間序列的預測能力,而非嚴格的因果關係。該方法由諾貝爾經濟學獎得主克萊夫·格蘭傑提出,廣泛應用於金融市場、宏觀經濟等領域。
如果在給定\(Y\)的歷史資料基礎上,加入\(X\)的歷史資料能夠顯著提高對\(Y\)的預測能力,則稱\(X\)格蘭傑導致\(Y\)。格蘭傑因果性關注的是一個變數過去的資訊對另一個變數的預測能力。
1.1 格蘭傑因果檢驗的數學表達
給定兩個平穩時間序列\(X_t\)和\(Y_t\),透過對比以下兩種迴歸模型來判斷它們之間是否存在因果關係:
- 單變數自迴歸模型:\[Y_t = \alpha_0 + \alpha_1 Y_{t-1} + \alpha_2 Y_{t-2} + \cdots + \alpha_p Y_{t-p} + \epsilon_t \]
- 多變數回歸模型:\[Y_t = \beta_0 + \beta_1 Y_{t-1} + \beta_2 Y_{t-2} + \cdots + \beta_p Y_{t-p} + \gamma_1 X_{t-1} + \gamma_2 X_{t-2} + \cdots + \gamma_q X_{t-q} + \eta_t \]
選擇合適的滯後階數p和q,通常透過資訊準則(如AIC、BIC)來決定。
1.2 格蘭傑因果檢驗步驟
- 平穩性檢驗。進行因果檢驗前,先對資料進行平穩性檢驗,如ADF檢驗或KPSS檢驗。如果資料不平穩,可以透過差分變換使其平穩。
- 模型建立。根據兩個時間序列的資料,建立AR模型和包含多個滯後項的迴歸模型。具體步驟包括:
單變數自迴歸模型:僅使用一個變數的過去值進行迴歸分析。
多變數回歸模型:加入另一個變數的過去值,進行聯合迴歸分析。 - F檢驗
格蘭傑因果檢驗的核心在於對兩個模型進行比較。透過F檢驗來判斷引入\(X_t\)的過去值是否能夠顯著提高對\(Y_t\)的預測能力。F檢驗的原假設是“\(X_t\)不格蘭傑導致\(Y_t\)”,備擇假設是“\(X_t\)格蘭傑導致\(Y_t\)”。F檢驗的公式為:$$F = \frac{(RSS_r - RSS_{ur}) / q}{RSS_{ur} / (n - k)} $$ 其中:- \(RSS_r\)是單變數自迴歸模型的殘差平方和。
- \(RSS_{ur}\)是多變數回歸模型的殘差平方和。
- \(q\)是引入的滯後項個數。
- \(n\)是樣本量。
- \(k\)是模型中的解釋變數個數。
如果F統計量大於臨界值,或者p值小於顯著性水平,則拒絕原假設,說明\(X_t\)格蘭傑導致\(Y_t\)。
- 雙向檢驗
格蘭傑因果檢驗通常是雙向的。除了檢驗\(X_t\)是否格蘭傑導致\(Y_t\),還需要檢驗\(Y_t\)是否格蘭傑導致\(X_t\)。透過雙向檢驗,可以更全面地理解兩個變數之間的動態關係。
二、案例分析
檢驗1981~2013年我國居民實際消費總支出年增長率 (GY) 和實際可支配收入年增長率 (GX) 時間序列之間的因果關係。該研究旨在分析1981年至2013年間,我國居民的實際消費總支出年增長率 (GY) 與實際可支配收入年增長率 (GX) 之間的統計關聯和潛在因果效應。透過分析這兩個經濟指標的時間序列資料,可以揭示它們之間的動態關係,為理解消費行為和制定相關經濟政策提供依據。
年份 | GY | GX | 年份 | GY | GX | 年份 | GY | GX |
---|---|---|---|---|---|---|---|---|
1981 | 0.099473 | 0.062099 | 1982 | 0.082741 | 0.094567 | 1983 | 0.091417 | 0.090969 |
1984 | 0.127428 | 0.147912 | 1985 | 0.145660 | 0.003061 | 1986 | 0.062468 | 0.123817 |
1987 | 0.076548 | 0.122000 | 1988 | 0.081482 | 0.079701 | 1989 | -0.049696 | -0.048035 |
1990 | 0.040257 | 0.099168 | 1991 | 0.097858 | 0.146047 | 1992 | 0.138718 | 0.164554 |
1993 | 0.100700 | 0.174172 | 1994 | 0.072262 | 0.111463 | 1995 | 0.109241 | 0.083073 |
1996 | 0.105028 | 0.085910 | 1997 | 0.057785 | 0.062081 | 1998 | 0.071002 | 0.060773 |
1999 | 0.083955 | 0.056033 | 2000 | 0.089322 | 0.066737 | 2001 | 0.070681 | 0.080250 |
2002 | 0.081920 | 0.106086 | 2003 | 0.073655 | 0.120293 | 2004 | 0.088857 | 0.129201 |
2005 | 0.098908 | 0.139262 | 2006 | 0.115015 | 0.166874 | 2007 | 0.113153 | 0.122116 |
2008 | 0.094716 | 0.157067 | 2009 | 0.114582 | 0.075955 | 2010 | 0.102600 | 0.103122 |
2011 | 0.138954 | 0.102237 | 2012 | 0.066299 | 0.058626 | 2013 | 0.118778 | 0.115859 |
2.1 GY和GX的時序圖
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager
# 設定中文字型,避免中文亂碼
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑體字(SimHei)
plt.rcParams['axes.unicode_minus'] = False # 解決負號顯示問題
# 建立資料表
data = {
'年份': [1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013],
'GY': [0.099473, 0.082741, 0.091417, 0.127428, 0.145660, 0.062468, 0.076548, 0.081482, -0.049696, 0.040257, 0.097858, 0.138718, 0.100700, 0.072262, 0.109241, 0.105028, 0.057785, 0.071002, 0.083955, 0.089322, 0.070681, 0.081920, 0.073655, 0.088857, 0.098908, 0.115015, 0.113153, 0.094716, 0.114582, 0.102600, 0.138954, 0.066299, 0.118778],
'GX': [0.062099, 0.094567, 0.090969, 0.147912, 0.003061, 0.123817, 0.122000, 0.079701, -0.048035, 0.099168, 0.146047, 0.164554, 0.174172, 0.111463, 0.083073, 0.085910, 0.062081, 0.060773, 0.056033, 0.066737, 0.080250, 0.106086, 0.120293, 0.129201, 0.139262, 0.166874, 0.122116, 0.157067, 0.075955, 0.103122, 0.102237, 0.058626, 0.115859]
}
# 轉換為 pandas DataFrame
df = pd.DataFrame(data)
# 建立圖形
plt.figure(figsize=(10, 6))
# 繪製 GY 曲線
plt.plot(df['年份'], df['GY'], label='GY', marker='o')
# 繪製 GX 曲線
plt.plot(df['年份'], df['GX'], label='GX', marker='s')
# 新增標題和標籤
plt.title('GY 和 GX 隨年份的變化', fontsize=14)
plt.xlabel('年份', fontsize=12)
plt.ylabel('值', fontsize=12)
# 顯示圖例
plt.legend()
# 新增網格線
plt.grid(True)
# 顯示圖形
plt.show()
2.2 格蘭傑因果檢驗程式
import pandas as pd
import numpy as np
from statsmodels.tsa.stattools import adfuller, grangercausalitytests
from statsmodels.tsa.ar_model import AutoReg
from arch import arch_model
import statsmodels.api as sm
# 建立資料表
data = {
'年份': [1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013],
'GY': [0.099473, 0.082741, 0.091417, 0.127428, 0.145660, 0.062468, 0.076548, 0.081482, -0.049696, 0.040257, 0.097858, 0.138718, 0.100700, 0.072262, 0.109241, 0.105028, 0.057785, 0.071002, 0.083955, 0.089322, 0.070681, 0.081920, 0.073655, 0.088857, 0.098908, 0.115015, 0.113153, 0.094716, 0.114582, 0.102600, 0.138954, 0.066299, 0.118778],
'GX': [0.062099, 0.094567, 0.090969, 0.147912, 0.003061, 0.123817, 0.122000, 0.079701, -0.048035, 0.099168, 0.146047, 0.164554, 0.174172, 0.111463, 0.083073, 0.085910, 0.062081, 0.060773, 0.056033, 0.066737, 0.080250, 0.106086, 0.120293, 0.129201, 0.139262, 0.166874, 0.122116, 0.157067, 0.075955, 0.103122, 0.102237, 0.058626, 0.115859]
}
df = pd.DataFrame(data)
# ADF檢驗函式
def adf_test(series):
result = adfuller(series)
output = {
'ADF Statistic': round(result[0], 2),
'p-value': round(result[1], 2),
'Critical Values': {key: round(val, 2) for key, val in result[4].items()}
}
return output
# 檢查GY和GX的平穩性
print("GY的ADF檢驗結果:")
print(adf_test(df['GY']))
print("\nGX的ADF檢驗結果:")
print(adf_test(df['GX']))
# 如果非平穩,進行差分
df['GY_diff'] = df['GY'].diff().dropna()
df['GX_diff'] = df['GX'].diff().dropna()
# 對差分後的資料進行ADF檢驗
print("\nGY差分後的ADF檢驗結果:")
print(adf_test(df['GY_diff'].dropna()))
print("\nGX差分後的ADF檢驗結果:")
print(adf_test(df['GX_diff'].dropna()))
# 格蘭傑因果檢驗,max_lag=5
print("\n格蘭傑因果檢驗結果(GX導致GY):")
gc_result = grangercausalitytests(df[['GY', 'GX']], maxlag=5, verbose=False)
print("\n格蘭傑因果檢驗結果(GY導致GX):")
gc_result_reverse = grangercausalitytests(df[['GX', 'GY']], maxlag=5, verbose=False)
# 選擇最優滯後階數(透過AIC和BIC)
model_aic = {}
model_bic = {}
for lag in range(1, 6):
model = sm.tsa.VAR(df[['GY_diff', 'GX_diff']].dropna())
result = model.fit(lag)
model_aic[lag] = result.aic
model_bic[lag] = result.bic
optimal_p_aic = min(model_aic, key=model_aic.get)
optimal_p_bic = min(model_bic, key=model_bic.get)
print(f"\n最優滯後階數基於AIC: {optimal_p_aic}")
print(f"最優滯後階數基於BIC: {optimal_p_bic}")
2.3 結果輸出
GY的ADF檢驗結果:
{'ADF Statistic': -4.14, 'p-value': 0.0, 'Critical Values': {'1%': -3.65, '5%': -2.96, '10%': -2.62}}
GX的ADF檢驗結果:
{'ADF Statistic': -2.4, 'p-value': 0.14, 'Critical Values': {'1%': -3.71, '5%': -2.98, '10%': -2.63}}
GY差分後的ADF檢驗結果:
{'ADF Statistic': -3.22, 'p-value': 0.02, 'Critical Values': {'1%': -3.72, '5%': -2.99, '10%': -2.63}}
GX差分後的ADF檢驗結果:
{'ADF Statistic': -3.23, 'p-value': 0.02, 'Critical Values': {'1%': -3.69, '5%': -2.97, '10%': -2.63}}
格蘭傑因果檢驗結果(GX導致GY):
格蘭傑因果檢驗結果(GY導致GX):
最優滯後階數基於AIC: 5
最優滯後階數基於BIC: 1
總結
格蘭傑因果檢驗(Granger Causality Test)是一種強有力的工具,廣泛應用於時間序列資料的因果關係分析。它透過檢驗一個時間序列變數的過去值是否能夠顯著提高對另一個變數未來值的預測,來判斷兩者之間是否存在因果關係。具體而言,格蘭傑因果檢驗透過構建兩個迴歸模型:一個僅使用被解釋變數的滯後項,另一個加入解釋變數的滯後項。隨後,研究者透過F檢驗對這兩個模型的優劣進行比較。如果加入解釋變數的滯後項顯著提高了預測效果,則可以認為該變數“格蘭傑導致”了另一個變數的變化。
然而,格蘭傑因果檢驗僅是一種統計上的工具,因其基於預測能力而非實際的因果機制,因此在解釋結果時需要謹慎。特別是在處理複雜的經濟和金融資料時,研究者應結合其他分析方法,例如協整檢驗、脈衝響應分析等,以避免誤判因果關係。此外,該方法僅適用於平穩的時間序列,因此在使用前需要對資料進行平穩性檢驗。總之,格蘭傑因果檢驗提供了識別時間序列間動態關係的重要手段,但在實際應用中,需結合多種分析工具,以確保結果的可靠性和有效性。
參考資料
- 格蘭傑因果關係檢驗
- 因果檢測(一)–格蘭傑因果檢查Granger causality