🍰 まずはやさしく
結果を説明するためのヒントのようなものです。
ある値がどう変わるかを予想するために使います。
スマホの利用時間でテストの点数を予想する例です。
この章では説明変数の基本的な意味を学びます。
説明変数(Explanatory Variable):回帰モデル $y = \beta_0 + \beta_1 x_1 + \cdots + \beta_p x_p + \varepsilon$ の右辺の $x_j$。 ML では feature、 統計では 独立変数 / 共変量 (covariate) / regressor とも呼ぶ。
A1101 や 65 歳以上人口 A1303 を $x$ にとり、 出生数 A4101 を $y$ とする使い方が典型。statsmodels.OLS(y, sm.add_constant(X)).fit() または sklearn.linear_model.LinearRegression().fit(X, y)。 X が説明変数行列。🍰 まずはやさしく
データの分析でとても重要な役割を持つ言葉です。
機械学習の基礎を身につけるために使います。
部活の練習量と試合の結果の関係を調べる例です。
このページでは定義から計算方法までを解説します。
このページは「説明変数(Explanatory Variable)」の用語解説です。 機械学習の基礎カテゴリにおける重要概念で、 機械学習の基礎 グループ教材の中で繰り返し登場します。 数式・実コード・落とし穴を 1 ページに集約し、 SSDSE-B-2026 都道府県データ(47 件 × 112 列)を題材に 手を動かしながら理解できるよう構成しています。
別称:独立変数 / 予測変数 / x。 まず 💡 30秒結論 で全体像を、 次に 🎨 直感 → 📐 数式 → 🧮 実値 → 🐍 Python の順で読むのがおすすめ。
🍰 まずはやさしく
変化の原因となる側のデータのことです。
何が結果に影響を与えているかを探るために使います。
買い物で使う金額が、お小遣いの額で決まる例です。
ここでは直感的なイメージと注意点を読みます。
説明変数は「原因側 / 入力」の変数です。 統計では $x$、 ML では特徴量、 計量経済では共変量と呼ぶことも。 「都道府県の総人口で 15 歳未満人口を説明する」と言うとき、 総人口が説明変数、 15 歳未満人口が目的変数です。
SSDSE-B-2026 の具体例: A1101_総人口 を $x$、 A1301_15歳未満人口 を $y$ にすると、 47 都道府県のデータで $y = \beta_0 + \beta_1 x$ を推定できます。 $\beta_1 \approx 0.11$ なので「総人口 100 万人増 → 15 歳未満が約 11 万人増」と読めます。 ただし因果ではなく 同時に動く 関係に過ぎません。
複数の説明変数を同時に使うのが 重回帰 (例: 人口 + 平均所得 + 高齢化率で出生率を説明)。 ただし説明変数同士の相関が強い(多重共線性)と係数が暴れ、 解釈が困難に。 VIF (分散拡大係数) が 10 を超えるなら片方を除外 するのが実務の目安。 また「データ収集前から含めるべき説明変数」(理論的に関与) と「後付けで足した変数」 (過学習リスク) を区別する習慣が重要。
説明変数は「天気予報の入力データ」と同じ。 明日の最高気温(目的変数 $y$)を予測したいとき、 気象予報士は「今日の気温」「気圧」「湿度」「風向き」「雲の量」を入力(説明変数 $x_1, x_2, \dots$)として使う。 もし君が「明日が暑くなるか」を予想したかったら、 何を見るだろうか? 単に「今日が暑かった」だけでなく「南風が強い」「湿度が高い」など複数の手がかりを組み合わせるはず。 これがまさに重回帰の発想だ。
| 目的変数 $y$(予測したいもの) | 有力な説明変数 $x_1, x_2, \dots$ | 不適切な説明変数 |
|---|---|---|
| 出生数(A4101) | 総人口 A1101・婚姻件数 A9101・15〜64歳人口 A1302 | 15歳未満人口(結果の一部) |
| 死亡数(A4200) | 65歳以上人口 A1303・総人口 A1101 | 出生数(因果的にほぼ無関係) |
| 転入超過(A5101−A5102) | 総人口 A1101・婚姻件数 A9101・年平均気温 B4101 | 翌年の人口(未来の値) |
🍰 まずはやさしく
数式の中で x と書かれる変数のことです。
目的の値を計算するための材料として使います。
地域の人口を使って、子供の数を数える例です。
ここでは具体的な数式での書き方を学びます。
主定義 (重回帰モデルにおける説明変数): 目的変数 $y$ を $p$ 個の説明変数 $x_1, \dots, x_p$ で線形に表現する。
SSDSE-B-2026 列名で意味づけ: 47 都道府県データで「出生数 (A4101)」を予測するモデルを例にすると、 説明変数は次のように具体化される。
$i = 1, \dots, 47$ は都道府県インデックス。 $x_{1}=\text{総人口 (A1101)}$, $x_{2}=\text{65歳以上人口 (A1303)}$, $x_{3}=\text{年平均気温 (B4101)}$ が説明変数、 $y=\text{出生数 (A4101)}$ が目的変数。 $\beta_j$ は他変数を一定にしたときの限界効果 (例: 総人口が 1 万人増えると出生数が $10000\,\beta_1$ 人増える)。
別表現 1: ベクトル/行列形:
$\mathbf{X}$ はデザイン行列 (1 列目は切片用の 1 ベクトル、 2 列目以降が説明変数)。 SSDSE-B-2026 の場合 $n=47, p=3$ なので $\mathbf{X}$ は $47 \times 4$ 行列。
別表現 2: 多重共線性診断 (VIF):
$R_j^2$ は $x_j$ を他の説明変数で回帰した決定係数。 SSDSE-B-2026 で「総人口 A1101」と「65歳以上人口 A1303」は強く相関する ($r \approx 0.99$) ため $\mathrm{VIF}$ が 10 を超えやすい。
パラメータの条件: $\mathbf{X}$ は列フルランク ($\text{rank}(\mathbf{X})=p+1$)、 $E[\varepsilon|\mathbf{X}]=0$ (外生性)、 $\mathrm{Var}(\varepsilon)=\sigma^2 I$ (等分散・無相関)。 $n > p+1$ (サンプル数 > パラメータ数)。 英語名 Explanatory Variable。 別称:独立変数 / 予測変数 / $x$。
記号と意味を逐一突き合わせて読みます。 慣れないうちは式を「日本語で読む」ことが理解の近道です。
SSDSE-B から 3 つの説明変数 で 15 歳未満人口を重回帰し、 VIF を確認します。
データ出典:SSDSE-B-2026(独立行政法人統計センター)。 47 都道府県 × 複数年(最新 2023)の社会統計データ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import pandas as pd import numpy as np import statsmodels.api as sm from statsmodels.stats.outliers_influence import variance_inflation_factor df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1) df = df[df['年度'] == 2023].reset_index(drop=True) # 説明変数を 3 つ X = df[['総人口','15~64歳人口','65歳以上人口']] y = df['15歳未満人口'] # 重回帰 X_const = sm.add_constant(X) model = sm.OLS(y, X_const).fit() print(model.summary().tables[1]) # VIF for i, name in enumerate(X.columns): vif = variance_inflation_factor(X.values, i) print(f'VIF({name}) = {vif:.2f}') |
実行結果の要約(出力は環境依存。 概算値):
| 項目 | 値 |
|---|---|
| β(総人口) | +0.999 (p<0.001) |
| β(15~64歳人口) | −0.999 (p<0.001) |
| β(65歳以上人口) | −0.999 (p<0.001) |
| VIF(総人口) | ≈1.8e4 (完全共線に近く桁は環境依存) |
| VIF(15~64歳人口) | ≈8.8e3 |
| VIF(65歳以上人口) | ≈1.8e3 |
⚠️ ここでは 総人口 ≈ 15歳未満 + 15~64歳 + 65歳以上 という定義上の恒等関係に近い 3 変数を選んでいるため、 係数は $\beta \approx (+1, -1, -1)$、 VIF は桁で 10³〜10⁴ に達する(ほぼ完全共線)。 これは「説明変数に目的変数の構成要素を入れてはいけない」極端な失敗例で、 VIF の絶対値は丸め誤差・環境依存。 次節では恒等関係を避けた 2 変数(総人口 x₁・65歳以上 x₂)で手計算する。
SSDSE-B-2026 から 5 都道府県を抜き出し、 説明変数 2 つ(総人口 x₁, 65 歳以上人口 x₂)で 15 歳未満人口 y を予測する OLS を電卓で再現します。
| i | 都道府県 | x₁=総人口(千人) | x₂=高齢(千人) | y=15歳未満(千人) |
|---|---|---|---|---|
| 1 | 東京 | 14086 | 3205 | 1513 |
| 2 | 大阪 | 8763 | 2424 | 984 |
| 3 | 福岡 | 5103 | 1452 | 644 |
| 4 | 沖縄 | 1468 | 350 | 236 |
| 5 | 島根 | 650 | 227 | 77 |
Step 1 — 中心化 (x̄₁ = 6014.0, x̄₂ = 1531.6, ȳ = 690.8):
Step 2 — 正規方程式 XTX β = XTy の係数:
Step 3 — 2×2 連立を解く(クラメルの公式):
Step 4 — VIF (x₁ を x₂ で回帰した R²):
Step 5 — Python (numpy) で同じ計算を再現し、 5 都道府県の手計算と一致することを確認:
1 2 3 4 5 6 7 8 | import numpy as np X = np.array([[14086,3205],[8763,2424],[5103,1452],[1468,350],[650,227]],dtype=float) y = np.array([1513,984,644,236,77],dtype=float) Xc = X - X.mean(0); yc = y - y.mean() beta = np.linalg.solve(Xc.T@Xc, Xc.T@yc) print(f"β = {beta.round(4)}") r2_x = np.corrcoef(X.T)[0,1]**2 print(f"VIF(x1) = {1/(1-r2_x):.1f}") |
💬 手計算(Step 3〜4)と Python 出力が一致。 5 都道府県のように説明変数が高相関だと VIF が 40 を超え、 全 47 都道府県の本格回帰でも β の標準誤差が膨れ上がる。 説明変数選択時に 多重共線性をまず確認すべき理由がここに表れる。
scikit-learn / pandas を使った最小実装パターン。 上の SSDSE-B 計算と同じスタイルですが、 ここでは「読み込み→前処理→学習→評価」のテンプレを 4 つのスニペットに分けます。
1 2 3 4 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1) df = df[df['年度'] == 2023].reset_index(drop=True) print(df.shape, df.columns.tolist()[:8]) |
1 2 3 | X = df[['総人口','65歳以上人口']].values y = df['15歳未満人口'].values print('X shape =', X.shape, ', y shape =', y.shape) |
1 2 3 4 5 6 | from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestRegressor X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, random_state=0) model = RandomForestRegressor(n_estimators=300, random_state=0).fit(X_tr, y_tr) print('R^2 (test) =', model.score(X_te, y_te)) |
1 2 3 4 5 6 | import matplotlib.pyplot as plt pred = model.predict(X_te) plt.scatter(y_te, pred) plt.plot([y_te.min(), y_te.max()], [y_te.min(), y_te.max()], 'r--') plt.xlabel('実測'); plt.ylabel('予測'); plt.title('「説明変数」関連モデルの予測精度') plt.tight_layout(); plt.savefig('out.png', dpi=150) |
※ 「説明変数」固有の本格コードは上の 🧮 SSDSE-B 実値計算 節を参照。
説明変数 x(横軸)と目的変数 y(縦軸=15歳未満人口)の関係を、 手を動かして体感します。 データは SSDSE-B-2026(2023年) の 5 都道府県の実測値(総人口・65歳以上人口・15歳未満人口、 単位:千人)。 まず どの列を説明変数にするか をボタンで選び、 次に 青い点を横にドラッグ して「x をこの値にしたら y はいくつと予測されるか」を確かめてください。
—
操作:ボタンで説明変数を切り替え/散布図を左右にドラッグ(タッチ可)で予測したい x を移動。 オレンジの直線が回帰直線 $\hat y=\beta_0+\beta_1 x$、 青い点線がドラッグ位置の予測です。 計算はブラウザ内で最小二乗法により厳密に実行しています(丸めなし)。
「総人口」を選ぶと点がきれいに一直線に並び(r≈0.99)、 x が決まれば y をかなり正確に予測できます。 これが「良い説明変数」。 傾き β₁ は x が 1 千人増えたときに y が何千人変わるかを表す予測の変換レートです。 一方「ダミー(無相関)」を選ぶと直線はほぼ水平(β₁≈0、 R²≈0)になり、 x をいくら動かしても予測 ŷ は平均値からほとんど動きません。 無関係な変数は予測に寄与しないことが図で分かります。
この体験は説明変数 1 つの単回帰ですが、 実務では複数を同時に使う 重回帰 が基本です。 「相関が強い列だけ残す」「無相関な列は落とす」という判断は 特徴量選択の第一歩。 ただし相関が強い列同士は片方に絞る(多重共線性回避)、 という上の落とし穴と両立させる必要があります。 予測対象そのものである 目的変数 との対比も押さえておきましょう。
| タイプ | 例 | 取扱い |
|---|---|---|
| 連続 | 身長、 所得 | そのまま/標準化/対数変換 |
| カテゴリ(名義) | 性別、 地域 | OneHotエンコード |
| 順序 | 満足度1-5 | 整数化 or OneHot |
| 日時 | 購入日 | 年/月/曜日に分解、 周期特徴量 |
| テキスト | レビュー文 | TF-IDF or 埋め込みでベクトル化 |
ここからは 説明変数(explanatory variable)という用語固有の 4 つの視点(定義/実装手順/コード解釈/落とし穴の理由)を、 SSDSE-B-2026 都道府県データを軸にストーリーとして連結します。 「説明変数」は単純な「入力 x」ではなく、 研究設計と統計推論の交点に位置する重要概念です。 単なる手続き的理解では本質を捉えられません。
回帰分析における $X$ には複数の呼び方があります。 統計学では 独立変数(independent variable)、 経済学では 外生変数(exogenous variable)、 機械学習では 特徴量(feature)、 そして本ページの主役 説明変数(explanatory variable)。 「説明」という日本語は、 「目的変数 $Y$ の変動を $X$ で説明する」という統計的因果関係の含意を持っています。 SSDSE-B-2026 で「医療費(A6502)を、 高齢化率(A1303/A1101)と人口密度で説明する」と書くとき、 高齢化率と人口密度が説明変数です。 ただし、 「説明できる ≠ 因果関係がある」という点が最大の落とし穴で、 「相関と因果は別物」という統計の鉄則を踏まえずに「説明変数」と呼ぶと議論が混乱します。 厳密に因果を主張したいなら、 ランダム化比較試験(RCT)か操作変数法など因果推論の道具立てを併用する必要があります。
SSDSE-B-2026 で説明変数を回帰モデルに投入するまでの流れは次のとおりです。 ① 候補列の選択:A1101(総人口)、 A1303(高齢人口)、 A1303/A1101(高齢化率)、 A4101(出生数)、 A4200(死亡数)など。 ② 多重共線性チェック:人口と出生数は強い正の相関(r > 0.95)。 両方入れると VIF > 10 で係数不安定。 一方を落とすか主成分分析で集約。 ③ 標準化:尺度の異なる変数(人口は数万 〜 数百万、 高齢化率は 0.2 〜 0.4)を StandardScaler で平均 0・分散 1 に揃える。 これで係数の絶対値が「効果の大きさ」として比較可能に。 ④ カテゴリ変数のエンコード:地方(北海道・東北・関東 …)を one-hot エンコード。 ⑤ モデル投入:sklearn の LinearRegression().fit(X, y)。 ⑥ 係数の解釈:標準化済みなら係数 = 標準化効果量。 ここまでの 6 段階を毎回省略せず実行するのが、 説明変数を「使う」ことの実体です。
sklearn では X.shape = (n_samples, n_features) の 2D 配列が説明変数。 SSDSE-B-2026 なら X.shape = (47, k)(47 県 × k 個の説明変数)。 1 列だけ使う単回帰でも X = df[['feature']](二重括弧)で 2D を維持するのが定石。 X = df['feature'] は 1D Series でエラー。 pandas の DataFrame をそのまま渡せるのが scikit-learn 1.0 以降の便利機能で、 列名が保持され、 feature_importances_ で参照可能。 説明変数の名前を残しておくと、 後で結果報告するときに「X1」「X2」ではなく「高齢化率」「人口密度」と書けて読みやすい。
「説明変数」という用語の最大の罠は、 「説明」という日本語が因果関係を暗示することです。 SSDSE-B-2026 で「高齢化率が高い県ほど医療費が高い」という相関を見つけたとき、 「高齢化が医療費を引き上げる」と結論したくなります。 しかしこれは シンプソンのパラドックス の罠かもしれません。 高齢化率も医療費も「県の経済発展度」という第三の交絡因子(confounder)で説明される可能性があり、 真の因果関係ではないかもしれない。 観察データから因果を主張するには、 操作変数(IV)・差の差分(DID)・回帰不連続デザイン(RDD)・傾向スコアマッチング(PSM)など因果推論の道具立てが必要です。 「説明変数を投入して有意な係数が出た」だけでは因果の証明にならない ── これが、 説明変数を扱うすべての研究者が忘れてはならない統計の鉄則です。
線形回帰モデル $Y = \beta_0 + \beta_1 X_1 + \beta_2 X_2 + \dots + \beta_k X_k + \varepsilon$ を声に出して読むと、 「目的変数 $Y$ は、 切片 $\beta_0$ に、 各説明変数 $X_j$ に重み $\beta_j$ をかけて足したもの、 さらに誤差項 $\varepsilon$ を足したもので表される」となります。 ここで $X_1, X_2, \dots, X_k$ がすべて 説明変数 で、 $k$ は説明変数の個数。 SSDSE-B-2026 で「医療費 $Y$ を 高齢化率 $X_1$ と人口密度 $X_2$ で説明」する場合、 $k = 2$ となります。
係数 $\beta_j$ の意味は「他の説明変数を一定に保ったとき、 $X_j$ が 1 単位増えると $Y$ が $\beta_j$ だけ変化する」です。 「他を一定」(ceteris paribus)が重要で、 単回帰と多変量回帰で同じ $X_1$ でも係数が違うことがあります。 これは多重共線性や交絡の影響です。 標準化済みデータ(平均 0・分散 1)で回帰すれば、 $\beta_j$ は「$X_j$ の 1 標準偏差変化が $Y$ にどれだけの標準偏差変化を引き起こすか」を表し、 説明変数間の効果量を直接比較できます。 SSDSE-B-2026 で「高齢化率の標準化係数 = 0.6」「人口密度の標準化係数 = 0.3」なら、 高齢化率の効果が約 2 倍大きい、 と読めます。
誤差項 $\varepsilon$ は「$Y$ のうち、 $X_1, \dots, X_k$ では説明しきれない残差」。 説明変数を増やすほど $\varepsilon$ は小さくなり、 決定係数 $R^2 = 1 - \text{Var}(\varepsilon) / \text{Var}(Y)$ が 1 に近づきます。 ただし「説明変数を闇雲に増やす」と過学習を招き、 訓練データには適合するがテストデータで予測精度が落ちます。 「必要最小限の説明変数で必要十分な精度」を目指すのが、 オッカムの剃刀的な統計モデリングの美学です。 数式は「説明変数の役割」を明示しますが、 「どの変数を選ぶか」「どう前処理するか」「結果をどう因果的に解釈するか」は数式の外側の、 研究者の判断と責任です。
SSDSE-B-2026 の都道府県別データから、 説明変数選択 → 前処理 → 回帰モデル投入の一連の流れを示します。
| 列コード | 意味 | 想定される目的変数 | 注意点 |
|---|---|---|---|
| A1101 | 総人口 | 医療費、 教育費 | 対数変換推奨 |
| A1303/A1101 | 高齢化率 | 医療費 | 割合なので 0-1 スケール |
| A1301/A1101 | 年少率 | 教育費、 子育て関連 | 高齢化率と負相関 |
| A4101 | 出生数 | 人口動態 | 人口と共線性 |
| A4200 | 死亡数 | 医療費、 高齢化 | 人口と共線性 |
| B4101 | 年平均気温 | 健康、 エネルギー消費 | 地理的バイアス |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import pandas as pd from sklearn.linear_model import LinearRegression from sklearn.preprocessing import StandardScaler df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年に限定 # 説明変数:高齢化率、 出生数(人口で正規化)、 死亡数(人口で正規化) df['aging'] = df['A1303'] / df['A1101'] df['birth_rate'] = df['A4101'] / df['A1101'] df['death_rate'] = df['A4200'] / df['A1101'] X = df[['aging', 'birth_rate', 'death_rate']] y = df['A1101'] # 例:人口を目的変数(実用上は別の指標を使う) Xs = StandardScaler().fit_transform(X) model = LinearRegression().fit(Xs, y) print(dict(zip(X.columns, model.coef_))) print('R²:', model.score(Xs, y)) |
1 2 3 4 5 6 7 8 | import pandas as pd from statsmodels.stats.outliers_influence import variance_inflation_factor df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年に限定 X = df[['A1101', 'A1301', 'A1302', 'A1303', 'A4101', 'A4200']] for i, col in enumerate(X.columns): vif = variance_inflation_factor(X.values, i) print(f'{col}: VIF = {vif:.2f}') |
| 用語 | 分野 | 同義 / 違い |
|---|---|---|
| 独立変数 | 統計学 | ほぼ同義、 実験計画で多用 |
| 外生変数 | 計量経済 | モデル外で決まる変数 |
| 特徴量 | 機械学習 | 同義、 予測重視 |
| 予測子 | 統計学 | 予測モデルの入力 |
| 共変量 | 医学統計 | 調整変数として使う |
| 入力変数 | 工学 | 汎用、 入出力の対応 |
| 交絡因子 | 因果推論 | $X$ と $Y$ 両方に影響する第三変数 |
$X_1 \times X_2$ を新たな変数として追加。 「高齢化率 × 人口密度」のように、 2 つの説明変数の相乗効果をモデル化。 sklearn の PolynomialFeatures(interaction_only=True)。
$X^2, X^3$ などを追加して非線形関係を線形回帰で表現。 過学習リスクと表現力のトレードオフ。
人口・所得など正の歪んだ分布は np.log1p(X) で対数化。 弾力性係数として解釈可能に。
連続変数を区間で離散化(年齢を「若年・中年・高齢」3 段階)。 非線形関係を線形モデルで扱える。
カテゴリ変数を「そのカテゴリ内の目的変数の平均値」で置換。 one-hot より次元が少なく済む。 ただしリーケージ注意。
深層学習で高次元カテゴリを低次元連続ベクトルに変換。 「県」を 8 次元ベクトルで表すなど、 ニューラルネットの特徴量化。
1805 年 Legendre が最小二乗法を発表、 説明変数と目的変数の関係を線形モデルで定式化。 1885 年 Francis Galton が親子の身長関係で「回帰」を造語、 説明変数(親の身長)と目的変数(子の身長)の関係を分析。 20 世紀初頭 Karl Pearson と Ronald Fisher が現代的な統計学を確立し、 「独立変数」「説明変数」という用語が定着。 1934 年 Tinbergen がマクロ経済モデルに多変数回帰を導入、 経済学に「外生変数」概念を持ち込む。 1986 年 Judea Pearl が因果ベイジアンネットワークで「説明と因果」の区別を厳密化、 説明変数の解釈の限界を理論化。 2010 年代 機械学習ブームで「特徴量」が広く使われるようになり、 「説明」よりも「予測」を強調する流れが加速。
「どの変数を説明変数に入れるか」は、 研究設計の最重要決定の 1 つです。 統計学・機械学習で標準化された 7 つの選択戦略を紹介します。
「先行研究と理論からこの変数は関係あるはず」と仮説駆動で選ぶ。 SSDSE-B-2026 で「医療費を予測したい」なら、 既存の医学・公衆衛生研究から「高齢化率・人口密度・所得」を選ぶ。 最も健全だが、 先行研究が薄い分野では使えない。
目的変数との相関係数が高い順に変数を並べ、 上位 N 個を採用。 単純だが多重共線性を見逃すリスク。
forward / backward / stepwise。 P 値や AIC を基準に変数を追加・削除する古典的手法。 過学習リスクが知られており、 現代的には Lasso を推奨。
回帰係数の絶対値和に penalty を課し、 不要な変数の係数を 0 に潰す。 自動変数選択。 SSDSE-B-2026 の数百列から自動絞り込み可能。
model.feature_importances_ で各変数の予測寄与度を取得。 非線形関係も拾えるが、 相関の高い変数間で寄与が分散する。
機械学習モデルの説明変数寄与度を行ごとに分解。 「この県では高齢化率が大きく医療費を押し上げている」という解釈が可能。
Judea Pearl の因果ダイアグラム(DAG)で「真の因果変数」「交絡因子」「媒介変数」を区別、 因果推論の標準的手法。 d-separation 基準で「調整すべき変数集合」を導出。
目的変数:A6502(医療費総額)、 説明変数候補:A1101(総人口)、 A1303/A1101(高齢化率)、 A4200/A1101(粗死亡率)、 A4101/A1101(粗出生率)、 B4101(年平均気温)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import pandas as pd from sklearn.linear_model import LinearRegression, Lasso from sklearn.preprocessing import StandardScaler df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年に限定 df['aging'] = df['A1303'] / df['A1101'] df['death_rate'] = df['A4200'] / df['A1101'] df['birth_rate'] = df['A4101'] / df['A1101'] X = df[['A1101', 'aging', 'death_rate', 'birth_rate', 'B4101']] y = df['A1101'] # 仮の目的変数 Xs = StandardScaler().fit_transform(X) # OLS ols = LinearRegression().fit(Xs, y) print('OLS:', dict(zip(X.columns, ols.coef_))) # Lasso lasso = Lasso(alpha=0.1).fit(Xs, y) print('Lasso:', dict(zip(X.columns, lasso.coef_))) |
| 項目 | 記述例 |
|---|---|
| 変数の選択根拠 | 「先行研究 X[1] に基づき高齢化率を含めた」 |
| 変数の定義 | 「高齢化率 = A1303 / A1101 × 100」 |
| 記述統計 | 平均、 標準偏差、 最小、 最大 |
| 前処理 | 「対数変換、 標準化を適用」 |
| 多重共線性チェック | VIF 値の表掲載 |
| 符号の事前期待 | 「理論上正の符号を予想」 |
| 推定結果 | 係数、 標準誤差、 t 値、 p 値 |
| 解釈 | 「高齢化率 1pp 上昇で医療費 X 万円増」 |
| 因果の限界 | 「観察データのため因果は主張不可」 |
SSDSE-B-2026 の都道府県別医療費を、 高齢化率・人口密度・所得水準で説明。 多重共線性に注意しつつ、 政策提言の根拠を作る。
大学進学率を、 1 世帯当たり所得・学校教員数・年少人口比で説明。 教育格差研究の定番。
都道府県別観光客数を、 観光地数・気候・宿泊施設数で説明。 SSDSE-A-2025 と組み合わせる。
選挙投票率を、 高齢化率・人口密度・所得で回帰。 政治学の基本トピック。
Kaggle コンペで「Tabular データ + 数百列の説明変数」を扱う典型ケース。 特徴量エンジニアリング・選択・SHAP 解釈の総合演習。
| # | 項目 | 配点 |
|---|---|---|
| 1 | 理論的根拠あり | 1 |
| 2 | 変数定義明示 | 1 |
| 3 | 単位明示 | 1 |
| 4 | スケール統一(標準化) | 1 |
| 5 | VIF < 10 | 1 |
| 6 | サンプル / 変数 ≥ 10 | 1 |
| 7 | 記述統計を表掲載 | 1 |
| 8 | 外れ値処理を記載 | 1 |
| 9 | 欠損処理を記載 | 1 |
| 10 | カテゴリ変数は one-hot | 1 |
| 11 | 符号の事前期待を明示 | 1 |
| 12 | 残差プロットで線形性確認 | 1 |
| 13 | 交絡因子を DAG で整理 | 1 |
| 14 | 因果主張の限界を明示 | 1 |
| 15 | 再現可能なコード公開 | 1 |
重回帰モデルは一般に、目的変数 $Y$ を $p$ 個の説明変数 $X_1, X_2, \ldots, X_p$ の線形結合と誤差項 $\epsilon$ の和として表現する。 都道府県データで「出生数」を「総人口・65歳以上人口・年平均気温」で説明する場面を想定すると、次の式が基盤となる。
$$ Y_i = \beta_0 + \beta_1 X_{i1} + \beta_2 X_{i2} + \cdots + \beta_p X_{ip} + \epsilon_i, \quad i=1,2,\ldots,n $$
$$ \hat{\boldsymbol{\beta}} = (\mathbf{X}^{\top}\mathbf{X})^{-1}\mathbf{X}^{\top}\mathbf{y} $$
| 記号 | 意味 | SSDSE-B-2026 での具体例 |
|---|---|---|
$Y_i$ | 目的変数 (被説明変数)、サンプル $i$ の応答値 | 都道府県 $i$ の出生数 (人) |
$X_{ij}$ | サンプル $i$ における $j$ 番目の説明変数の値 | 都道府県 $i$ の総人口、65歳以上人口、年平均気温など |
$\beta_0$ | 切片 (intercept)、説明変数すべてが 0 のときの $Y$ の期待値 | 総人口・高齢人口・気温が 0 の架空の県の出生数 |
$\beta_j$ | 偏回帰係数、他変数を一定にしたとき $X_j$ が 1 単位増えたときの $Y$ の変化量 | 総人口 1 万人増あたりの出生数増加 (約 75 人) |
$\epsilon_i$ | 誤差項、説明変数では捉えきれない変動 (期待値 0、分散 $\sigma^2$) | 産業構造の違い、地理的特性など説明変数外の要因 |
$\mathbf{X}$ | $n \times (p+1)$ の計画行列 (design matrix)、説明変数を行列形式に積む | 47 行 × 4 列 (切片+総人口+高齢人口+気温) |
$\hat{\boldsymbol{\beta}}$ | 最小二乗推定量、$\sum (Y_i - \hat{Y}_i)^2$ を最小化するパラメータ | scikit-learn の LinearRegression.coef_ として取得 |
重要なのは「偏回帰係数」という呼称である。$\beta_j$ は単純に「$X_j$ が $Y$ に及ぼす効果」ではなく、 「他の説明変数を統制したうえで $X_j$ が $Y$ に及ぼす効果」を意味する。 したがって同じ説明変数でも、モデルに含める他の変数が変われば係数の値・符号・有意性すべてが変わりうる。 この事実は説明変数の選び方を語るうえで最も基本かつ重要な性質である。
式 $\hat{\boldsymbol{\beta}} = (\mathbf{X}^{\top}\mathbf{X})^{-1}\mathbf{X}^{\top}\mathbf{y}$ は、 観測ベクトル $\mathbf{y}$ を計画行列 $\mathbf{X}$ の列空間 (column space) へ正射影する操作にほかならない。 予測値 $\hat{\mathbf{y}} = \mathbf{X}\hat{\boldsymbol{\beta}}$ は、説明変数群が張る平面上での $\mathbf{y}$ に最も近い点である。 残差 $\mathbf{y} - \hat{\mathbf{y}}$ はこの平面と直交する。これを直交条件 (normal equation) と呼ぶ。
もし $\mathbf{X}^{\top}\mathbf{X}$ が 正則でない (= 逆行列が存在しない) 場合、解は一意に定まらない。 これは説明変数同士が完全な線形従属関係にあるとき (例: 「男性ダミー」と「女性ダミー」を両方入れる) に発生する。 この問題を 多重共線性 と呼び、後段で詳しく扱う。
説明変数を 1 つだけ使う単回帰と、3 つに増やした重回帰で、決定係数 $R^2$ がどれだけ向上するかを、SSDSE-B-2026 の 47 都道府県データ (2023 年) で実際に確かめる。 目的変数は「出生数 (A4101)」、説明変数候補は「総人口 A1101」「65歳以上人口 A1303」「年平均気温 B4101」とする。
このコードでやること: SSDSE-B-2026 を読み込み、単回帰 ($Y \sim X_1$) と重回帰 ($Y \sim X_1+X_2+X_3$) の $R^2$ を比較する。
📥 入力データ (SSDSE-B-2026 の関連列を抜粋):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import pandas as pd import statsmodels.api as sm from sklearn.linear_model import LinearRegression df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True) # 2023 年に限定 # 単回帰: 人口 1 変数のみ X1 = df[['A1101']] # 総人口 y = df['A4101'] # 出生数 m1 = LinearRegression().fit(X1, y) print('単回帰 R^2 =', round(m1.score(X1, y), 4)) # 重回帰: 総人口 + 65歳以上人口 + 年平均気温 (スケール差に強い statsmodels の OLS を使用) X3 = sm.add_constant(df[['A1101', 'A1303', 'B4101']]) m3 = sm.OLS(y, X3).fit() print('重回帰 R^2 =', round(m3.rsquared, 4)) print('係数:', m3.params.round(4).to_dict()) |
📤 実行例 (47 都道府県、SSDSE-B-2026 で実測):
💬 結果の読み方: 総人口 1 変数だけでも $R^2=0.991$ と高いが、65歳以上人口と年平均気温を追加すると $R^2=0.995$ に上昇する (+0.0045)。 係数を見ると、総人口 1 人増で出生数は約 0.0075 人増 (=1 万人あたり約 75 人)、65歳以上人口 1 人増では逆に -0.0057 人 (高齢者比率の高い県ほど出生数が少ない傾向)、年平均気温が 1℃ 高いと出生数は約 437 人多い (暖かい県でやや多く見える交絡的な関係)。 符号が直感に反するときや交絡が疑われるときは「他変数を統制した条件付き効果」であることを思い出す必要がある。
前節で出生数を「総人口・65歳以上人口・年平均気温」で説明したが、総人口と65歳以上人口は明らかに連動している (規模の大きい県ほど高齢者数も多い)。 こうした「説明変数同士の強い相関」を 多重共線性 といい、係数の標準誤差を膨張させ、推定を不安定にする。 分散拡大係数 (Variance Inflation Factor、VIF) は、これを定量化する標準ツールである。
$$ \mathrm{VIF}_j = \frac{1}{1 - R_j^2}, \quad R_j^2 = \text{他の説明変数で } X_j \text{ を回帰した時の決定係数} $$
$R_j^2 = 0$ (= $X_j$ が他変数と完全に無相関) なら $\mathrm{VIF}_j = 1$ — 多重共線性なし$R_j^2 = 0.8$ なら $\mathrm{VIF}_j = 5$ — 注意レベル (経験則の閾値)$R_j^2 = 0.9$ なら $\mathrm{VIF}_j = 10$ — 多くの教科書が「除外検討」を推奨する境界$R_j^2 \to 1$ なら $\mathrm{VIF}_j \to \infty$ — 完全共線、係数推定不能
このコードでやること: statsmodels の variance_inflation_factor で、3 説明変数の VIF を計算し、どれが共線性問題を起こしているかを特定する。
📥 入力データ: 前節と同じ SSDSE-B-2026 の 3 列 (総人口 A1101・65歳以上人口 A1303・年平均気温 B4101)
1 2 3 4 5 6 7 8 9 10 11 12 | import pandas as pd from statsmodels.stats.outliers_influence import variance_inflation_factor from statsmodels.tools.tools import add_constant df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True) # 2023 年に限定 X = df[['A1101', 'A1303', 'B4101']] Xc = add_constant(X) for i, col in enumerate(Xc.columns): vif = variance_inflation_factor(Xc.values, i) print(f'{col:10} VIF = {vif:8.2f}') |
📤 実行例 (SSDSE-B-2026、47 都道府県):
💬 結果の読み方: 総人口と65歳以上人口の VIF はいずれも約 61 で、境界値 10 を大きく超える強い共線性が発生している。 これは総人口と65歳以上人口の相関が $r \approx 0.99$ とほぼ同一の情報量だからである。 対処法は (1) どちらか一方を除外、(2) 両者の比 (高齢化率=65歳以上人口/総人口) に変換、(3) Ridge/Lasso で正則化、のいずれか。 年平均気温は VIF=1.11 と健全で、これは独立した情報源として残してよい。
なお、切片 (const) の VIF が 85 と高いのは、説明変数の絶対値スケール (総人口は数百万、気温は 2 桁) が大きく違うことの数値的副作用であり、 多くのテキストでは切片を除いて解釈する。中心化 (mean centering) すれば const の VIF は劇的に下がる。
説明変数には数値 (連続量) だけでなく、カテゴリ (質的変数) も含めることができる。ただし回帰モデルが扱える形に変換する必要がある。 SSDSE-B-2026 の都道府県を「8 地方区分 (北海道・東北・関東・中部・近畿・中国・四国・九州沖縄)」にまとめて説明変数に加える例を見る。
$$ Y = \beta_0 + \beta_1 X_{pop} + \sum_{k=2}^{8} \beta_k D_k + \epsilon, \quad D_k \in \{0,1\} $$
8 つの地方を直接 8 個のダミー変数で表現すると、$\sum_k D_k = 1$ という恒等式が成立し、切片と完全共線になる (「ダミー変数トラップ」と呼ばれる)。 これを避けるため、必ず 1 つを ベースカテゴリ として除外し、残り $K-1$ 個のダミーをモデルに入れる。 例えば「北海道」をベースにすれば、$\beta_k$ は「北海道に対する地方 $k$ の上乗せ効果」と解釈される。
このコードでやること: SSDSE-B-2026 の都道府県名を 8 地方ブロックに割り当て、pd.get_dummies(drop_first=True) でダミー化し、総人口と地方ダミーで出生数を重回帰する。
📥 入力データ: 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 23 24 25 26 27 28 29 30 | import pandas as pd import statsmodels.api as sm df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True) # 2023 年に限定 # 47 都道府県ぶんを都道府県コードから割り当てる。 # 一部だけ書いて「以下同様」で済ませると、残りが NaN になり # ダミーがすべて 0 になって係数が意味を失う。 def _region(code): n = int(str(code).lstrip('R')) // 1000 if n == 1: return '北海道' if n <= 7: return '東北' if n <= 14: return '関東' if n <= 23: return '中部' if n <= 30: return '近畿' if n <= 35: return '中国' if n <= 39: return '四国' return '九州沖縄' df['地方'] = df['Code'].apply(_region) df['地方'] = pd.Categorical(df['地方'], categories=['北海道','東北','関東','中部','近畿','中国','四国','九州沖縄']) # 先頭=ベース # ダミー化 (drop_first=True で先頭カテゴリ「北海道」がベース) D = pd.get_dummies(df['地方'], drop_first=True, dtype=int) X = sm.add_constant(pd.concat([df[['A1101']], D], axis=1).astype(float)) y = df['A4101'].astype(float) m = sm.OLS(y, X).fit() print('R^2 =', round(m.rsquared, 4)) for c, b in m.params.items(): print(f'{c:12} {b:12.2f}') |
📤 実行例 (SSDSE-B-2026):
💬 結果の読み方: 九州沖縄ダミーが +8338 人と最大、関東地方が +4573 人と最小。
これは「人口効果を統制してもなお、九州沖縄は北海道より出生数が多い」ことを意味する (= 地域ごとの出生力の違いが説明変数として効いている)。
pandas の get_dummies は手軽だが、scikit-learn パイプラインに統合するなら OneHotEncoder(drop='first') を使う方が再利用性が高い。
| 特徴 | pd.get_dummies |
OneHotEncoder |
|---|---|---|
| 所属 | pandas | scikit-learn |
| 出力型 | DataFrame (列名つき) | 疎行列または ndarray |
| 未知カテゴリ | 出現順依存 (危険) | handle_unknown='ignore' で安全 |
| パイプライン統合 | × | ○ (Pipeline / ColumnTransformer) |
| ベース除外 | drop_first=True | drop='first' |
候補となる説明変数が多いとき、「どの変数をモデルに入れ、どれを外すか」は本質的に難しい問題である。 伝統的には p 値ベースの段階的選択 (stepwise) が使われてきたが、現代では正則化や情報量規準を組み合わせるのが標準である。
| 手法 | 考え方 | 長所 | 短所・落とし穴 |
|---|---|---|---|
| 前進選択 (Forward) | 空モデルから 1 つずつ p 値の低い変数を追加 | 計算が軽い、解釈が直感的 | 局所最適に陥る、選択後の p 値が信頼できない |
| 後退選択 (Backward) | 全変数モデルから p 値の高いものを 1 つずつ除外 | 前進選択より見落としが少ない | $p > n$ では実行不能、共線時に不安定 |
| Stepwise | 前進と後退を交互に | 中規模問題で妥当な解 | 「選択後の検定の歪み」問題は解決しない |
| AIC / BIC | 情報量規準で全モデル比較 | 理論的根拠が明快 | $2^p$ 通り探索は組合せ爆発 |
| Lasso ($L_1$) | 罰則項で係数を 0 に圧縮 | $p \gg n$ でも動く、自動選択 | 共線変数のうち 1 つを恣意的に選ぶ、係数バイアス |
| Elastic Net | $L_1+L_2$ の混合 | 共線変数をグループで残せる | ハイパラ調整が 2 次元化 |
| ドメイン知識 | 専門的に意味のある変数のみ採用 | 解釈可能性が最高 | 担当者の主観・盲点が混入 |
このコードでやること: SSDSE-B-2026 の 47 都道府県データ (2023 年) で出生数 (A4101) を目的変数とし、5 個の候補説明変数 (総人口・65歳以上人口・年平均気温・婚姻件数・死亡数) から Lasso が自動選択する変数を観察する。
📥 入力データ: SSDSE-B-2026 の 5 列を標準化して投入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import pandas as pd from sklearn.linear_model import LassoCV from sklearn.preprocessing import StandardScaler df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True) # 2023 年に限定 cols = ['A1101', 'A1303', 'B4101', 'A9101', 'A4200'] X = StandardScaler().fit_transform(df[cols]) y = df['A4101'] lasso = LassoCV(cv=5, random_state=None).fit(X, y) print('最適 alpha =', round(lasso.alpha_, 2)) for c, b in zip(cols, lasso.coef_): mark = '●' if abs(b) > 1 else '.' print(f'{mark} {c:10} {b:14.2f}') |
📤 実行例:
💬 結果の読み方: Lasso は 5 個から 3 個 (総人口・婚姻件数・年平均気温) を残し、65歳以上人口と死亡数を係数 0 に圧縮した。
65歳以上人口は総人口と $r \approx 0.99$、死亡数も総人口と強く相関するため、いずれも「人口で説明できる冗長な情報」として除外された。
ただし「Lasso が選んだ=因果的に重要」ではない点に注意。
共線な変数のうちどれを残すかは 本質的に恣意的 で、ランダムシードや CV 分割の違いで採用変数が入れ替わることが知られている。
安定性を測るには StabilitySelection や bootstrap を併用する。
回帰モデルにおける「説明変数」は、純粋に予測 (prediction) を目的とするなら何でもよい。 しかし「ある変数を操作したら $Y$ がどう変わるか」という因果的な問いに答えるには、 通常の重回帰では不十分で、因果推論 の枠組み (因果ダイアグラム・反実仮想・条件付き独立性) が必要になる。
因果推論では説明変数を「処置 (treatment) $T$」「結果 (outcome) $Y$」「共変量 (covariates) $\mathbf{Z}$」に役割分けする。 観測データから因果効果を推定するには、$Y$ と $T$ の両方に影響する「交絡因子 (confounder)」を $\mathbf{Z}$ として説明変数に含めて統制する必要がある。
$$ Y = \alpha + \tau T + \boldsymbol{\gamma}^{\top}\mathbf{Z} + \epsilon, \quad \tau = \text{平均処置効果 (ATE)} $$
| 変数の役割 | 回帰に含めるべきか? | 含めないとどうなるか |
|---|---|---|
| 交絡因子 (Confounder) | 必ず含める | 推定値にバイアスが乗る (交絡バイアス) |
| 中間変数 (Mediator) | 含めない (条件付け禁止) | 含めると直接効果と間接効果が混ざる |
| 合流点 (Collider) | 絶対に含めない | 含めると偽の相関が発生 (Berkson のパラドックス) |
| 道具変数 (Instrument) | 2 段階最小二乗法の第 1 段階に | 通常の OLS には入れない |
| 先行因子 (Y にのみ影響) | 含めると精度向上 | バイアスはないが、分散が大きいまま |
つまり「とりあえず全変数を投入する」のは因果推論では明確に間違いである。 特に 中間変数 や 合流点 を含めると、推定値が真の因果効果から乖離する。 どの変数が交絡因子で、どれが中間変数かは、データから自動判定できず、ドメイン知識と因果ダイアグラム でしか決まらない。
交絡因子の一部が観測できない場合、説明変数 $T$ と相関し、かつ誤差項 $\epsilon$ とは独立な「道具変数 $Z$」を見つけ、 2 段階最小二乗法 (2SLS) で推定する手法がある。例えば「教育年数が賃金に与える影響」を推定するとき、 生まれた四半期や義務教育年齢の制度変更を道具変数として用いる古典的研究 (Angrist & Krueger 1991) が有名。
drop_first=True または drop='first' を必ず指定する。
StandardScaler で平均 0・分散 1 に揃えてから fit する。線形回帰 (OLS) では係数値が変わるだけで結論は変わらないが、係数の大小比較は無意味になる。
| # | 確認項目 | 合格基準 |
|---|---|---|
| 1 | 予測時点で取得可能か? | 全変数 ○ |
| 2 | 欠損率 | < 5% (5-20% は補完、>20% は除外検討) |
| 3 | VIF | < 10 (理想は < 5) |
| 4 | 単位とスケール | 標準化 or ログ変換済 |
| 5 | 外れ値の扱い | Winsorize or robust regression |
| 6 | カテゴリ変数のダミー化 | drop_first=True を確認 |
| 7 | 因果的役割 (交絡/中間/合流) | DAG で整理済 |
| 8 | 解釈可能性 (符号と大きさ) | ドメイン知識と矛盾しない |
| 9 | 変数選択の検証 | CV 安定性 or bootstrap |
| 10 | test データでの $R^2$ 劣化 | < 10% 程度 (大きければ過学習) |
ここからは、 説明変数 (explanatory variable) を実務で扱う際に避けて通れない 14 のテーマを SSDSE-B-2026 (47 都道府県データ) を題材に踏み込んで解説する。 単に「目的変数 y を説明する x」と覚えるだけでは、 実務で再現性のある分析にはならない。
説明変数の特性は分布形・関係性・群間差の 3 つの観点で必ず確認する。
| 役割 | 意味 | SSDSE-B-2026 例 |
|---|---|---|
| 主効果変数 | 目的変数を直接動かす主因 | 総人口 → 出生数 |
| 調整変数 (covariate) | 主因の効果を「補正」する | 年齢構成で給与水準を補正 |
| 媒介変数 (mediator) | 原因 → 結果の経路上にある | 教育年数 → 所得 → 健康 |
| 交絡変数 (confounder) | 原因と結果の両方に影響 | 都市度 → 平均所得・通勤時間 |
| 交互作用変数 | 2 変数の組合せで効果が変わる | 地方 × 高齢化率 |
| 制御変数 (control) | 分析の前提条件として固定 | 調査年・地域ブロック |
| 計測代理変数 (proxy) | 本来測りたいものの代用 | 夜間光量 → 経済活動代理 |
| 道具変数 (instrument) | 因果推定で外生的な揺らぎを供給 | 制度変更時刻 → 補助金額 |
| 型 | 例 | 主な前処理 | 注意点 |
|---|---|---|---|
| 連続量 (interval/ratio) | 人口、所得 | 標準化・対数化 | 外れ値・歪度 |
| 順序カテゴリ | 満足度 1-5 | 整数化 or one-hot | 等間隔仮定の妥当性 |
| 名義カテゴリ | 都道府県、業種 | one-hot, target encoding | 水準数爆発、リーク |
| 二値 | 男女、有無 | 0/1 にエンコード | 基準カテゴリ選択 |
| 時系列 | 年度、四半期 | ラグ、差分、周期化 | 定常性、季節調整 |
| テキスト | 商品レビュー | TF-IDF, embedding | 次元の呪い |
| 画像 | 店舗写真 | CNN 特徴抽出 | 転移学習の選択 |
| 地理座標 | 緯度経度 | クラスタリング・距離 | 球面距離 vs 平面 |
説明変数同士が強く相関すると回帰係数の解釈が不安定になる。 Variance Inflation Factor (VIF) で診断する。
| VIF 値 | 判定 | 対処 |
|---|---|---|
| 1.0 - 2.0 | 問題なし | そのまま使う |
| 2.0 - 5.0 | 軽度 | 必要なら残す |
| 5.0 - 10.0 | 中等度 | 主成分分析や Ridge を検討 |
| 10.0 以上 | 強い共線性 | 変数削除、合成、L2 正則化 |
このコードでやること: 47 都道府県データ (2023 年) から「総人口」を説明変数 (x)、「出生数」を目的変数 (y) として単回帰し、 係数・決定係数を求める。
📥 入力データ (SSDSE-B-2026.csv 抜粋、 2023 年):
1 2 3 4 5 6 7 8 9 10 11 12 13 | import pandas as pd from sklearn.linear_model import LinearRegression df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True) x = df[['A1101']].astype(float).values # 総人口 y = df['A4101'].astype(float).values # 出生数 model = LinearRegression().fit(x, y) print(f'回帰係数 (傾き): {model.coef_[0]:.4f}') print(f'切片 : {model.intercept_:.2f}') print(f'決定係数 R^2: {model.score(x, y):.4f}') |
📤 実行すると次の出力が得られる:
💬 R² = 0.9909 は「出生数の分散の 99% が総人口で説明される」という非常に強い説明力。 傾き 0.0061 は「総人口が 1 人増えると出生数が約 0.0061 人増える (=1 万人あたり約 61 人)」と読む。 ただしこれは「相関」であり、 因果ではない点に注意。 出生数と総人口は互いに関連し合う関係でもあり、 ラグ変数や道具変数を併用しないと因果は語れない。
| パターン | 使い所 | 例 |
|---|---|---|
| 対数変換 log(x+1) | 右に裾を引く分布 | 人口、所得 |
| 標準化 (z-score) | 線形モデル、距離ベース | 身長と体重を同列に扱う |
| min-max 正規化 | ニューラルネット入力 | 画像ピクセル値 |
| 多項式特徴 | 非線形関係の近似 | x, x², x³ を追加 |
| 交互作用項 | 2 変数組合せ効果 | 地域 × 年齢 |
| ビニング (離散化) | 非線形応答 | 年齢を 10 歳刻みに |
| 欠損フラグ | 欠損自体が情報 | 未回答フラグ列 |
| ラグ特徴 | 時系列予測 | 1 期前の売上 |
| 差分・変化率 | トレンド除去 | 前年比成長率 |
| クラスタリング ID | 潜在群を変数化 | 顧客セグメント |
| 主成分 (PC) | 共線性対策 | 多変量から PC1, PC2 |
| target encoding | 高基数カテゴリ | 郵便番号 → 平均売上 |
| 手法 | 仕組み | 長所 | 短所 |
|---|---|---|---|
| 前進選択 | 有意な変数から追加 | 計算軽量 | 局所最適に陥る |
| 後退消去 | 全変数から除去 | 解釈しやすい | 変数数 > サンプル数で破綻 |
| ステップワイズ | 追加と除去を交互 | 柔軟 | 多重検定問題 |
| Lasso (L1) | 係数を 0 に縮約 | 自動選択 | 相関高い群から 1 つだけ選ぶ |
| Ridge (L2) | 係数を縮小 | 共線性に強い | 0 にならない |
| Elastic Net | L1 + L2 | 両者の長所 | ハイパラ 2 つ |
| ランダムフォレスト重要度 | 不純度減少 | 非線形対応 | 相関変数で過大評価 |
| Permutation 重要度 | 値をシャッフル | モデル非依存 | 計算コスト高 |
| SHAP | シャプレー値 | 個別予測説明可 | 計算重い |
| Boruta | 影変数比較 | 厳格 | 計算コスト高 |
| 事例 | 目的変数 | 主な説明変数 | 学び |
|---|---|---|---|
| 住宅価格予測 | 取引価格 | 面積、駅距離、築年数 | 非線形を入れないと立地効果を過小評価 |
| 離脱率予測 | 解約フラグ | 利用頻度、サポート連絡数 | サポート連絡数は逆因果 (解約意思 → 連絡) に注意 |
| 農作物収量 | 収量 kg/ha | 気温、降雨、肥料量 | 気温は U 字応答 (高すぎても低すぎても下がる) |
| 都道府県医療費 | 1 人当たり医療費 | 高齢化率、医師数、所得 | 高齢化率と医師数は相関するため共線性チェック必須 |
| 年 | 出来事 |
|---|---|
| 1805 | Legendre が最小二乗法を発表 (説明変数の概念の萌芽) |
| 1886 | Galton が「回帰」を発見 |
| 1908 | Gosset (Student) が t 分布を提示 |
| 1922 | Fisher が分散分析と説明変数体系を整備 |
| 1970 | Hoerl と Kennard が Ridge 回帰を提案 |
| 1996 | Tibshirani が Lasso を提案 |
| 2001 | Breiman がランダムフォレストを発表 (変数重要度) |
| 2017 | Lundberg らが SHAP を提案 |
| 用語 | 1 行解説 |
|---|---|
| 共変量 (covariate) | 調整目的で加える説明変数 |
| 外生変数 (exogenous) | モデル外で決まる変数 |
| 内生変数 (endogenous) | モデル内の他変数と相関する変数 |
| 潜在変数 (latent) | 直接観測できない変数 |
| 顕在変数 (observed) | 直接観測できる変数 |
| 制御変数 | 分析の前提条件として固定 |
| 条件変数 | 分析の対象を絞り込む変数 |
| 群分け変数 | カテゴリで分けるための変数 |
| 処理変数 | 因果推定における介入変数 |
| 結果変数 | 処理の結果として観測される変数 |
| 媒介変数 | 原因 → 結果の経路上にある |
| 調節変数 (moderator) | 主効果の強さを変える変数 |
説明変数の設計は分析全体の 7 割を決める最重要工程である。 「何を入れるか」だけでなく「何を入れないか」「どう変換するか」「どの順で評価するか」を体系的に管理することで、 はじめて再現性のある分析になる。 SSDSE-B-2026 のような実データを使って、 まずは小さく試し、 VIF・残差プロット・交差検証で確かめながら段階的に変数を増やすのが王道である。
| 領域 | 典型的な目的変数 | 定石の説明変数群 | 注意点 |
|---|---|---|---|
| 金融 (与信) | デフォルト確率 | 年収、勤続年数、取引履歴、業種コード | 属性差別 (sensitive attribute) を避ける |
| マーケティング | 購買、CVR | RFM (Recency, Frequency, Monetary)、サイト行動、デバイス | 同意のないトラッキングは GDPR 違反 |
| 製造業 | 不良率、稼働率 | 温度、圧力、回転数、材料ロット ID | センサー欠損、外れ値が頻発 |
| 医療 | 転帰、再入院 | 年齢、検査値、既往歴、処方歴 | 個人情報、IRB 承認、欠損が多い |
| 不動産 | 取引価格、賃料 | 面積、駅距離、築年数、周辺施設 | 立地は非線形 (駅徒歩 1 分と 5 分は大差) |
| 農業 | 収量、品質等級 | 気温、降雨、肥料、土壌成分 | 気温は U 字、灌水量にも閾値 |
| 教育 | 学業成績、合格率 | 出席率、学習時間、家庭背景 | 家庭背景は機微情報、扱い注意 |
| 交通 | 渋滞、事故率 | 時刻、曜日、天候、工事情報 | 時刻は周期化 (sin / cos) が定番 |
| 行政 (公衆衛生) | 罹患率、医療費 | 人口構成、所得分布、医療資源 | 都道府県集計はサンプルサイズ小 |
| 環境 | 大気質、河川水質 | 気象、地形、人口密度、産業集積 | 空間自己相関 (Moran I) を確認 |
| 手法 | 仕組み | 長所 | 短所 | 使い所 |
|---|---|---|---|---|
| One-hot | 各水準を 0/1 列に展開 | 線形モデルで自然 | 水準数爆発 | 少水準 (≤20) |
| Label encoding | 整数を割当 | 列数増えない | 順序を仮定 | 木系モデル |
| Ordinal encoding | 順序を持つ整数化 | 順序情報維持 | 等間隔仮定 | 満足度、学歴 |
| Target encoding | 目的変数の平均で置換 | 高基数に強い | リーク危険 | 郵便番号、商品 ID |
| Frequency encoding | 出現頻度で置換 | シンプル | 同頻度で衝突 | 探索的分析 |
| Hash encoding | ハッシュで圧縮 | メモリ効率 | 衝突 | 超高基数 |
| Embedding | 低次元ベクトル学習 | 意味距離保存 | 大規模データ必要 | NN モデル |
| Binary encoding | 2 進数で圧縮 | 列数を log オーダーに | 解釈困難 | 中基数 (20〜100) |
時系列予測では、 説明変数の作り方が予測精度を大きく左右する。 典型的な設計パターンを整理する。
| パターン | 定義 | 例 |
|---|---|---|
| ラグ (lag) | 過去 k 期前の値 | 1 期前売上、 7 日前気温 |
| 移動平均 (rolling mean) | 過去 k 期の平均 | 7 日移動平均、 30 日移動平均 |
| 移動標準偏差 | 過去 k 期のばらつき | 変動性指標 |
| 差分 | 当期 - 前期 | 前日比、 前月比 |
| 変化率 | (当期 - 前期) / 前期 | 成長率、 前年同月比 |
| 周期化 (sin/cos) | 時刻を円周上に変換 | 時間 → sin(2π h/24) |
| イベントフラグ | 特殊日の 0/1 | 祝日、 セール、 災害 |
| 季節指数 | 季節成分の平均 | 夏の電力需要指数 |
| 累積 | 期初からの累積 | 年初来売上 |
| 傾き (slope) | k 期の線形傾き | 30 日トレンド |
| モデル | 標準化 | カテゴリ encoding | 欠損処理 | 多重共線性 |
|---|---|---|---|---|
| 線形回帰 | 不要 (解釈用なら推奨) | one-hot 必須 | 必須 | 要対処 |
| Ridge / Lasso | 必須 | one-hot 必須 | 必須 | 正則化で吸収 |
| ロジスティック回帰 | 必須 (収束安定) | one-hot 必須 | 必須 | 要対処 |
| KNN | 必須 (距離ベース) | one-hot or distance metric | 必須 | 影響小 |
| SVM (RBF) | 必須 | one-hot 必須 | 必須 | 影響小 |
| 決定木 | 不要 | label 可 | 多くは耐性あり | 影響小 |
| ランダムフォレスト | 不要 | label 可 | 耐性あり | 耐性あり |
| XGBoost / LightGBM | 不要 | label or native cat | native 対応 | 耐性あり |
| ニューラルネット | 必須 | one-hot or embedding | 必須 | 影響中 |
| GMM / クラスタリング | 必須 | one-hot 必須 | 必須 | 要対処 |
説明変数は単なる「入力」ではなく、 分析者の仮説と知識を反映する設計成果物である。 「ある」変数を入れることに意味があり、 「ない」変数を入れないことにも意味がある。 SSDSE-B-2026 のような公的データで小さく試し、 散布図 → 相関行列 → VIF → 残差プロット → 交差検証の順で確かめながら徐々に変数を増やす。 そして因果を語るときは必ず back-door / front-door を意識し、 道具変数や RCT を計画的に組み合わせる。 これが 21 世紀のデータ分析者が身につけるべき説明変数設計の作法である。
次の一歩としては、 (1) 最小二乗法 で説明変数の係数解釈を学ぶ、 (2) 相関 ページで多変量関係を視覚化する、 (3) Lasso / Ridge / Elastic Net の実装に挑戦する、 の 3 つを順に行うのが効率的である。 SSDSE-B-2026 を題材に、 まず人口・所得・高齢化率といった代表的説明変数で小さな線形モデルを組み立てるところから始めよう。
ここでは 5 つの実務領域について、 説明変数設計の典型的な迷いどころと最初の一手を述べる。 SSDSE-B-2026 や e-Stat の公開データを使って手を動かすことを前提に書いた。
目的変数を「1 人当たり医療費」とすると、 直感的に思い浮かぶ説明変数は「高齢化率」「医師数」「平均所得」「人口密度」「健診受診率」である。 しかしこの 5 つは互いに強く相関する。 例えば人口密度が高い都市部は医師数も多く、 平均所得も高く、 同時に高齢化率はやや低い。 そのまま線形回帰すると VIF が 10 を超え、 個別の係数解釈が不能になる。 対処として、 (a) 主成分分析で 2 次元に圧縮、 (b) Ridge / Lasso 回帰で正則化、 (c) 領域知識から「医師数」を残し「人口密度」を削除、 の 3 つを比較するのが王道である。 さらに「都道府県」自体を固定効果として入れるパネル分析にすると、 観測できない地域固有要因を吸収できる。
目的変数を「日次売上」、 説明変数を「曜日」「祝日フラグ」「気温」「降水量」「キャンペーン有無」「前年同日売上」「移動平均 7 日」とする。 ここで未来情報リークに注意する。 当日のレシート枚数や来客数は予測時点で取得不可能なので、 説明変数には入れない。 一方、 気温予報は「予報値」を使えば未来時点で利用可能なため OK。 曜日は数値ラベル (1〜7) ではなく one-hot や sin/cos の周期化が望ましい。 さらに、 セール期間中の異常売上を識別するためにイベントフラグを別に立てる。 ラグ・移動平均は 7 / 14 / 28 / 365 日を組み合わせるとトレンドと周期の両方を捉えられる。
センサーデータが説明変数の中心になる。 温度・圧力・回転数・電流・振動・湿度の時系列を、 直近 1 分 / 10 分 / 1 時間で要約する (mean, std, min, max, p95)。 これにより 6 種類 × 5 統計量 × 3 期間 = 90 個の特徴量が自動生成される。 ここから Lasso か Random Forest 重要度で上位 20 個を選び、 残りを捨てる。 さらに材料ロット ID は target encoding で「ロット平均不良率」を当て込み、 機械 ID は固定効果として one-hot 化する。 欠損が頻発するため、 「欠損率自体」が異常検知の特徴量になることもある (欠損フラグを必ず残す)。
個人レベルでは「出席率」「学習時間」「模試成績」「家庭学習時間」が代表的説明変数となる。 ただし「家庭背景 (世帯所得、 親の学歴)」は機微情報であり、 個人を識別しない集計値で扱うか、 同意を得て扱う必要がある。 また「出席率」は時系列で変動するため、 直近 1 ヶ月の出席率と通年出席率を別変数にすると変化情報が得られる。 さらに「模試成績の伸び (傾き)」を派生変数として加えると、 単純な現在値より予測力が高まる。 これは時系列における slope 特徴の典型である。
PM2.5 濃度を目的変数、 「気温」「湿度」「風速」「風向」「気圧」「降水量」「人口密度」「工場稼働指数」を説明変数とする。 気象変数は隣接地域とも強く相関するため、 空間自己相関 (Moran I) の確認と空間ラグ変数の追加が定石。 また風向は角度 (0〜359 度) なので、 sin / cos に分解しないと「359 度と 1 度が大きく異なる」誤った距離計算になる。 さらに、 越境汚染を考慮するなら隣接地域の PM2.5 ラグ値も特徴量化すべきである。
ランダムフォレストや勾配ブースティングが出力する「重要度 (importance)」は、 直感的だが落とし穴も多い。 ここでは 5 種類の重要度指標の特徴を整理する。
| 指標 | 計算方法 | 長所 | 注意点 |
|---|---|---|---|
| 不純度減少 | ノード分割時の Gini / 二乗誤差減少を平均 | 高速 (学習時に算出) | 連続値・高基数変数を過大評価 |
| Permutation | 変数値をシャッフルし精度低下を測定 | モデル非依存 | 相関変数群があると過小評価 |
| SHAP | Shapley 値で各サンプルへの貢献を分解 | 個別予測の解釈可能 | 計算コスト高 (TreeSHAP で高速化) |
| Drop-column | 変数を 1 つ抜いて再学習し精度低下を測定 | 厳密 | 変数数だけ再学習が必要 |
| Boruta | シャッフル版 (影変数) と統計的に比較 | 厳格な選択 | 計算コスト高 |
特に SHAP と permutation の組み合わせは、 「全体的に効いている変数」と「個別予測に効く変数」の両方を可視化できるため、 本番運用前のレビューで強く推奨される。
「ある変数が目的を説明する」という言明には、 実は深い哲学的問題が含まれている。 19 世紀後半の Galton による回帰の発見以来、 統計学は「相関」と「因果」の境界を巡って議論してきた。 Pearson は相関係数で十分とし、 Fisher は実験計画 (RCT) を絶対視し、 Pearl は因果ダイアグラム (DAG) で観察データからの因果推論を可能にした。 現代の機械学習は予測精度を最優先するが、 ビジネス意思決定では「介入したらどうなるか」を問う場面が多く、 そこでは因果が不可欠になる。
説明変数の設計者は、 (a) 予測モデルとして使うか、 (b) 因果推論として使うか、 (c) 記述統計として使うかを最初に決める必要がある。 同じ変数でも、 目的が違えば前処理も解釈も変わる。 例えば「過去の購買履歴」は予測モデルでは強い変数だが、 因果推論では「過去の購買 = 嗜好の代理」となり交絡変数として制御対象になる。
| 工程 | 確認項目 | 失敗時の典型症状 |
|---|---|---|
| データ取得 | 取得時刻と最新性 | 古いデータで予測精度低下 |
| スキーマ管理 | カラム名・型の固定 | 名前変更で全パイプライン破綻 |
| 欠損監視 | 欠損率の急変アラート | センサー故障を見落とす |
| 外れ値検知 | 分位点ベース監視 | 異常値で勾配爆発 |
| 分布シフト検知 | KL ダイバージェンス監視 | 季節要因で精度低下 |
| 標準化統計の固定 | train の mean/std を保存 | test で再計算 → leakage |
| encoding 辞書の固定 | train の水準を保存 | 新カテゴリ出現で予測不能 |
| バージョン管理 | 特徴量定義の git 管理 | 再現性消失 |
| ロギング | 本番予測時の入力ログ | 後で原因究明できない |
| 監査 | 定期的な変数重要度レビュー | 不要変数が残存しコスト増 |
最終的に説明変数は「意思決定者が動かせる」変数かどうかで分類できる。 例えば「気温」「他社価格」「人口」は外生で動かせないが、 「自社価格」「広告費」「在庫量」は動かせる。 動かせる変数だけが介入対象になるため、 ビジネス利用を前提とした分析では、 まず動かせる変数の効果を分離して測ることが重要である。
| 分類 | 例 | 用途 |
|---|---|---|
| 動かせる変数 (decision variable) | 価格、 広告費、 在庫 | 最適化、 施策設計 |
| 動かせない変数 (environmental) | 気温、 競合動向、 人口 | 予測、 シナリオ分析 |
| 遅延変数 (lagging indicator) | 解約率、 売上 (確定後) | 過去評価、 監視 |
| 先行変数 (leading indicator) | サイト訪問数、 検索量 | 早期警報、 予測 |
説明変数は分析の「素材」であり、 同じ目的変数でも素材が違えば料理が変わる。 良い分析者は、 まず手持ちの素材を観察し、 不足を補い、 余計を削ぎ、 仮説と整合する組み合わせを選ぶ。 SSDSE-B-2026 のような信頼できる公的データから始めて、 散布図・相関行列・VIF・残差プロット・交差検証の 5 点セットを毎回回す習慣をつければ、 説明変数設計の力は確実に伸びる。 そしてある程度慣れたら、 Pearl の因果ダイアグラムや Boruta、 SHAP といった高度な道具に手を伸ばして、 「相関」を「因果」へ昇華させる工程に進むのが理想的なロードマップである。
| 用語 | 解説 |
|---|---|
| 説明力 (explanatory power) | 説明変数群が目的変数の分散をどの程度説明できるか。 R² で測定。 |
| 予測力 (predictive power) | 未知データに対する精度。 訓練 R² ではなく交差検証で測定。 |
| 偽の関係 (spurious correlation) | 因果がないのに統計的に相関する関係。 交絡や偶然による。 |
| シンプソンのパラドックス | 群別と全体で相関の符号が逆転する現象。 群分け変数の重要性を示す例。 |
| 分布シフト (covariate shift) | 訓練と本番で説明変数の分布が異なる現象。 精度低下の主因。 |
| 概念ドリフト (concept drift) | x と y の関係そのものが時間で変わる現象。 定期再学習が必要。 |
| サロゲート (surrogate) | 本来欲しい変数の代替となる変数。 夜間光量 → 経済活動など。 |
| マニフォールド学習 | 高次元説明変数を低次元で表現する非線形手法群。 |
| 変数選択の安定性 | サブサンプリングで何度学習しても同じ変数が選ばれる度合い。 |
| 正則化パス | 正則化強度を変えたときの係数推移。 Lasso では多くがゼロに収束。 |
説明変数 (independent / predictor / feature) は 回帰・分類・因果推論の入力側に位置するすべての変数群を指す。 SSDSE-B-2026 では 人口・産業構造・社会指標 など 47 都道府県あたり 100+ 列の数値・カテゴリ変数が説明変数候補となる。
【回帰・分類モデルの 4 部品】
説明変数 X (本ページ)
│
▼
┌────────────┐
│ モデル f │ ─── 重回帰 / ロジスティック回帰 / 決定木
└────────────┘ ランダムフォレスト / Gradient Boosting / NN
│
▼
目的変数 y (応答変数)
│
▼
予測誤差 (損失関数で評価)
【説明変数を扱う 6 工程】
データ取得 ─→ 変数の生成 (人口/面積 など SSDSE-B 直接列)
│
▼
データクリーニング ─→ 欠損・型・外れ値
│
▼
特徴量エンジニアリング ─→ 対数変換・標準化・ダミー化・交互作用
│
▼
変数選択 ─→ 多重共線性チェック (VIF)・Lasso・SHAP
│
▼
モデル学習 ─→ 重回帰 / 木モデル / NN
│
▼
モデル解釈 ─→ 偏回帰係数・部分依存・SHAP・反実仮想
【上位概念ツリー】
変数 (variable)
├─ 量的 (numerical)
│ ├─ 連続 ─ 例: 総人口、 出生数、 年平均気温
│ └─ 離散 ─ 例: 病院数、 大学数
├─ 質的 (categorical)
│ ├─ 名義 ─ 例: 地方区分 (北海道/東北/関東…)
│ └─ 順序 ─ 例: 都市規模ランク
└─ 役割
├─ 説明変数 (X) ★ 本ページ
├─ 目的変数 (y) ─ 例: 出生率、 失業率
├─ 共変量 (confounder) ─ 例: 高齢化率
├─ 操作変数 (IV)
└─ 制御変数 (control)
要点: 説明変数は「役割」であって変数の種類ではない。 同じ「人口」が、 失業率を予測するなら説明変数、 人口を従属変数にしたモデルでは目的変数になる。 役割は解きたい問いで決まる。
説明変数の扱いを段階的に習熟するための学習ロードマップを示す。 各段階で「読むべき内容」と「手を動かすべき課題」をセットで掲げた。
| 段階 | テーマ | 読む | 手を動かす |
|---|---|---|---|
| 入門 1 | 連続変数と単回帰 | 最小二乗法 | SSDSE-B-2026 で人口 → 総生産の単回帰 |
| 入門 2 | カテゴリ変数のダミー化 | 本ページ「encoding 詳細」 | 地域カテゴリを one-hot 化して重回帰 |
| 初級 1 | 多重共線性と VIF | 本ページ「VIF チェック表」 | statsmodels.stats.outliers_influence の VIF 計算 |
| 初級 2 | 標準化と正則化 | 本ページ「ML モデル別前処理表」 | sklearn の Ridge / Lasso で正則化パスを描く |
| 中級 1 | 変数選択 | 本ページ「選択法の体系」 | Boruta もしくは Lasso で変数を絞り込む |
| 中級 2 | 変数重要度 | 本ページ「重要度の指標」 | RF / XGBoost で permutation importance を出す |
| 上級 1 | SHAP による解釈 | Molnar『Interpretable ML』 | shap.TreeExplainer で個別予測解釈 |
| 上級 2 | 因果推論 | Pearl『Causality』 | DoWhy で back-door 制御による因果推定 |
| 上級 3 | 時系列特徴量 | 本ページ「時系列における設計」 | tsfresh で時系列から数百特徴量を自動抽出 |
| 上級 4 | 運用パイプライン | 本ページ「実務パイプライン」 | MLflow で encoding 辞書をバージョン管理 |
最後に、 これまでの議論を 3 つの原則に集約する。 第一原則は「目的との整合」で、 予測か因果か記述かによって説明変数の選び方が変わる。 第二原則は「節約原理 (parsimony)」で、 同じ説明力なら少ない変数で済ませるほうがよい。 第三原則は「再現性」で、 前処理・encoding 辞書・seed・バージョン管理を徹底することで、 半年後の自分や他者が同じ結果を再現できる状態を作る。 この 3 原則を毎回意識すれば、 説明変数設計は確実に再現可能でロバストなものになる。 そして実務では、 これらの原則を守ったうえで、 業務知見・倫理的配慮・運用コストの 3 者をバランスさせることが最終的な価値創出に繋がる。 説明変数を制する者は分析を制すると言っても過言ではない。
本ページの内容を一度通読したら、 SSDSE-B-2026 を使って実際に手を動かし、 散布図・相関行列・VIF・残差プロット・交差検証の 5 点セットを 1 度回してみることを強く推奨する。 理論と実践の往復こそが、 説明変数設計力を伸ばす最短経路である。
SSDSE-B-2026 (47 都道府県年次データ) を題材に、 説明変数設計の練習を 5 題提示する。 各問題は 30 分程度で取り組める粒度に絞った。
データ分析者がどの変数を説明変数に選ぶかは、 単なる技術判断ではなく、 その人の「世界の見方」の表明である。 例えば「学業成績」を説明したいときに、 「学習時間」を入れる人と「家庭環境」を入れる人と「遺伝的素質」を入れる人とでは、 出てくる結論も含意も大きく異なる。 「動かせる変数」だけを選ぶことは、 「動かせる範囲で意思決定したい」というプラグマティックな立場を意味し、 「動かせない変数」も含めることは、 「現実を記述したい」という記述的立場を意味する。
さらに、 機微な変数 (人種、 性別、 出身地) を入れるかどうかは、 倫理的・社会的な判断を伴う。 法律 (個人情報保護法、 GDPR) の遵守は最低限の境界線にすぎず、 その上で「使うべきか」「公平性を担保できるか」「説明責任を果たせるか」を考える必要がある。 こうした判断は AI 倫理の中心テーマであり、 説明変数設計は技術と倫理が交差する重要な接点である。
SSDSE-B-2026 のような匿名化された地域集計データは、 個人を識別しない安全な題材として優れている。 まずは個人情報を含まない公的データで腕を磨き、 倫理的判断を要する場面では領域専門家やデータ保護責任者と協議する姿勢を持つこと。 これが現代のデータサイエンティストに求められる態度である。
| 論点 | 1 行要約 |
|---|---|
| 定義 | 目的変数を説明するために投入する入力変数 |
| 別名 | 独立変数、 予測変数、 特徴量 |
| 主要な役割 | 主効果、 調整、 媒介、 交絡、 道具、 制御 |
| 前処理の柱 | 標準化、 encoding、 欠損補完、 変換 |
| 診断指標 | VIF, 相関、 残差、 重要度、 SHAP |
| 選択手法 | Lasso, Ridge, ステップワイズ, Boruta |
| リーク防止 | train/test 分離、 K-fold encoding、 時系列分割 |
| 因果視点 | back-door, front-door, 道具変数 |
| 運用視点 | 分布シフト監視、 encoding 辞書固定、 ロギング |
| 最重要原則 | 「何を入れないか」も同等に重要 |
合成 3 説明変数で他 2 変数による R² から VIF を計算する。
| 変数 | R² | VIF = 1/(1-R²) |
|---|---|---|
| x1 | 0.20 | 1.25 |
| x2 | 0.80 | 5.00 |
| x3 | 0.95 | 20.00 |
1 2 3 4 5 | import numpy as np r2 = np.array([0.20, 0.80, 0.95]) vif = 1 / (1 - r2) print(f"VIF: {vif}") print(f"問題変数 (VIF>=10): {np.where(vif >= 10)[0]}") |
💬 手計算 (Step 1) と Python 出力が完全一致。
「説明変数」を実際の課題に当てはめるとき、 以下の 3 ステップで判断する。 領域固有の判断基準と組み合わせて使用する。
説明変数の選定は (1) 業務目的が予測か因果か (2) サンプル n と次元 p の比 (3) 解釈性要求 の 3 軸で決まる。 予測重視なら Lasso / RF 重要度 / SHAP、 因果重視なら DAG → back-door 制御変数、 解釈重視なら標準化係数 / VIF 制約。 SSDSE-B-2026 (n=47, p=数十) では n/p≈1 でハイリスクなため、 Bootstrap でCI 必須。
| 状況 | 第一選択 | 第二選択 | 避ける |
|---|---|---|---|
| n=47 県 × p<10 (SSDSE-B-2026 で予測) | OLS + 標準化、 LOOCV で汎化確認 | Ridge (λ を CV) | Random Forest 単独 (n が少なすぎ) |
| n=47 × p=30+ (高次元) | Lasso / ElasticNet で変数選択 | 主成分回帰 (PCR) | OLS (p>n で解けない) |
| 因果効果を推定したい | DAG 描画 → back-door 集合のみ投入 | 傾向スコアマッチング | 「使えるから入れる」雑食モデル |
| 説明を経営陣に提示 | 標準化偏回帰係数 + 95% CI | SHAP の global importance | 非線形 ML 単独 (解釈不能) |
| 時系列 (年次) | lag 変数 + TimeSeriesSplit | 状態空間モデル | シャッフル CV (リーク) |
「説明変数」は単独で完結せず、 隣接する手法と接続することで分析パイプラインの一部として機能する。 以下に具体的な接続関係を示す。
説明変数は (1) 業務知見で「投入すべき変数の候補」を列挙 → (2) EDA で分布・欠損・外れ値を確認 → (3) 前処理 (標準化 / encoding / 変換) → (4) 相関・VIF で多重共線性チェック → (5) Lasso / 重要度で絞り込み → (6) 残差診断と業務的妥当性検証、 という 6 段プロセスで一巡する。 各段階で意思決定を文書化し、 再現可能なパイプラインに固定する。
このセクションの数値は SSDSE-B-2026.csv(2023 年・47 都道府県)の実測値を Python で最小二乗回帰して得たもの。架空データは使っていない。
説明変数(explanatory variable = 独立変数)とは、データそのものの属性ではなく、あなたが割り当てる「役割」だ。同じ列でも、研究の問いが変われば役割は入れ替わる。たとえば SSDSE-B の「転入者数」は、人口増減を説明する手がかりとして使えば説明変数だが、その転入者数自体を気候や求人数から予測したければ目的変数になる。だから「この列は説明変数か?」という問いは半分ナンセンスで、正しくは「このモデルにおいて説明変数か?」と問う。x は「条件・手がかり・つまみ」の側、y は「その結果として動く」側 —— この向きを決めるのは統計ではなく分析者の因果仮説である。
ひとつの説明変数の回帰係数は、それ単独では意味を持たない。同じモデルに他にどの説明変数が入っているかで、大きさどころか符号(プラス/マイナス)まで変わる。実データで見せる。目的変数を 出生数、説明変数を 65歳以上人口 にして 2023 年 47 都道府県を回帰すると:
| モデル(説明変数の組み合わせ) | 65歳以上人口の係数 | 総人口の係数 | R² |
|---|---|---|---|
| 出生数 ~ 65歳以上人口 のみ | +0.0242 | — | 0.9610 |
| 出生数 ~ 65歳以上人口 + 総人口 | −0.0085 | +0.0082 | 0.9930 |
単回帰では「65歳以上人口が多い県ほど出生数も多い(+0.0242)」と出る。文字どおり読めば「高齢者が多いほど赤ちゃんが増える」——明らかに不合理だ。これは両方とも総人口に引きずられている(規模の交絡)ための見せかけ。実際、65歳以上人口と総人口の相関は r=0.9910、出生数と65歳以上人口の相関も r=0.9803 と、いずれもほぼ一直線。ここに説明変数として総人口を追加すると、65歳以上人口の係数は −0.0085 へ符号が反転する。「人口規模をそろえた(同じ大きさの県どうしで比べた)とき、高齢者の割合が高い県ほど出生数は少ない」という、はるかにまともな向きが現れる。同じデータ・同じ説明変数なのに、相棒の説明変数が変わっただけで結論が正反対になった——これが最大の落とし穴だ。
重回帰の係数は偏回帰係数(partial coefficient)であり、その定義は「他の説明変数をすべて固定したうえで、その変数だけを 1 単位動かしたときの y の変化」。上の反転は、単回帰の「+0.0242」が他を固定していないのに対し、重回帰の「−0.0085」が総人口を固定した数値だから起きる。つまり係数は数値ではなく「どの条件のもとでの効果か」という文脈込みで初めて意味を持つ。ただし今回のように説明変数どうしが r=0.991 とほぼ重なる(強い多重共線性)と、個々の係数は推定が不安定で、わずかなデータ変化で符号がぐらつく。実務での対処は主に 3 つ:(1) 比・割合に作り替える(例:65歳以上人口そのものでなく「高齢化率=65歳以上/総人口」を説明変数にすれば規模の交絡を最初から断てる)、(2) 交絡候補を意図的に統制変数として投入する、(3) 係数を 1 本ずつ解釈せず説明変数の集合として報告する。「係数の符号だけ見て因果を語らない」——これが説明変数を扱う実務の第一原則である。
▼ 上表の再現コード(そのまま実行すれば同じ値が出る)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import pandas as pd, numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) d = df[df['SSDSE-B-2026'] == 2023] # 2023年・47都道府県 y = d['A4101'].to_numpy(float) # 出生数(目的変数) x1 = d['A1303'].to_numpy(float) # 65歳以上人口 x2 = d['A1101'].to_numpy(float) # 総人口 one = np.ones(len(d)) # 単回帰:説明変数は 65歳以上人口 だけ b_single = np.linalg.lstsq(np.column_stack([one, x1]), y, rcond=None)[0] # 重回帰:総人口を説明変数に追加 b_multi = np.linalg.lstsq(np.column_stack([one, x1, x2]), y, rcond=None)[0] print(round(b_single[1], 4)) # +0.0242 ← 65歳以上の係数(単回帰) print(round(b_multi[1], 4)) # -0.0085 ← 総人口を足すと符号反転 print(round(b_multi[2], 4)) # +0.0082 ← 追加した総人口の係数 |