論文中に 「Granger因果検定」として登場する用語。
Granger因果検定 とは:「Xの過去値を加えるとYの予測が改善するか」を検定。統計的因果ではなく予測上の因果性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # 基本パターン import pandas as pd import numpy as np from scipy import stats import matplotlib.pyplot as plt import seaborn as sns # データ読み込み df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932') # 基本統計量 df.describe() # 可視化 sns.pairplot(df[['食料費', '教育費', '住居費']]) plt.show() |
このページの上にある3つの概念マップ(関係マップ、 包含マップ、 ツリーマップ)でこの概念の位置づけが視覚的に分かります。 関連手法を辿って学習を進めましょう。
統計データ活用コンペティションのSSDSE-B-2026データは、 47都道府県の社会経済データ。 この概念を使って以下のような分析ができます:
| 機能 | Python (pandas) | Python (scipy) |
|---|---|---|
| 要約統計 | df.describe() | stats.describe() |
| 平均 | df.mean() | np.mean() |
| 標準偏差 | df.std() | np.std() |
| 相関 | df.corr() | stats.pearsonr() |
| t検定 | — | stats.ttest_ind() |
| 回帰 | — | stats.linregress() |
| 分布フィッティング | — | stats.norm.fit() |
この概念は、 他の多くの統計概念と密接に関連しています。 ジャストインタイム型学習では、 必要に応じて関連用語へジャンプしながら全体像を構築します。
| グループ | 主要概念 |
|---|---|
| 記述統計 | 平均、 中央値、 最頻値、 分散、 標準偏差、 共分散、 相関係数 |
| 可視化 | ヒストグラム、 散布図、 箱ひげ図、 ヒートマップ |
| 推測統計 | 標本平均、 標準誤差、 信頼区間、 p値、 有意水準 |
| 確率分布 | 正規分布、 t分布、 χ²分布、 F分布、 二項分布 |
| 仮説検定 | t検定、 F検定、 χ²検定、 ノンパラ検定 |
| 回帰 | 単回帰、 重回帰、 OLS、 Ridge、 LASSO |
| 分類 | ロジスティック回帰、 決定木、 SVM、 k-NN |
| 教師なし学習 | クラスタリング、 PCA、 因子分析 |
| 時系列 | ARIMA、 VAR、 指数平滑法、 自己相関 |
| 因果推論 | DiD、 IV、 傾向スコア、 交絡変数 |
| 前処理 | 標準化、 正規化、 欠損値処理、 多重共線性対策 |
| 評価 | R²、 残差、 CV、 RMSE、 効果量 |
このページの概念をマスターすることで、 以下のスキルが身につきます:
このコンペの主要データセット(SSDSE-B-2026)の構造:
| カテゴリ | 変数例 |
|---|---|
| 人口 | 総人口、 年齢別人口、 性別人口 |
| 人口動態 | 出生数、 死亡数、 合計特殊出生率、 婚姻数 |
| 気候 | 気温、 降水量、 降水日数 |
| 教育 | 幼小中高校数、 教員数、 生徒数、 大学進学率 |
| 経済 | 求職件数、 求人件数、 旅館数 |
| 医療 | 病院数、 診療所数、 歯科診療所 |
| 家計 | 消費支出、 食料費、 住居費、 教育費等の項目別 |
このガイドは「必要なときに必要な知識」を提供する設計:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # 必須ライブラリのインストール pip install pandas numpy scipy statsmodels scikit-learn matplotlib seaborn # 標準的なインポート import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from scipy import stats from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.metrics import r2_score, mean_squared_error # 日本語表示の設定(matplotlib) plt.rcParams['font.family'] = 'Hiragino Sans' plt.rcParams['axes.unicode_minus'] = False # データ読み込み(SSDSE は cp932 エンコーディング) df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932') print(df.shape) print(df.head()) print(df.describe()) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | def quick_eda(df, target=None): """探索的データ分析の基本テンプレート""" print(f"Shape: {df.shape}") print(f"\nColumn types:\n{df.dtypes}") print(f"\nMissing values:\n{df.isnull().sum()}") print(f"\nBasic stats:\n{df.describe()}") # 数値列の可視化 numeric_cols = df.select_dtypes(include=[np.number]).columns df[numeric_cols].hist(bins=20, figsize=(15, 10)) plt.tight_layout() plt.show() # 相関ヒートマップ if len(numeric_cols) > 1: plt.figure(figsize=(12, 10)) sns.heatmap(df[numeric_cols].corr(), annot=True, fmt='.2f', cmap='RdBu_r', center=0) plt.show() # ターゲットがあれば散布図行列 if target and target in df.columns: sns.pairplot(df[numeric_cols[:5]], hue=target if df[target].dtype == 'O' else None) plt.show() |
分析結果を報告する際の標準的な構成:
p値だけでなく効果量も併記するのが現代統計の標準。 主要な指標と Cohen の解釈基準:
| 統計量 | 効果量 | 小 | 中 | 大 |
|---|---|---|---|---|
| 2群平均差 | Cohen's d | 0.2 | 0.5 | 0.8 |
| 相関 | r | 0.1 | 0.3 | 0.5 |
| 線形回帰 | R² | 0.02 | 0.13 | 0.26 |
| ANOVA | η² (eta²) | 0.01 | 0.06 | 0.14 |
| χ² | Cramér's V | 0.1 | 0.3 | 0.5 |
| ロジスティック | Odds Ratio | 1.5 | 2.5 | 4.0 |
| 日本語 | 英語 |
|---|---|
| 統計的に有意 | statistically significant |
| 効果量 | effect size |
| 95%信頼区間 | 95% confidence interval (CI) |
| 標本サイズ | sample size |
| 検出力 | statistical power |
| 第1種の誤り | Type I error / false positive |
| 第2種の誤り | Type II error / false negative |
| 多重比較問題 | multiple comparisons problem |
| 過学習 | overfitting |
| 汎化性能 | generalization |
| 交差検証 | cross-validation (CV) |
Granger因果検定 がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。
🌐 体系階層に未登録
中心の概念から放射状に、 前提・兄弟・発展形・応用先などの関係性を矢印で結びます。 横の繋がりを見るのに最適。 ノードをドラッグ、 ホイールでズーム、 クリックで遷移。
大きな円が小さな円を包含する Circle Packing 図。 「Granger因果検定」は緑色でハイライト。
長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「Granger因果検定」は緑色でハイライト。
| マップ | 分かること | こんな時に見る |
|---|---|---|
| 🔗 関係マップ | 手法間の横の関係(前提→発展→応用) | 「次に何を学べばよい?」 学習順序の判断 |
| ⭕ 包含マップ | 分類体系の入れ子構造(上位⊃下位) | 「この手法はどんなジャンルに属する?」 |
| 🌳 ツリーマップ | 分野の規模比較(面積=ボリューム) | 「データサイエンス全体の俯瞰像」 |
💡 ジャストインタイム学習のヒント:3つの視点を行き来することで、 概念を多角的に理解できます。 包含マップやツリーマップはズーム/ドリルダウンで大分類から細部まで探索できます。
Granger 因果性に関連する時系列概念のチップ集。
SSDSE-B-2026 を年度パネルとして並べ替えれば、 都道府県の時系列を作ることができます。 ここでは年次データを擬似時系列として Granger 因果性を計算します。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import pandas as pd from statsmodels.tsa.stattools import grangercausalitytests df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) # 東京都の時系列を抽出(年度列が存在する想定) tokyo = df[df['都道府県'] == '東京都'].sort_values(df.columns[0]) num_cols = tokyo.select_dtypes('number').columns ts = tokyo[num_cols[:2]].dropna() # Granger 因果性:列1 が 列2 を予測できるか(最大 3 ラグ) res = grangercausalitytests(ts, maxlag=3, verbose=False) for lag, r in res.items(): print(f'lag={lag}: F={r[0]["ssr_ftest"][0]:.3f}, p={r[0]["ssr_ftest"][1]:.4f}') |
1 2 3 4 5 6 7 8 9 10 11 12 13 | import pandas as pd from statsmodels.tsa.api import VAR df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) tokyo = df[df['都道府県'] == '東京都'].sort_values(df.columns[0]) num_cols = tokyo.select_dtypes('number').columns ts = tokyo[num_cols[:3]].dropna().diff().dropna() # 1階差で定常化 model = VAR(ts) selection = model.select_order(maxlags=3) print('推奨ラグ (AIC/BIC):', selection.aic, selection.bic) fit = model.fit(maxlags=2) print(fit.test_causality(num_cols[0], [num_cols[1]], kind='f')) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import pandas as pd from statsmodels.tsa.stattools import grangercausalitytests, adfuller from statsmodels.tsa.api import VAR df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) tokyo = df[df['都道府県'] == '東京都'].sort_values(df.columns[0]) ts = tokyo.select_dtypes('number').iloc[:, :2].dropna() # まず定常性チェック for c in ts.columns: stat, p = adfuller(ts[c])[:2] print(f'{c}: ADF stat={stat:.3f}, p={p:.4f}') # Granger res = grangercausalitytests(ts.diff().dropna(), maxlag=3, verbose=False) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import numpy as np import pandas as pd from scipy import stats import statsmodels.api as sm df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) tokyo = df[df['都道府県'] == '東京都'].sort_values(df.columns[0]) ts = tokyo.select_dtypes('number').iloc[:, :2].dropna().values # 制約モデルと非制約モデルの SSR を比較 def granger_f(y, x, lag=2): Y = y[lag:] X_rest = np.column_stack([y[lag-i-1:-i-1] for i in range(lag)]) X_full = np.column_stack([Y]*0 + [y[lag-i-1:-i-1] for i in range(lag)] + [x[lag-i-1:-i-1] for i in range(lag)]) X_rest = sm.add_constant(X_rest); X_full = sm.add_constant(X_full) ssr_r = sm.OLS(Y, X_rest).fit().ssr ssr_f = sm.OLS(Y, X_full).fit().ssr n, k = len(Y), lag F = ((ssr_r - ssr_f) / k) / (ssr_f / (n - 2*k - 1)) p = 1 - stats.f.cdf(F, k, n-2*k-1) return F, p print(granger_f(ts[:, 0], ts[:, 1], lag=2)) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from arch.bootstrap import StationaryBootstrap import numpy as np import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) tokyo = df[df['都道府県'] == '東京都'].sort_values(df.columns[0]) ts = tokyo.select_dtypes('number').iloc[:, :2].dropna().values def stat_func(data): # 簡易: 共分散を統計量に return np.cov(data[:, 0], data[:, 1])[0, 1] bs = StationaryBootstrap(3, ts) results = bs.apply(stat_func, 200) print('ブートストラップ平均:', np.mean(results), '95%CI:', np.percentile(results, [2.5, 97.5])) |
1 2 3 4 5 6 7 8 9 10 11 12 13 | import pmdarima as pm import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) tokyo = df[df['都道府県'] == '東京都'].sort_values(df.columns[0]) ts = tokyo.select_dtypes('number').iloc[:, :2].dropna() y, x = ts.iloc[:, 0], ts.iloc[:, 1] # 単独 ARIMA vs 外生変数つき ARIMA mod1 = pm.auto_arima(y, seasonal=False) mod2 = pm.auto_arima(y, exogenous=x.values.reshape(-1,1), seasonal=False) print(f'BIC 単独: {mod1.bic():.2f}, 外生あり: {mod2.bic():.2f}') print('外生変数で予測改善 →', mod2.bic() < mod1.bic()) |
1 2 3 4 5 6 7 8 9 10 11 12 | import pandas as pd from statsmodels.tsa.api import VAR import matplotlib.pyplot as plt df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) tokyo = df[df['都道府県'] == '東京都'].sort_values(df.columns[0]) ts = tokyo.select_dtypes('number').iloc[:, :3].dropna().diff().dropna() model = VAR(ts).fit(maxlags=2) irf = model.irf(10) irf.plot() plt.savefig('var_irf.png', dpi=120, bbox_inches='tight') |
「グレンジャー因果」を理解するうえで必要なキーワードを 10 件以上提示します。 各チップから対応セクションへ移動できます。
30 秒結論 文脈 直感 数式 記号読み解き 実値計算 Python 実装 落とし穴 関連手法 関連用語 グループ教材 概念マップ
このセクションは「グレンジャー因果」を扱う 用語ページ です。 統計データ分析コンペティション(2026)の再現教材における中核用語のひとつで、人口 A1101 と所得 A4101 の時系列でグレンジャー因果検定 という観点で SSDSE-B-2026(47 都道府県 × 複数年 × 100 超列)に紐づけられます。
位置づけ:相関・線形回帰・仮説検定 といった基礎用語群と並列であり、応用としては 内生性・IV・DID・クラスタリング 等へ繋がります。
グレンジャー因果 を一言でいえば「人口 A1101 と所得 A4101 の時系列でグレンジャー因果検定」。 47 都道府県という小さな母集団でも、 SSDSE-B-2026 の A1101 列に注目すると、 大都市圏と地方の差・人口規模に伴う相対比較など、 様々なパターンが見えてきます。
比喩でいうと、 グレンジャー因果 はデータ分析の「眼鏡」のようなもの。 同じデータでも眼鏡を変えれば、 平均(中心)・分散(ばらつき)・相関(連動)・因果(影響)と、 異なる情報が浮かび上がります。 SSDSE-B-2026 を題材に、 この眼鏡をかけてみるのが本ページの狙いです。
グレンジャー因果 の代表的な定義式は次のとおりです。
$$ y_t = \alpha_0 + \sum_{i=1}^p \alpha_i y_{t-i} + \sum_{j=1}^p \beta_j x_{t-j} + \varepsilon_t; \quad H_0:\beta_1=\cdots=\beta_p=0 $$ここで使われる記号や演算の意味は次節で言葉に翻訳します。
数式の各記号を、日本語の意味に変換します。
SSDSE-B-2026(公的統計の社会・教育系データセット、 47 都道府県 × 10 年分超 × 100 以上の列)を用いて、 「グレンジャー因果」を体感します。 ファイル名は SSDSE-B-2026.csv、 読み込みは下記の Python コードで行います。
import pandas as pd
# SSDSE-B-2026 を読み込む(cp932 / Shift_JIS)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1], encoding='cp932')
print(df.shape) # (564, 112)
print(df['SSDSE-B-2026'].unique()) # 含まれる年度
latest = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()].copy()
print(latest[['Prefecture', 'A1101', 'A4101']].head())
ここで使った中心列 A1101 は SSDSE-B-2026 における 人口 A1101 と所得 A4101 の時系列でグレンジャー因果検定 に関連する指標です。 算出例:
A1101 平均と標準偏差を求めるA1101 と A4101 の相関(線形・順位)を比較するscipy / pandas / scikit-learn / statsmodels を中心とした標準的な実装例です。 まず CSV を読み込み、 次に グレンジャー因果 の解析を行います。
import pandas as pd
import numpy as np
from scipy import stats
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1], encoding='cp932')
df = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()].copy()
x = df['A1101'].astype(float).values
y = df['A4101'].astype(float).values
# 基本統計量
print('n =', len(x))
print('mean(x) =', np.mean(x))
print('std(x) =', np.std(x, ddof=1))
# グレンジャー因果 の代表的計算(用途に応じて scipy/statsmodels を切替える)
r, p = stats.pearsonr(x, y)
print(f'Pearson r = {r:.4f}, p = {p:.4g}')
rs, ps = stats.spearmanr(x, y)
print(f'Spearman rho = {rs:.4f}, p = {ps:.4g}')
用途別の追加実装:
# 標準化と簡易クラスタリングの例
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
X = df[['A1101', 'A4101']].astype(float).values
Xs = StandardScaler().fit_transform(X)
km = KMeans(n_clusters=4, n_init=10, random_state=0).fit(Xs)
df['cluster'] = km.labels_
print(df[['Prefecture', 'A1101', 'A4101', 'cluster']].head(10))
# 時系列(北海道の A1101)— 例として ARIMA 系の前処理
import statsmodels.api as sm
ts = df.sort_values('SSDSE-B-2026').groupby('SSDSE-B-2026')['A1101'].mean()
print(ts.tail())
res = sm.tsa.stattools.adfuller(ts)
print('ADF stat:', res[0], 'p:', res[1])
グレンジャー因果 を実務で扱う際に踏みやすい落とし穴を 5 件挙げます。
本ページでは「グレンジャー因果」を 12 セクション(🔖 キーワード索引/💡 30 秒結論/📍 文脈/🎨 直感/📐 数式/🔬 記号読み解き/🧮 実値計算/🐍 Python 実装/⚠️ 落とし穴/🌐 関連手法/🔗 関連用語/📚 グループ教材)で完結に整理しました。 SSDSE-B-2026 を素材に、 概念の輪郭・式の意味・実装手順・典型的な失敗パターンの 4 点を最低限押さえれば、 統計データ分析コンペの現場で迷わず使えるはずです。