論文中に 「VAR(ベクトル自己回帰)」として登場する用語。
VAR(ベクトル自己回帰) とは:複数時系列が互いに過去の値で影響し合う構造をモデル化。Granger因果検定の前段。
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) |
VAR(ベクトル自己回帰) がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。
🌐 体系階層に未登録
中心の概念から放射状に、 前提・兄弟・発展形・応用先などの関係性を矢印で結びます。 横の繋がりを見るのに最適。 ノードをドラッグ、 ホイールでズーム、 クリックで遷移。
大きな円が小さな円を包含する Circle Packing 図。 「VAR(ベクトル自己回帰)」は緑色でハイライト。
長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「VAR(ベクトル自己回帰)」は緑色でハイライト。
| マップ | 分かること | こんな時に見る |
|---|---|---|
| 🔗 関係マップ | 手法間の横の関係(前提→発展→応用) | 「次に何を学べばよい?」 学習順序の判断 |
| ⭕ 包含マップ | 分類体系の入れ子構造(上位⊃下位) | 「この手法はどんなジャンルに属する?」 |
| 🌳 ツリーマップ | 分野の規模比較(面積=ボリューム) | 「データサイエンス全体の俯瞰像」 |
💡 ジャストインタイム学習のヒント:3つの視点を行き来することで、 概念を多角的に理解できます。 包含マップやツリーマップはズーム/ドリルダウンで大分類から細部まで探索できます。
分散(variance)は統計学の最重要概念のひとつです。 関連キーワードを難易度別に整理しました。
合成データではなく公的統計を念頭に、 分散の計算手順を具体的な数値で示します。
# 47 都道府県の人口(万人、 概算値)
東京 1404、 神奈川 924、 大阪 884、 愛知 755、 埼玉 734、 千葉 628、 兵庫 547、
北海道 522、 福岡 513、 静岡 365、 茨城 287、 広島 280、 京都 258、 宮城 230、
新潟 220、 長野 205、 岐阜 198、 福島 184、 群馬 194、 栃木 193、 岡山 189、
三重 178、 熊本 174、 鹿児島 159、 沖縄 147、 滋賀 141、 山口 134、 愛媛 133、
長崎 130、 奈良 132、 青森 124、 岩手 121、 大分 113、 石川 113、 山形 106、
宮崎 107、 富山 104、 秋田 96、 香川 95、 和歌山 92、 山梨 81、 佐賀 81、
福井 77、 徳島 72、 高知 69、 島根 67、 鳥取 55
# 平均 x̄
合計 ≈ 12,612 万人
n = 47
x̄ = 12,612 / 47 ≈ 268.3 万人
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 偏差の二乗和(最大値での寄与が圧倒的) (1404 - 268.3)² ≈ 1,289,800 (924 - 268.3)² ≈ 430,000 (884 - 268.3)² ≈ 379,000 (755 - 268.3)² ≈ 237,000 (734 - 268.3)² ≈ 217,000 (55 - 268.3)² ≈ 45,500 # 全偏差二乗和 Σ(xᵢ - x̄)² ≈ 3,800,000 # 標本分散(n-1 補正) s² = 3,800,000 / 46 ≈ 82,609 (万人²) # 標準偏差 s = √82,609 ≈ 287.4 万人 # 変動係数 CV = 287.4 / 268.3 ≈ 1.07 = 107% → 標準偏差が平均よりも大きい!極端な右裾の分布 |
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 各人口を log₁₀ 変換 log₁₀(1404) ≈ 3.147 log₁₀(268.3) ≈ 2.428(平均近く) log₁₀(55) ≈ 1.740 # log 変換後の平均と分散 log₁₀ 値の平均 ≈ 2.30 log₁₀ 値の標準偏差 ≈ 0.33 # 変動係数 CV_log = 0.33 / 2.30 ≈ 14% → 大幅に縮減、 釣鐘型に近づく |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # 47 都道府県を 8 ブロックに分けて分散分解 # 北海道、 東北 6、 関東 7、 中部 9、 近畿 6、 中国 5、 四国 4、 九州沖縄 9 県 # 各ブロック平均(万人) 北海道(1 県):522 東北:156 関東:495 中部:236 近畿:316 中国:195 四国:92 九州沖縄:176 # 全体平均 = 268.3 # 群間平方和 SS_between = Σ nᵢ(x̄ᵢ - x̄_全)² ≈ 1·(522-268.3)² + 6·(156-268.3)² + 7·(495-268.3)² + ... ≈ 1·64400 + 6·12613 + 7·51372 + 9·1037 + 6·2273 + 5·5366 + 4·31000 + 9·8500 ≈ 64400 + 75678 + 359604 + 9333 + 13638 + 26830 + 124000 + 76500 ≈ 749,983 # 群内平方和 SS_within ≈ 3,800,000 - 750,000 ≈ 3,050,000 # 寄与率 SS_between / SS_total = 750,000 / 3,800,000 ≈ 0.197 → 約 20% の分散がブロック間で説明可能、 80% はブロック内 |
標本データの分散は n−1 で割る(不偏分散、 Bessel's correction)のが正しい。 母集団全体のデータなら n で割る。 numpy の `np.var(x)` はデフォルトで n で割る(標本のみ扱う場合は注意)、 `np.var(x, ddof=1)` で n−1。 pandas の `df.var()` はデフォルト n−1。 この違いを意識しないとサンプルサイズが小さいときに数 % の誤差が出ます。
分散は偏差の二乗の平均なので、 外れ値の影響を二乗で受けます。 47 都道府県の人口で東京(1404 万人)1 県が分散の約 34% を占めます。 つまり 1 県が全体の散布度を支配する。 ロバストな代替指標として MAD(中央絶対偏差)、 IQR、 trimmed variance(上下数 % を切り捨てた分散)を併用するか、 対数変換でスケールをならしましょう。
「人口」の分散と「人口密度」の分散を直接比較しても無意味です。 単位が違うため。 比較したいなら変動係数 CV = σ/μ を使うか、 標準化(z スコア化)してから扱うべきです。 ただし CV は μ が 0 近傍だと不安定になる(負の値もある変数では使えない)ことに注意。
Var(X + Y) = Var(X) + Var(Y) は X と Y が独立な場合のみ成立。 一般には Var(X+Y) = Var(X) + Var(Y) + 2·Cov(X, Y) と共分散項が加わります。 ポートフォリオ理論、 回帰の残差分析、 ANOVA の分散分解などでこの違いを誤ると結果が大きく狂います。
線形回帰の OLS は誤差分散が一定(等分散)を仮定します。 不均一分散があると係数推定はバイアスなしでも、 標準誤差・p 値・信頼区間が狂います。 残差プロットで「漏斗状」の広がりが見えたら要注意。 対処は (i) 加重最小二乗 WLS、 (ii) Huber–White ロバスト標準誤差、 (iii) Box-Cox 変換などの分散安定化、 (iv) GLM のリンク関数選択。
分散が同じでも、 分布形状は全く異なり得ます。 一様分布、 正規分布、 二峰分布のいずれも同じ分散を持つように設計できます。 Anscombe の四つ組(平均・分散・相関がすべて同じだが分布が全く違う 4 組)は古典的な反例。 分散は形状情報を持たないので、 必ずヒストグラム・密度プロット・QQ プロットで分布形状も確認しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import numpy as np import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8-sig') x = df['人口総数'].dropna().values # numpy(デフォルト ddof=0 で母分散) print('母分散(n で割る):', np.var(x)) print('標本分散(n-1 で割る):', np.var(x, ddof=1)) print('標準偏差(標本):', np.std(x, ddof=1)) # pandas(デフォルト ddof=1 で標本) print('pandas 分散:', df['人口総数'].var()) print('pandas 標準偏差:', df['人口総数'].std()) # 変動係数 print('CV:', df['人口総数'].std() / df['人口総数'].mean()) |
1 2 3 4 5 6 7 8 9 10 11 | from scipy import stats # 1 行で多くの統計量 desc = stats.describe(x, ddof=1) print(desc) # DescribeResult(nobs=47, minmax=(55, 1404), mean=268.3, variance=82609, ...) # トリム平均・トリム分散(上下 10% カット) trim_mean = stats.tmean(x, limits=(np.percentile(x, 10), np.percentile(x, 90))) trim_var = stats.tvar(x, limits=(np.percentile(x, 10), np.percentile(x, 90))) print(f'10% トリム平均={trim_mean:.1f}, 分散={trim_var:.1f}') |
1 2 3 4 5 6 7 8 9 10 11 12 13 | from scipy import stats # MAD(中央絶対偏差) mad = stats.median_abs_deviation(x, scale='normal') print(f'MAD(正規スケール化)= {mad:.1f}') # IQR q75, q25 = np.percentile(x, [75, 25]) iqr = q75 - q25 print(f'IQR = {iqr:.1f}') # 比較:標準偏差はずっと大きい print(f'SD = {np.std(x, ddof=1):.1f}') |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | df['region'] = df['都道府県'].map(...) # 地方ブロックに分類 # 全体平方和 grand_mean = df['人口総数'].mean() ss_total = ((df['人口総数'] - grand_mean)**2).sum() # 群間平方和 group_means = df.groupby('region')['人口総数'].mean() group_counts = df.groupby('region')['人口総数'].count() ss_between = ((group_means - grand_mean)**2 * group_counts).sum() # 群内平方和 ss_within = ss_total - ss_between print(f'全体: {ss_total:.0f}') print(f'群間: {ss_between:.0f} ({ss_between/ss_total*100:.1f}%)') print(f'群内: {ss_within:.0f} ({ss_within/ss_total*100:.1f}%)') |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import statsmodels.api as sm from statsmodels.stats.diagnostic import het_breuschpagan, het_white X = sm.add_constant(df[['高齢化率']]) y = df['死亡率'] model = sm.OLS(y, X).fit() # Breusch–Pagan 検定 bp = het_breuschpagan(model.resid, model.model.exog) print(f'BP statistic = {bp[0]:.3f}, p = {bp[1]:.4f}') # White 検定 wh = het_white(model.resid, model.model.exog) print(f'White statistic = {wh[0]:.3f}, p = {wh[1]:.4f}') # ロバスト標準誤差で再フィット model_robust = model.get_robustcov_results(cov_type='HC3') print(model_robust.summary()) |
1 2 3 | df_ts = pd.read_csv('data/raw/time_series.csv', parse_dates=['date']) df_ts['rolling_var'] = df_ts['value'].rolling(window=30).var() df_ts[['value', 'rolling_var']].plot(subplots=True, figsize=(10, 6)) |
1 2 3 4 5 6 7 | from scipy.stats import boxcox # 正値のみ対応。 最適なラムダを自動推定 transformed, lambda_opt = boxcox(x) print(f'最適 λ = {lambda_opt:.4f}') print(f'変換前の標準偏差 = {x.std():.2f}') print(f'変換後の標準偏差 = {transformed.std():.2f}') |
「VAR モデル」を理解するうえで必要なキーワードを 10 件以上提示します。 各チップから対応セクションへ移動できます。
30 秒結論 文脈 直感 数式 記号読み解き 実値計算 Python 実装 落とし穴 関連手法 関連用語 グループ教材 概念マップ
このセクションは「VAR モデル」を扱う 用語ページ です。 統計データ分析コンペティション(2026)の再現教材における中核用語のひとつで、人口 A1101・所得 A4101 の 2 変量 VAR(1) モデル という観点で SSDSE-B-2026(47 都道府県 × 複数年 × 100 超列)に紐づけられます。
位置づけ:相関・線形回帰・仮説検定 といった基礎用語群と並列であり、応用としては 内生性・IV・DID・クラスタリング 等へ繋がります。
VAR モデル を一言でいえば「人口 A1101・所得 A4101 の 2 変量 VAR(1) モデル」。 47 都道府県という小さな母集団でも、 SSDSE-B-2026 の A1101 列に注目すると、 大都市圏と地方の差・人口規模に伴う相対比較など、 様々なパターンが見えてきます。
比喩でいうと、 VAR モデル はデータ分析の「眼鏡」のようなもの。 同じデータでも眼鏡を変えれば、 平均(中心)・分散(ばらつき)・相関(連動)・因果(影響)と、 異なる情報が浮かび上がります。 SSDSE-B-2026 を題材に、 この眼鏡をかけてみるのが本ページの狙いです。
VAR モデル の代表的な定義式は次のとおりです。
$$ \mathbf{y}_t = \mathbf{c} + \mathbf{A}_1\,\mathbf{y}_{t-1} + \cdots + \mathbf{A}_p\,\mathbf{y}_{t-p} + \mathbf{u}_t $$ここで使われる記号や演算の意味は次節で言葉に翻訳します。
数式の各記号を、日本語の意味に変換します。
SSDSE-B-2026(公的統計の社会・教育系データセット、 47 都道府県 × 10 年分超 × 100 以上の列)を用いて、 「VAR モデル」を体感します。 ファイル名は 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 の 2 変量 VAR(1) モデル に関連する指標です。 算出例:
A1101 平均と標準偏差を求めるA1101 と A4101 の相関(線形・順位)を比較するscipy / pandas / scikit-learn / statsmodels を中心とした標準的な実装例です。 まず CSV を読み込み、 次に VAR モデル の解析を行います。
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))
# VAR モデル の代表的計算(用途に応じて 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])
VAR モデル を実務で扱う際に踏みやすい落とし穴を 5 件挙げます。
本ページでは「VAR モデル」を 12 セクション(🔖 キーワード索引/💡 30 秒結論/📍 文脈/🎨 直感/📐 数式/🔬 記号読み解き/🧮 実値計算/🐍 Python 実装/⚠️ 落とし穴/🌐 関連手法/🔗 関連用語/📚 グループ教材)で完結に整理しました。 SSDSE-B-2026 を素材に、 概念の輪郭・式の意味・実装手順・典型的な失敗パターンの 4 点を最低限押さえれば、 統計データ分析コンペの現場で迷わず使えるはずです。