論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
情報利得
Information Gain
ML基礎

🔖 キーワード索引

情報利得 IG 決定木 ID3 C4.5 エントロピー減少 分割基準 ジニ不純度 ゲイン比 属性選択 純度向上 ノード分割 split feature importance

💡 30秒で分かる結論

🍰 まずはやさしく

データの整理具合を測る物差しです。

効率よくデータを分けるために使います。

部活のメンバーを特徴で分ける時に便利です。

数式やコード、注意点を学びます。

情報利得(Information Gain):ある分割によりエントロピーが減った量。 決定木の分割選択基準

📍 あなたが今見ているもの

🍰 まずはやさしく

情報利得という言葉の解説ページです。

機械学習の基礎を身につけるために使います。

都道府県のデータを使って練習します。

直感的な意味からPythonでの書き方まで読みます。

このページは「情報利得(Information Gain)」の用語解説です。 機械学習の基礎カテゴリにおける重要概念で、 機械学習の基礎 グループ教材の中で繰り返し登場します。 数式・実コード・落とし穴を 1 ページに集約し、 SSDSE-B-2026 都道府県データ(47 件 × 112 列)を題材に 手を動かしながら理解できるよう構成しています。

別称:情報ゲイン。 まず 💡 30秒結論 で全体像を、 次に 🎨 直感📐 数式🧮 実値🐍 Python の順で読むのがおすすめ。

🎨 直感で掴む

🍰 まずはやさしく

良い質問でデータが整理された量のことです。

どの質問が一番効くかを判断するために使います。

スマホの機種で人を分けるようなイメージです。

なぜこの考え方が必要なのかを詳しく読みます。

情報利得は「ある質問(分割)でデータがどれだけ整理されたか」を数値化したものです。 質問前のエントロピー $H(\mathrm{親})$ から、 質問後の子ノード達のエントロピーの加重平均を引いた値。 大きいほど「効く質問」です。

決定木の ID3 / C4.5 は、 全候補変数の中から情報利得が最大の変数で分割を繰り返します。 例:47 都道府県を「人口 100 万人未満/以上」で割ると、 若年人口比率の純度がどれくらい上がるか、 を情報利得で測ります。

🎨 直感の深掘り — もう一段の理解

情報利得を 30 秒で言えば「分岐前後でエントロピーがどれだけ減ったか。 大きいほど「この質問は良い分岐だ」と判定できる。」ですが、 実務で迷わないためにはもう一段深い理解が必要です。 ここでは「何が分かれば自信を持って使えるか」を、 3 つの観点で整理します。

観点問い答え方の指針
定義の根拠なぜこの式・この定義になったのか?「何を最小化/最大化したいか」から逆算する
境界条件いつ使える/使えないのか?「データの形」「分布の前提」を確認する
他との関係隣接概念とは何が違うのか?「共通点」と「分かれ目」を 1 つずつ挙げる

💡 暗黙の前提:情報利得 が「うまく機能する」には、 データに対する暗黙の仮定(独立同分布、 適切な前処理、 十分なサンプル数)があります。 これを言語化できるかどうかで、 失敗時のデバッグ力が大きく変わります。

📐 数式または定義

🍰 まずはやさしく

整理された量を計算する式のことです。

正確な数値で分かれ目を決めるために使います。

買い物リストを種類別に分ける計算に似ています。

記号の意味や式の読み方を順番に読みます。

情報利得 IG は親ノードのエントロピーから、 子ノードの加重平均エントロピーを引いた量として記述されます (KaTeX で描画)。

$$IG(D, A) = H(D) - \sum_{v \in \mathrm{values}(A)} \frac{|D_v|}{|D|} H(D_v)$$

英語名 Information Gain。 別称:情報ゲイン。

📐 数式を 3 段階で読み直す

数式 $IG(D, A) = H(D) - \sum_{v \in A} \frac{|D_v|}{|D|} H(D_v)$ を「ぼんやり眺める」から「自分の言葉で説明できる」レベルに引き上げます。

$$IG(D, A) = H(D) - \sum_{v \in A} \frac{|D_v|}{|D|} H(D_v)$$

① 形を見る

左辺は何か(スカラー?関数?)、 右辺は和・積・最大化のどれが主役か。 ここで「式の文型」が見えます。

② 各記号に意味を持たせる

記号それぞれに「データ/パラメータ/確率/集合」のラベルを貼り、 「これは固定」「これは動かす」を区別します。

③ 極端なケースで確かめる

サンプルが 1 個、 すべて同じ値、 完全にランダム、 などの極端なケースで式がどう振る舞うか確認すると、 数式が「ただの記号」から「動く道具」になります。

📐 情報利得の式と数式を言葉で読み解く(完全版)

情報利得は決定木の分割基準で、 ある属性 $X$ で分割したときに目的変数 $Y$ の不確実性(エントロピー)がどれだけ減ったかを測ります。 ID3 アルゴリズム(Quinlan 1986)の中核概念です。

$$ H(Y) = -\sum_{k=1}^{K} p_k \log_2 p_k, \quad H(Y \mid X) = \sum_{v} \frac{|D_v|}{|D|} H(Y \mid X=v) $$

$$ IG(X) = H(Y) - H(Y \mid X), \quad \text{GainRatio}(X) = \frac{IG(X)}{H(X)} $$

🔬 数式を言葉で読み解く(記号 → 意味)

記号意味具体例(都道府県の都市/地方分類)
$Y$目的変数(クラスラベル)「都市」「地方」の 2 値
$p_k$クラス $k$ の出現確率「都市」が 47 中 12 県なら $p=12/47$
$H(Y)$$Y$ のエントロピー(不確実性)2 値で均等なら 1.0 bit、 偏ると 0 に近づく
$H(Y \mid X)$$X$ で分割後の条件付きエントロピー「人口 ≥ 200 万」で分けた後の残り不確実性
$IG(X)$情報利得 = エントロピー減少量「この属性で分けるとどれだけスッキリするか」
$H(X)$分割属性自体のエントロピー(split info)多値属性の偏った IG を補正する基準
GainRatio多値属性ペナルティ付き IG(C4.5)都道府県 ID のような高基数属性の過大評価を防ぐ

直感的には「分割前と分割後でラベル分布のばらつきがどれだけ整理されたか」を bit で測る指標。 IG が 0 ならその属性は無情報、 1 に近ければ完全に分離できる属性です。

🔬 数式を言葉で読み解く

記号と意味を逐一突き合わせて読みます。 慣れないうちは式を「日本語で読む」ことが理解の近道です。

🧮 SSDSE-B 実値で計算してみる

SSDSE-B で「都道府県を 若年人口比率 ≥ 中央値 / 未満 の 2 値ラベル」とし、 「高齢化率(65 歳以上人口比率)の中央値で分割」する質問の情報利得を計算します。

データ出典:SSDSE-B-2026(独立行政法人統計センター)。 47 都道府県 × 複数年(最新 2023)の社会統計データ。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 SSDSE-B-2026(年度) A1301(15歳未満人口) A1101(総人口) A1303(65歳以上人口) 北海道 2,023 514,000 5,092,000 1,681,000 東京都 2,023 1,513,000 14,086,000 3,205,000 沖縄県 2,023 236,000 1,468,000 350,000 …(全 47 行)
 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
31
import pandas as pd
import numpy as np

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
df = df[df['年度'] == 2023].reset_index(drop=True)

# 目的変数: 若年人口比率が中央値以上か
df['若年比率'] = df['15歳未満人口'] / df['総人口']
df['若年ラベル'] = (df['若年比率'] >= df['若年比率'].median()).astype(int)
# 分割に使う属性: 高齢化率(65歳以上人口 / 総人口)
df['高齢比率'] = df['65歳以上人口'] / df['総人口']

def entropy(y):
    p = y.value_counts(normalize=True)
    return -np.sum(p * np.log2(p + 1e-12))

# 親ノード
H_parent = entropy(df['若年ラベル'])
print(f'H(親) = {H_parent:.4f}')

# 「高齢化率 ≥ 中央値」で分割
mask = df['高齢比率'] >= df['高齢比率'].median()
left, right = df[mask], df[~mask]
H_left  = entropy(left['若年ラベル'])
H_right = entropy(right['若年ラベル'])
wL = len(left) / len(df)
wR = len(right) / len(df)
H_child = wL * H_left + wR * H_right
IG = H_parent - H_child
print(f'H(左)={H_left:.4f}, H(右)={H_right:.4f}')
print(f'IG = {IG:.4f} bit')

実行結果の要約(出力は環境依存。 概算値):

項目
H(親)0.9997 bit(若年ラベルはほぼ半々)
|左| (高齢化率 ≥ 中央値)24 県
|右| (高齢化率 < 中央値)23 県
H(左)0.9544 bit
H(右)0.9321 bit
IG (この分割)0.0562 bit

💬 結果の読み方:IG ≈ 0.056 bit と小さい。 これは「高齢化率だけでは若年ラベルをあまり分離できない(弱い特徴量)」ことを意味する。 IG は大きいほど良いが、 実データではほとんど効かない分割も普通に起こる、 という好例。 次節では逆に IG が大きく出る分割を見る。

🧮 SSDSE-B-2026 実値: 都道府県の「都市/地方」分類で IG を計算

🎯 このコードでやること:SSDSE-B-2026 の 47 都道府県を、 総人口で「都市(≥200 万人)」「地方(<200 万人)」に二値化。 さらに地域ブロック(北海道/東北/関東/…)属性で分割した場合の情報利得を計算し、 どの属性が分類に有用かを比較する。

📥 入力データ

都道府県 A1101(人口) ブロック 都市/地方 東京都 14,086,000 関東 都市 北海道 5,092,000 北海道 都市 鳥取県 537,000 中国 地方 沖縄県 1,468,000 九州 地方
 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
31
32
import pandas as pd
import numpy as np
from scipy.stats import entropy

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df.rename(columns={'SSDSE-B-2026': '年度', 'Prefecture': '都道府県'})
latest = df[df['年度'] == df['年度'].max()].copy()

# 目的変数: 都市 (人口 200 万人以上) / 地方
latest['ラベル'] = (latest['A1101'] >= 2_000_000).map({True: '都市', False: '地方'})

# 親エントロピー H(Y)
p = latest['ラベル'].value_counts(normalize=True)
H_Y = entropy(p, base=2)
print(f'H(Y) = {H_Y:.4f} bit')

# 属性: 地域ブロック (北海道/東北/関東/その他)
def block(pref):
    if pref in ['北海道']: return '北海道'
    if pref in ['青森県','岩手県','宮城県','秋田県','山形県','福島県']: return '東北'
    if pref in ['茨城県','栃木県','群馬県','埼玉県','千葉県','東京都','神奈川県']: return '関東'
    return 'その他'
latest['BLK'] = latest['都道府県'].map(block)

# 条件付きエントロピー H(Y|X)
H_YX = 0
for blk, sub in latest.groupby('BLK'):
    w = len(sub) / len(latest)
    p_sub = sub['ラベル'].value_counts(normalize=True)
    H_YX += w * entropy(p_sub, base=2)
print(f'H(Y|BLK) = {H_YX:.4f} bit')
print(f'IG(BLK)  = {H_Y - H_YX:.4f} bit')

📤 実行結果

H(Y) = 0.9252 bit H(Y|BLK) = 0.8051 bit IG(BLK) = 0.1201 bit

💬 結果の読み方:地域ブロック属性は約 0.120 bit の情報利得をもたらす(H(Y) の約 13% を削減)。 もし「関東のみ都市、 それ以外地方」なら IG は H(Y) に近づくが、 北海道(人口 500 万で単独ブロックだが都市)や宮城(200 万超で「東北」に都市が 1 県混じる)があるため、 完全分離はできない。 これが「IG が中間値になる属性」の典型例。

🧮 数式に値を入れて手で計算する: 決定木の情報利得

合成データで分割前後のエントロピー差から情報利得を計算する。

Step 1: 親ノード

親: 10 件中 6 正, 4 負 H(親) = -(0.6·log 0.6 + 0.4·log 0.4) ≈ 0.97095 bit

Step 2: 子ノード (X<5 で分割)

左 (5 件): 4 正, 1 負 → H_左 = -(0.8·log 0.8 + 0.2·log 0.2) ≈ 0.72193 右 (5 件): 2 正, 3 負 → H_右 = -(0.4·log 0.4 + 0.6·log 0.6) ≈ 0.97095

Step 3: 情報利得

H(子) = 0.5·0.72193 + 0.5·0.97095 = 0.84644 IG = H(親) - H(子) = 0.97095 - 0.84644 = 0.12451 bit

🐍 Python で再現

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import numpy as np
def H(p):
    p = np.array([p, 1-p])
    p = p[p>0]
    return -(p*np.log2(p)).sum()
parent = H(0.6)
left = H(0.8)
right = H(0.4)
child = 0.5*left + 0.5*right
IG = parent - child
print(f"H(親): {parent:.4f}")
print(f"H(子): {child:.4f}")
print(f"IG: {IG:.4f}")

📤 実行結果

H(親): 0.9710 H(子): 0.8464 IG: 0.1245

💬 手計算 (Step 3) IG=0.124 と Python 出力が完全一致。

🎮 触って理解する

上の手計算を、 スライダーとドラッグで リアルタイムに 体験できます。 親ノードのクラス比率・分割位置・分割の分離度を動かすと、 子ノードのエントロピーと 情報利得 IG = H(親) − Σ 加重 H(子) がその場で再計算されます。 「どんなときに IG が大きく/ゼロになるか」を手で確かめてください。

クラスA(例: 都市型) クラスB(例: 地方型) 💡 親バーの縦線はドラッグ/タッチで動かせます
親ノード(全サンプル) H(親)=-- 左の子 右の子 -- -- H(左)=-- H(右)=--



H(親)
-- bit
加重平均 H(子)
-- bit
情報利得 IG
-- bit
IG の大きさ(親の不確実性に対する割合):

スライダーを動かしてみましょう。

計算式: エントロピー $H(q) = -q\log_2 q - (1-q)\log_2(1-q)$、 情報利得 $IG = H(\text{親}) - \big(w_L H(\text{左}) + w_R H(\text{右})\big)$。 分離度 100% は「その分割位置で最大限クラスを振り分けた」理想ケースです。

🧭 触って気づく 3 つのこと

この体験は 情報エントロピー決定木 の橋渡しです。 決定木は各ノードで全候補分割の IG を計算し、 最大の分割を選んで再帰的に木を育てます。 分類全般の位置づけは 分類、 損失関数としてのエントロピーは 交差エントロピー も参照。 なお「特徴量選択」「相互情報量」の専用ページは本用語集には未作成です。

🐍 Python 実装

scikit-learn / pandas を使った最小実装パターン。 上の SSDSE-B 計算と同じスタイルですが、 ここでは「読み込み→前処理→学習→評価」のテンプレを 4 つのスニペットに分けます。

① データ読み込み & 概観

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 SSDSE-B-2026(年度) 北海道 2,023 東京都 2,023 沖縄県 2,023 …(全 47 行)
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 実値計算 節を参照。

🐍 応用コード — 人口・年齢構成から合計特殊出生率を回帰予測する

SSDSE 公的データを題材に、 情報利得 を実際に動かす最小コードです。 paths は引数に直書きで、 初心者がコピペで動かせる形を優先しています。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 SSDSE-B-2026(年度) A1101(総人口) A1301(15歳未満人口) A1303(65歳以上人口) A4101(出生数) 北海道 2,023 5,092,000 514,000 1,681,000 24,430 東京都 2,023 14,086,000 1,513,000 3,205,000 86,348 沖縄県 2,023 1,468,000 236,000 350,000 12,549 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import pandas as pd
import numpy as np

# データ読み込み(SSDSE-B 都道府県・47 県 × 約 112 列)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
df = df[df['年度'] == 2023].reset_index(drop=True)
print('shape:', df.shape)
print('列の先頭:', df.columns.tolist()[:6])

# 必要な列だけ取り出して整形
features = ['総人口', '15歳未満人口', '65歳以上人口', '出生数']
df_use = df[features].copy()
print(df_use.describe())

次に、 情報利得 に固有の処理を加えます。 ここがページごとの「肝」になる部分。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score

X = df[['総人口', '15歳未満人口', '65歳以上人口']].fillna(0).values
y = df['合計特殊出生率'].fillna(df['合計特殊出生率'].median()).values

X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, random_state=0)
model = RandomForestRegressor(n_estimators=200, max_depth=4, random_state=0).fit(X_tr, y_tr)

pred_tr = model.predict(X_tr)
pred_te = model.predict(X_te)
print(f'train R^2 = {r2_score(y_tr, pred_tr):.3f}')
print(f'test  R^2 = {r2_score(y_te, pred_te):.3f}')
print(f'test RMSE = {np.sqrt(mean_squared_error(y_te, pred_te)):.4f}')

さらに可視化を加えると、 学んだ内容が「眼で」確認できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import matplotlib.pyplot as plt

plt.figure(figsize=(7,5))
plt.scatter(y_te, pred_te, alpha=0.7, edgecolor='k')
lims = [min(y_te.min(), pred_te.min()), max(y_te.max(), pred_te.max())]
plt.plot(lims, lims, 'r--', linewidth=2, label='完全予測ライン')
plt.xlabel('実測 出生率')
plt.ylabel('予測 出生率')
plt.title('情報利得 を使ったモデルの予測精度(SSDSE-B-2026)')
plt.legend()
plt.tight_layout()
plt.savefig('out_information-gain.png', dpi=150)

最後に、 同じ問題を別の角度から見る「クロスバリデーション版」も用意します。

1
2
3
4
5
6
7
8
from sklearn.model_selection import cross_val_score

scores = cross_val_score(
    RandomForestRegressor(n_estimators=200, max_depth=4, random_state=0),
    X, y, cv=5, scoring='r2'
)
print(f'5-fold CV R^2 = {scores.mean():.3f}{scores.std():.3f})')
print('各 fold:', np.round(scores, 3))

🐍 実装パターン集 — 状況別レシピ

同じ「情報利得」を使うにも、 データの形・規模・目的によって書き方が変わります。 4 つの典型パターンを示します。

パターン A:探索的・最小構成

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 SSDSE-B-2026(年度) 北海道 2,023 東京都 2,023 沖縄県 2,023 …(全 47 行)
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.head(3))

パターン B:パイプライン化(前処理+モデル)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import Ridge

pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('model',  Ridge(alpha=1.0)),
])
pipe.fit(X_tr, y_tr)
print('R^2 =', pipe.score(X_te, y_te))

パターン C:交差検証+ハイパーパラメータ探索

1
2
3
4
5
6
from sklearn.model_selection import GridSearchCV

params = {'model__alpha': [0.01, 0.1, 1.0, 10.0, 100.0]}
gs = GridSearchCV(pipe, params, cv=5, scoring='r2', n_jobs=-1)
gs.fit(X, y)
print('best:', gs.best_params_, 'score:', gs.best_score_)

パターン D:可視化付きの結果保存

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import matplotlib.pyplot as plt
import json

pred = gs.predict(X_te)
plt.figure(figsize=(7,5))
plt.scatter(y_te, pred, alpha=0.7, edgecolor='k')
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('result_information-gain.png', dpi=150)

with open('result_information-gain.json', 'w', encoding='utf-8') as f:
    json.dump({'best_params': gs.best_params_,
               'cv_score': gs.best_score_,
               'test_score': gs.score(X_te, y_te)}, f, ensure_ascii=False, indent=2)

🐍 sklearn DecisionTreeClassifier で IG ベース木を学習

🎯 このコードでやること:scikit-learn の DecisionTreeClassifier (criterion='entropy') を用い、 SSDSE-B-2026 の複数列から「都市/地方」を分類する木を学習。 各分割で使われた IG を可視化する。

📥 入力データ:上記で作成した latest テーブルに以下の特徴量を追加:

A1101 (総人口)、 A1301 (15歳未満人口)、 A1303 (65歳以上人口) A4101 (出生数)、 B4101 (年平均気温) ラベル: 都市 (1) / 地方 (0)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import pandas as pd
from sklearn.tree import DecisionTreeClassifier, export_text

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df.rename(columns={'SSDSE-B-2026': '年度', 'Prefecture': '都道府県'})
latest = df[df['年度'] == df['年度'].max()].copy()

feats = ['A1101','A1301','A1303','A4101','B4101']
X = latest[feats].fillna(0)
y = (latest['A1101'] >= 2_000_000).astype(int)

clf = DecisionTreeClassifier(criterion='entropy', max_depth=3, random_state=0)
clf.fit(X, y)
print('特徴量重要度 (IG ベース):')
for f, imp in sorted(zip(feats, clf.feature_importances_), key=lambda x:-x[1]):
    print(f'  {f}: {imp:.3f}')
print()
print(export_text(clf, feature_names=feats))

📤 実行結果

特徴量重要度 (IG ベース): A1303: 1.000 A1101: 0.000 A1301: 0.000 A4101: 0.000 B4101: 0.000 |--- A1303 <= 629000.00 | |--- class: 0 |--- A1303 > 629000.00 | |--- class: 1

💬 結果の読み方:木が最初に選んだのは A1303(65 歳以上人口)で、 これ 1 本で「都市/地方」を完全分離するため重要度が 1.000 に集中し、 A1101 を含む他列は 0.000 になった。 目的変数を A1101(総人口)から作ったのに A1101 自身ではなく A1303 が選ばれたのは、 A1303 が総人口とほぼ完全に相関しているため(人口規模の変数はどれも代理になり得る)。 実務ではリークがないか必ず確認する(目的変数の生成に使った列や、 それと強相関の列を特徴量に入れると IG が極端に高くなる)。

🐍 連続値の閾値選択を IG で探索

🎯 このコードでやること:連続値属性(人口)について、 候補閾値ごとに IG を計算し、 最適閾値を探索。 sklearn が内部で行っている処理を可視化する。

📥 入力データ:47 都道府県の総人口(A1101)と「都市/地方」ラベル。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd
import numpy as np
from scipy.stats import entropy

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df.rename(columns={'SSDSE-B-2026': '年度', 'Prefecture': '都道府県'})
latest = df[df['年度'] == df['年度'].max()].copy()
latest['ラベル'] = (latest['A1101'] >= 2_000_000).astype(int)

H_Y = entropy(latest['ラベル'].value_counts(normalize=True), base=2)
results = []
for th in np.linspace(latest['A1101'].min()+1, latest['A1101'].max()-1, 30):
    left  = latest[latest['A1101'] <= th]
    right = latest[latest['A1101']  > th]
    if len(left)==0 or len(right)==0: continue
    H_L = entropy(left ['ラベル'].value_counts(normalize=True), base=2)
    H_R = entropy(right['ラベル'].value_counts(normalize=True), base=2)
    H_YX = (len(left)*H_L + len(right)*H_R) / len(latest)
    results.append((th, H_Y - H_YX))

best = max(results, key=lambda x: x[1])
print(f'最適閾値 ≈ {best[0]:.0f}, IG = {best[1]:.4f}')

📤 実行結果

最適閾値 ≈ 1938621, IG = 0.9252

💬 結果の読み方:定義 200 万に最も近い 194 万付近で IG が最大化(≒ H(Y)=0.9252)。 連続値の閾値探索は、 sklearn のように「ソート → 隣接サンプル間の中点を全て候補」とする方式が標準。 本コードは粗い間隔(30 点)でも近い結論にたどり着く。

🐍 Random Forest の特徴量重要度を IG で解釈する

🎯 このコードでやること:単木の IG 重要度と Random Forest の Mean Decrease Impurity(MDI)を SSDSE-B-2026 で比較。 複数木による分散安定化の効果を確認する。

📥 入力データ:A1101 を除外した特徴量(A1301 15歳未満人口、 A1303 65歳以上人口、 A4101 出生数、 B4101 年平均気温)。 目的変数: 人口 200 万人以上の都市判定。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df.rename(columns={'SSDSE-B-2026': '年度', 'Prefecture': '都道府県'})
latest = df[df['年度'] == df['年度'].max()].copy()

feats = ['A1301','A1303','A4101','B4101']
X = latest[feats].fillna(0)
y = (latest['A1101'] >= 2_000_000).astype(int)

single = DecisionTreeClassifier(criterion='entropy', max_depth=3, random_state=0).fit(X, y)
forest = RandomForestClassifier(n_estimators=200, criterion='entropy', random_state=0).fit(X, y)

print('単木 IG 重要度:')
for f, imp in sorted(zip(feats, single.feature_importances_), key=lambda x:-x[1]):
    print(f'  {f}: {imp:.3f}')
print()
print('Random Forest MDI 重要度:')
for f, imp in sorted(zip(feats, forest.feature_importances_), key=lambda x:-x[1]):
    print(f'  {f}: {imp:.3f}')

📤 実行結果

単木 IG 重要度: A1303: 1.000 A1301: 0.000 A4101: 0.000 B4101: 0.000 Random Forest MDI 重要度: A1303: 0.506 A1301: 0.322 A4101: 0.157 B4101: 0.015

💬 結果の読み方:単木は A1303(65歳以上人口)だけに重要度が集中する(1.000)が、 Random Forest では 4 つすべてに分散する。 これは「ブートストラップ + 特徴量ランダム選択」により多様な木が生まれた結果で、 単一の IG だけに依存するより安定した特徴量解釈が得られる証拠。

🖼 情報利得を視覚で理解する — 4 つの図表で完全攻略

情報利得(Information Gain, IG)は「分割前のエントロピー − 分割後のエントロピー(重み付き平均)」で定義される指標である。 数式だけでは「なぜ大きい IG = 良い特徴量」と言えるのか、 そして「どの程度の差が実務上意味があるのか」を体で掴むのは難しい。 本章では SSDSE-B-2026 都道府県データから 4 種類の図表を生成し、 IG の挙動を可視化する。 すべての図は実在の公的データ(e-Stat 都道府県の指標 2026 年版から抽出された統計データ研究所版)から生成しており、 合成・乱数は一切含まれない。

図表 1: 散布図で見る「分割の鋭さ」と IG の対応

下図は SSDSE-B-2026 の出生数 (A4101) と人口 (A1101) の散布図である。 ここでは「出生数が県平均より上か下か」を 2 値ラベル(クラス 0 = 平均未満、 クラス 1 = 平均以上)として与え、 「人口」を特徴量として閾値で分割した場合の IG を考える。 散布図の見え方と IG 値の関係を直感で結びつけよう。

人口×出生数の散布図

図 1: SSDSE-B-2026 都道府県データから生成した散布図。 横軸が人口、 縦軸が出生数。 右上ほどクラス 1 (出生数が平均以上)、 左下ほどクラス 0 になる傾向が読み取れる。

この散布図から重要な観察ができる。 横軸(人口)の値で縦方向に切ると、 たとえば「人口 200 万人」あたりで縦線を引けば、 左側は大半がクラス 0、 右側は大半がクラス 1 になる。 これが「IG が大きい分割」の正体である。 逆に「人口 50 万人」のような端っこで切っても、 左側のサンプル数が少なすぎて分割後エントロピーがほとんど下がらない。 つまり 「閾値の選び方」が IG を決めるのだ。

決定木アルゴリズムは、 この散布図に対してすべての候補閾値を試し、 IG が最大になる位置に縦線を引く。 sklearn の DecisionTreeClassifier(criterion='entropy') はこれを内部で自動的に行い、 結果として「人口 188 万人で分割」のような最適閾値を吐き出す。 散布図を眺めれば、 なぜそこに線が引かれるのか(右側と左側でクラス比率が最も鋭く変わる場所)が一目で分かる。

図表 2: ヒストグラムで見るクラス別分布の重なり

IG を直感的に理解するもう一つの方法は、 クラスごとの特徴量分布を重ねたヒストグラムを見ることである。 2 つのクラスの分布がきれいに分離していれば IG は大きく、 重なりが激しければ IG は小さい。 下図は SSDSE-B-2026 都道府県データの分布である。

特徴量のヒストグラム

図 2: SSDSE-B-2026 都道府県データから生成した特徴量のヒストグラム。 分布の形状(右に裾の長い対数正規分布的)が、 都道府県データ特有の歪みを示している。

ヒストグラムから読み取れる重要な点は 3 つある。 第一に、 分布が左右対称ではない(東京・大阪・愛知のような大都市圏が右側に長い裾を作る)。 第二に、 大部分の県が低い値に固まっており、 中央値での分割と平均値での分割では IG が大きく異なる。 第三に、 「分布の重なり具合」が IG の上限を決める。 完全に分離した 2 クラスでは IG = エントロピーの最大値(2 値なら 1.0)になるが、 完全に重なれば IG = 0 になる。

実務的には、 ヒストグラムを描いたあとで「分布の山の位置がクラス間でずれているか?」を目視チェックする。 もし山の位置がほぼ同じなら、 その特徴量を使った分割では IG はほぼゼロ、 つまり分類に役立たない特徴量と判定できる。 これは決定木が自動で行う計算を、 人間の目で先取りする手法でもある。

図表 3: 箱ひげ図で見る「分割後の不純度低下」

3 つ目の視点は箱ひげ図である。 IG は「親ノードのエントロピー − 子ノードのエントロピーの重み付き平均」で計算される。 親ノードを「全体」、 子ノードを「分割後の左右」と考えれば、 箱ひげ図の中央値と四分位範囲が子ノードでどう縮むかが IG の本質を表す。 下図は SSDSE-B-2026 のグループ別分布である。

グループ別箱ひげ図

図 3: SSDSE-B-2026 都道府県データのグループ別箱ひげ図。 グループ間で中央値が大きく異なれば IG が大きく、 重なっていれば IG が小さい。

箱ひげ図のポイントは 3 つ。 第一に、 箱の重なり具合 = エントロピーの残存量。 グループ間で箱がほぼ重ならなければ、 そのグループ分けはクラスを綺麗に分離している、 つまり IG が大きい。 第二に、 外れ値の位置。 都道府県データでは東京が外れ値になりやすく、 これが IG 計算を歪めることがある。 第三に、 箱の長さ(IQR)の差。 一方のグループの箱が小さく、 他方が大きい場合、 サブグループ内のエントロピーに偏りが出る。

箱ひげ図を IG の文脈で読むコツは「親ノード = 全体の箱、 子ノード = 分割後の左右の箱」と読み替えること。 もし分割後に両側の箱が小さく縮めば不純度が下がった証拠で、 IG は大きい。 逆に分割後も箱がほとんど元のままなら IG はゼロに近い。 視覚化と数値の両輪で理解することで、 「なぜこの特徴量が選ばれたか」を後から説明できるようになる。

図表 4: 相関ヒートマップで見る特徴量間の冗長性

IG は単独の特徴量について計算されるため、 相関の高い特徴量がいくつもあると、 そのどれかが「代表」として高い IG を獲得し、 他は影に隠れる。 これが「IG だけを見て特徴量重要度を判断するのは危険」と言われる理由である。 下図は SSDSE-B-2026 から 4 変数を取り出した相関ヒートマップである。

相関ヒートマップ

図 4: SSDSE-B-2026 都道府県データの相関ヒートマップ。 赤いセル(r ≥ 0.8)は高相関、 つまり「どちらか一方を使えば十分」と判断できる組み合わせを示す。

相関ヒートマップを読むときは、 まず赤いセル(r ≥ 0.8)の塊を探す。 都道府県データでは「総人口」と「65歳以上人口」「出生数」などが軒並み r ≥ 0.98 になる。 これらは情報的にはほぼ同じものなので、 決定木では最初に IG が最大になった一つだけが選ばれ、 残りは「分割しても追加の IG はゼロ」となって無視される。 これが「Random Forest が必要な理由」でもある(ブートストラップで特徴量をランダム選択することで、 隠れた高相関特徴量にもチャンスが回る)。

3 つの視点を統合した結論

視点図表IG が大きい時の見え方IG が小さい時の見え方
分割の鋭さ散布図 (図 1)縦線で左右にクラスがきれいに分かれるどこに線を引いても両側に両クラスが混在
クラス分離ヒストグラム (図 2)クラス別の山がはっきり分かれるクラス別の山がほぼ重なる
不純度低下箱ひげ図 (図 3)分割後の箱が小さく縮む分割後も箱がほぼ元のまま
冗長性相関 (図 4)他特徴量と独立した情報を持つ高相関の特徴量があり、 影に隠れる

📝 演習問題(理解度チェック)

問 1. SSDSE-B-2026 都道府県データで「出生数が全国平均以上かどうか」を 2 値ラベルとし、 「人口」を特徴量として閾値分割する場合、 散布図(図 1)から判断すると最適閾値はおおよそ何万人付近に現れると予想されるか。 また、 その閾値で分割した場合の IG が大きくなる理由を、 「分割前エントロピー」と「分割後エントロピーの重み付き平均」の差という観点から 3 行以内で説明せよ。

解答例を見る

散布図から判断すると、 人口 150-200 万人付近に閾値が立つと予想される。 この閾値より上はほぼ全県が「出生数平均以上」、 下はほぼ全県が「平均未満」となり(出生数は人口とほぼ比例)、 子ノードのクラス純度が極端に高くなる。 結果として親ノードの H(S)≈1.0 に対し子ノードの重み付き平均が 0.3 程度まで下がり、 IG ≈ 0.7 という大きな値が得られる。

問 2. 図 4 の相関ヒートマップで、 総人口と65歳以上人口の相関係数が 0.99 と非常に高かったとする。 このとき、 決定木の最初の分割で「人口」が選ばれた場合、 「65歳以上人口」の IG はその後どうなるか。 また Random Forest を使うと何が変わるか、 「ブートストラップサンプリング」「特徴量ランダム選択」の 2 つのキーワードを使って説明せよ。

解答例を見る

人口で最初に分割されると、 65歳以上人口による追加分割の IG はほぼゼロになる(同じ情報を持つため、 既に不純度が下がりきっている)。 Random Forest では各木が異なるブートストラップサンプル上で訓練され、 さらに各分割で特徴量がランダム選択されるため、 「総人口が候補から外れた木」では65歳以上人口が高い IG を獲得できる。 結果として両特徴量に重要度が分散し、 安定した解釈が得られる。

問 3. 図 3 の箱ひげ図で、 グループ間の中央値が大きく異なるが IQR(四分位範囲)もどちらも非常に広い場合、 その特徴量の IG は大きい・小さいのどちらと予想されるか。 また、 もし箱の重なりが激しい場合は、 「ジニ不純度」と「エントロピー」で IG の評価結果は同じになるか異なるかを、 両者の関数形(凹関数の曲がり具合)に触れて答えよ。

解答例を見る

中央値の差があっても IQR が広く重なれば、 分割後の子ノードに両クラスが混じり込み、 IG は中程度(または小さめ)となる。 ジニとエントロピーは両方とも凹関数だが、 エントロピーの方が両端でより急峻に変化するため、 「ほぼ純粋」と「ほぼ完全混合」を識別する感度はエントロピーの方が高い。 実務的にはどちらでも結論はほぼ一致するが、 微小な不純度差が問題になる場面ではエントロピー(IG)を選ぶのが慣例である。

これら 3 問に答えられれば、 IG の数値が「何を意味し」「いつ大きくなり」「いつ信用してはいけないか」を実務レベルで判断できる。 図表と数値の往復こそが、 決定木アルゴリズムをブラックボックスから透明な道具へ変える鍵である。

補論 A: IG とジニ不純度・分散減少の比較

情報利得(IG)は決定木の分割基準のひとつだが、 他にもジニ不純度(Gini Impurity)、 分散減少(Variance Reduction)、 カイ二乗統計量など、 用途に応じて使い分けられる指標がいくつもある。 SSDSE-B-2026 都道府県データを使った具体例で、 これらの違いを整理しよう。

ジニ不純度は「ランダムに選んだ 2 サンプルが異なるクラスに属する確率」と定義される。 数式は $\text{Gini}(S) = 1 - \sum_i p_i^2$ で、 エントロピー $H(S) = -\sum_i p_i \log_2 p_i$ と非常に似た形をしている。 2 クラス問題でクラス確率を $p$ とすると、 Gini = $2p(1-p)$、 Entropy = $-p\log_2 p - (1-p)\log_2(1-p)$ となり、 両者は $p=0.5$ で最大、 $p=0$ または $p=1$ で最小(=0)になる。 グラフを描けば形状は酷似しており、 実務的にはほぼ同じ分割結果を返す。

違いは「計算コスト」と「両端での感度」にある。 ジニ不純度は対数計算を含まないため計算が速く、 sklearn の DecisionTreeClassifier のデフォルトは criterion='gini' である。 一方、 エントロピーは情報理論的に解釈しやすく、 「ビット数で測った不確かさ」という意味付けがある。 IG は厳密にはエントロピー基準だが、 「ジニ基準で計算した差」を「ジニ IG」と呼ぶこともある。 どちらを使うかは慣例の問題で、 結果の精度に大差は出ない。

分散減少は回帰木で使われる指標で、 「分割前の分散 − 分割後の重み付き分散」で定義される。 IG が分類タスク用なら、 分散減少は回帰タスク用、 と覚えればよい。 SSDSE-B-2026 で「出生数」を連続値として予測する回帰木を作る場合、 分散減少が分割基準となり、 IG と同じく「分割後の不純度(ここでは分散)が最も下がる特徴量・閾値」が選ばれる。 sklearn では DecisionTreeRegressor(criterion='squared_error') がこれに対応する。

カイ二乗統計量は古典的な CHAID 系決定木で使われる指標で、 「観測度数と期待度数の差」を測る。 IG と異なり、 統計的有意性のテストと結びついており、 p 値で分割の妥当性を判定できる。 ただし計算がやや複雑で、 現代の機械学習ライブラリでは IG とジニが主流である。

指標タスク数式の核特徴sklearn 引数
エントロピー (IG)分類$-\sum p_i \log_2 p_i$情報理論的解釈、 両端で感度高criterion='entropy'
ジニ不純度分類$1 - \sum p_i^2$計算が高速、 sklearn デフォルトcriterion='gini'
分散減少回帰$\sigma^2_\text{前} - \bar{\sigma}^2_\text{後}$連続値予測に対応criterion='squared_error'
カイ二乗分類$\sum (O-E)^2/E$統計的有意性で判定非標準(CHAID)

補論 B: 連続値特徴量における閾値探索の実態

SSDSE-B-2026 の「人口」のような連続値特徴量に対して、 決定木はどのように閾値を探すのか。 教科書では「すべての候補値を試す」と書かれているが、 実装上は次の手順を踏む。 まずサンプルを特徴量の値でソートする。 次に隣り合うサンプル間の中点(midpoint)を候補閾値とする(47 都道府県なら最大 46 個の候補)。 そして各候補について IG を計算し、 最大の IG を与える閾値を選ぶ。

この「中点を試す」方式の重要性は、 同じ値を持つサンプル間で分割しないことを保証する点にある。 たとえば人口 100 万人の県が 3 つあった場合、 それらの間で切ると左右にサンプルが分散して計算がおかしくなる。 中点を使えば、 自動的に「等しい値はまとめて片側に」配置される。 これが sklearn を含む現代の実装が採用している方式である。

計算量は $O(n \log n)$(ソート)+ $O(n)$(IG 計算)= $O(n \log n)$ となる。 サンプル数が増えても閾値探索は高速で、 47 都道府県なら一瞬で終わる。 大規模データ(数百万サンプル)でも実用的な速度が保たれるのは、 この効率的な実装のおかげである。 ただし特徴量数が増えると線形に時間が伸びる(各特徴量について同じ処理を行うため)ので、 高次元データでは 特徴量サブサンプリング(Random Forest の手法)が有効になる。

補論 C: カテゴリ変数の扱いと多値分割

SSDSE-B-2026 都道府県データは数値中心だが、 もし「地方区分(北海道・東北・関東・…)」のようなカテゴリ変数を扱う場合、 IG はどう計算されるのか。 アプローチは 2 種類ある。 多値分割(multi-way split)はカテゴリの数だけ子ノードを作る方式で、 ID3 や C4.5 など古典的な決定木で使われる。 たとえば「地方区分」を 8 カテゴリとすれば、 一発で 8 つの子ノードに分かれる。

一方、 二分木分割(binary split)はカテゴリを 2 グループに分ける方式で、 sklearn を含む CART 系アルゴリズムで採用されている。 「関東・関西 vs その他」のような分け方を試し、 IG が最大になる組み合わせを選ぶ。 候補は $2^{k-1} - 1$ 通り($k$ はカテゴリ数)あり、 カテゴリが多いと計算が重くなるため、 実装上は One-Hot Encoding で数値特徴に変換するのが一般的である。

多値分割の弱点は「カテゴリ数が多い変数の IG が過大評価される」こと。 たとえば「都道府県名」を 47 カテゴリのまま使うと、 47 個の子ノードが極小サンプルで純粋になり、 見かけ上 IG が非常に大きくなる。 これは過学習の典型パターンで、 C4.5 では「ゲイン比」(IG をカテゴリ数の対数で割った値)でこの偏りを補正する。 二分木分割では構造的にこの問題が起きにくく、 これも CART が主流になった理由のひとつである。

補論 D: 時系列データへの応用

SSDSE-B-2026 のような年次データを時系列として扱う場合、 IG はどのように活用できるか。 下図は時系列データの典型的な可視化である。

時系列データの例

図 5: 時系列データの例。 IG を直接適用するのではなく、 「上昇トレンドか下降トレンドか」のラベルを作り、 過去の値や移動平均を特徴量として分類木に投入するのが定石。

時系列予測に決定木を適用する場合、 通常は ラグ特徴量(過去 $k$ 期前の値)や 移動平均を作成し、 それらを通常の特徴量として IG で評価する。 たとえば「来年の人口が増えるか減るか」を予測する場合、 「今年の人口」「3 年前の人口」「過去 5 年の平均増加率」などを特徴量とし、 IG が最も大きい特徴量で分割していく。

時系列特有の注意点は 時間漏れ(temporal leakage)である。 訓練データとテストデータをランダムに分割すると、 「未来のサンプルが訓練データに混ざる」という不正な状況が生じる。 これを防ぐには、 必ず時間順に分割し(例: 2020 年まで訓練、 2021 年以降テスト)、 IG の計算も訓練データのみで行う必要がある。 この原則を守らないと、 IG は見かけ上大きく出るが、 実運用での精度は壊滅的に低くなる。

補論 E: IG の落とし穴 5 連発

実務で IG を使う際の典型的な落とし穴を 5 つまとめる。 これらを意識すれば、 「IG が大きいから良い特徴量」という安易な解釈を避けられる。

  1. カテゴリ数が多い変数の過大評価: 「ID 番号」のような全サンプルでユニークな変数は、 IG がほぼ最大値になるが汎化性能はゼロ。 必ず ID 列は除外する。
  2. 高相関特徴量の隠れ: 相関が高い 2 つの特徴量があると、 一方の IG だけが大きく、 もう一方はゼロになる。 重要度判断には Random Forest の MDI や Permutation Importance を併用する。
  3. クラス不均衡の影響: クラス比が 99:1 の極端な不均衡データでは、 「全部クラス 0 と予測する分割」の IG がそこそこ大きく見える。 これは class_weight='balanced' で補正する。
  4. サンプルサイズ依存: IG は絶対値で評価されるため、 サンプル数が多いノードと少ないノードで単純比較できない。 ノードサイズで重み付けされた IG(加重 IG)を使う。
  5. 非線形関係の見落とし: IG は単一の閾値による分割を前提とするため、 U 字型のような非線形関係を 1 段の分割では捉えられない。 木を深くするか、 特徴量変換(対数・二乗)を併用する。

補論 F: 実務でのワークフロー

SSDSE-B-2026 のような都道府県データで決定木を構築する際の標準ワークフローを示す。 IG を中心に据えながらも、 単独の指標に頼らない設計が重要である。

  1. 探索的データ分析(EDA): 散布図・ヒストグラム・箱ひげ図・相関ヒートマップで特徴量を可視化(本章の図 1-4 がこれに相当)。
  2. 特徴量エンジニアリング: 比率・対数変換・ラグ特徴量を作成。 SSDSE データなら「人口あたり総生産」「総人口比」などを派生させる。
  3. 初期モデル構築: DecisionTreeClassifier(max_depth=3) など浅い木で IG ベースの分割を確認。 木構造を可視化(plot_tree)して納得感を得る。
  4. 重要度の多角的評価: 単木 IG、 Random Forest MDI、 Permutation Importance の 3 種類を比較し、 共通して上位に来る特徴量を信頼する。
  5. クロスバリデーション: 木の深さや最小サンプル数をチューニングし、 過学習を防ぐ。
  6. 解釈と報告: 「なぜこの特徴量が IG で選ばれたか」をビジネス文脈で説明できるよう、 図表と数値の両方を準備する。

このワークフローを通じて、 IG は単なる「数値計算の結果」から「実務で信頼できる判断材料」へと昇格する。 重要なのは「IG の値そのもの」ではなく、 「IG が大きい理由を可視化と数値の両面から説明できるか」である。

補論 G: SSDSE-B-2026 都道府県データを用いた IG 計算の具体ステップ

ここでは SSDSE-B-2026 都道府県データ(2023 年)を使い、 IG を手計算で追跡してみる。 用いる変数は「人口 (A1101)」「出生数 (A4101)」「65 歳以上人口 (A1303)」で、 目的変数は「総人口が 200 万人以上 = 都市(クラス 1)、 未満 = 地方(クラス 0)」の 2 値ラベルである。 全 47 都道府県のうち都市(クラス 1)は 16 県、 地方(クラス 0)は 31 県という構成になる(実データの分布)。

まず親ノード(全 47 県)のエントロピーを計算する。 クラス 1 の確率は $p_1 = 16/47 \approx 0.340$、 クラス 0 の確率は $p_0 = 31/47 \approx 0.660$。 エントロピーは $H(S) = -0.340 \log_2(0.340) - 0.660 \log_2(0.660) \approx 0.925$ となる。 これが「分割前の不確かさの総量」である。 2 値分類の最大エントロピーは 1.0(完全な五分五分)なので、 0.925 は「かなり大きな不確かさ」を意味する。

次に「出生数」を特徴量として閾値およそ 10,700 人(年間出生数)で分割する場合を考える。 閾値未満には 28 県(すべて地方、 クラス 1 は 0 県)、 閾値以上には 19 県(うち都市 16 県、 地方 3 県)が分類される。 左子ノードは完全純粋なので $H(S_L) = 0$、 右子ノードのエントロピーは $H(S_R) = -(16/19)\log_2(16/19) - (3/19)\log_2(3/19) \approx 0.629$ となる。 重み付き平均は $(28/47) \times 0 + (19/47) \times 0.629 \approx 0.254$。 したがって IG = $0.925 - 0.254 = 0.671$ という大きな値が得られる。

この計算が示すのは、 「出生数 約 10,700 人」という閾値で分割すれば、 親ノードの不確かさの約 73% (= $0.671/0.925$)を一気に解消できるということ。 これが「IG が大きい = 良い分割」の定量的な意味である。 同じデータで「65 歳以上人口」を閾値分割すると IG は約 0.925(都市/地方を完全分離)となり、 出生数より高い。 ただし出生数・65 歳以上人口はいずれも人口規模と相関 $r \approx 0.98$ と非常に高く、 実質は「都市規模」の別表現である。 Random Forest で評価するとこれら相関の高い特徴量に重要度が分散する。

手計算で IG を追えるようになると、 「決定木が選んだ特徴量と閾値の組み合わせは、 数学的に最適である」という確信が得られる。 同時に、 「最適な数式の結果」が「実務で意味のある結果」と一致するかは別問題であることも見えてくる。 たとえば 188 万人という閾値は、 政令指定都市を持つ府県とそれ以外を分ける線でもあり、 ビジネス文脈で説明可能である。 一方で、 たまたまデータの偏りで得られた閾値は、 新しいサンプルでは通用しないかもしれない。 この「数学的最適性」と「実務的妥当性」の往復こそが、 機械学習エンジニアの本職である。

補論 H: IG をめぐる歴史と発展

情報利得という概念は、 1948 年のクロード・シャノンによる情報理論の提唱に源流を持つ。 シャノンの目的は通信路の符号化効率を測ることだったが、 その後の研究で「情報量 = 不確かさの減少」という解釈が機械学習にも応用された。 1986 年、 Ross Quinlan が ID3(Iterative Dichotomiser 3)アルゴリズムを発表し、 これが IG を分割基準とする最初の本格的な決定木アルゴリズムとなった。

ID3 の弱点は「カテゴリ数が多い特徴量で IG が過大評価される」「連続値を扱えない」「欠損値に弱い」という 3 点だった。 これを克服したのが Quinlan の後継作 C4.5(1993 年)で、 ゲイン比による補正、 連続値の自動閾値化、 欠損値処理を導入した。 C4.5 は長年にわたりベンチマークとして使われ、 その商用版 C5.0 は現在も一部の業界で活躍している。

一方、 1984 年に Breiman らが発表した CART(Classification and Regression Trees)は、 ジニ不純度を分割基準とする二分木モデルで、 回帰タスクにも対応する設計だった。 CART は sklearn を含む現代の主要ライブラリの実装ベースとなっており、 IG(エントロピー)とジニのどちらでも動かせるようになっている。 このため、 「IG = ID3/C4.5 系」「ジニ = CART 系」という対応関係はあるものの、 実装上は両者が混在している。

2001 年、 Breiman が Random Forest を発表し、 「複数の決定木の多数決」によって単木の弱点を克服する手法が確立した。 Random Forest は IG を直接の評価指標として使うが、 各木の各分割でランダムに特徴量サブセットを選ぶことで、 「高 IG 特徴量に偏る単木の弱点」を解消する。 これにより、 IG ベースの単木が抱えていた「不安定性」と「過学習傾向」が大幅に緩和され、 現代の機械学習における最も実用的なアルゴリズムのひとつとなった。

2014 年以降は、 Gradient Boosting(XGBoost, LightGBM, CatBoost)が登場し、 IG をベースとしながらも「直前の木の誤差を補正する」逐次学習を取り入れた。 これらは Kaggle などのデータ分析コンペで圧倒的な成績を残し、 現在のテーブルデータ分析のデファクトスタンダードとなっている。 内部では依然として IG(あるいは類似の不純度指標)が使われており、 シャノンが 1948 年に提唱した情報理論が、 70 年以上経った今も AI 技術の中核を支えている。

補論 I: 教育現場での IG の教え方

情報利得を初学者に教える際の効果的な順序を、 SSDSE-B-2026 都道府県データを題材に整理する。 経験上、 数式から入ると挫折する学生が多いため、 「ゲーム → 散布図 → 数式」の順で導入するのが推奨される。

ステップ 1: 「Yes/No ゲーム」で動機づけ。 「47 都道府県のうち、 私が考えた県を当ててください。 ただし質問は Yes/No のみ」というゲームを行う。 効率の良い質問者は「人口が多い?」「東日本?」のように、 集合を半分に切る質問を選ぶ。 この「半分に切る = 情報を最大化する」が IG の本質であることを体感させる。

ステップ 2: 散布図と縦線。 SSDSE データの散布図を見せ、 「ここに縦線を引いたら左右でどう分かれる?」と問う。 学生は「右下と左上が良い分け方になる位置」を直感的に当てられる。 これが「IG が大きい閾値」であることを後づけで説明する。

ステップ 3: エントロピーの定義。 ここで初めて $H(S) = -\sum p_i \log_2 p_i$ を導入する。 ただし、 まず 2 値の場合に絞り、 $H = -p\log_2 p - (1-p)\log_2(1-p)$ をグラフ化して「$p=0.5$ で最大、 $p=0$ または $p=1$ で 0」という形を見せる。 数式の意味が視覚的に分かれば、 学生は躓かない。

ステップ 4: IG の計算。 親ノードのエントロピーから子ノードの重み付き平均を引く、 という機械的計算に落とし込む。 SSDSE データの具体例で 1-2 回手計算させると、 数式の意味が完全に腑に落ちる。

ステップ 5: Python 実装。 ようやく DecisionTreeClassifier(criterion='entropy') を使って、 自分で計算した結果と sklearn の結果が一致することを確認する。 「自分の手計算」と「ライブラリの計算」が一致する瞬間に、 学生は「機械学習は魔法ではなく数学だ」と納得する。

この 5 ステップを 1 回の授業(90 分)で完結させると、 IG を「数式の暗記」ではなく「概念の理解」として身につけられる。 そして、 後に Random Forest や Gradient Boosting を学ぶ際にも、 「結局は IG の応用だ」という見通しが立つ。 教育において、 ひとつの基礎概念を深く理解することが、 後の発展概念の理解速度を圧倒的に上げる。 IG はその典型例である。

補論 J: 実データで起きやすい IG の挙動パターン 10 選

SSDSE-B-2026 都道府県データのような実データで決定木を回すと、 IG はしばしば「教科書通り」ではない挙動を見せる。 これらは技術的な誤りではなく、 データの性質に起因する自然な現象だが、 初学者は「バグ」と勘違いしやすい。 ここでは典型的な 10 のパターンを整理する。

パターン 1: 同じ IG を持つ複数の閾値が出現。 連続値特徴量で隣り合うサンプル間の値が極めて近い場合、 複数の閾値で IG がほぼ同じ値になる。 sklearn はランダムにひとつを選ぶため、 再現性のために random_state を固定する必要がある。 都道府県データなら、 人口 100 万人前後の県が複数あると、 99 万、 100 万、 101 万のどこで切っても IG がほぼ同じになる、 という現象が起きる。

パターン 2: 高 IG の特徴量がモデルを破壊する。 「県庁所在地ダミー」のようなほぼ一意な特徴量を入れると、 IG が極端に大きくなる。 しかし汎化性能はゼロ。 これは「ID 列を特徴量に含めてしまった」典型例で、 必ず除外する。

パターン 3: IG がゼロでない 2 番目以降の特徴量。 1 番手の特徴量で大半の不確かさが解消されると、 2 番手・3 番手の特徴量は IG が極端に小さくなる。 これは「冗長性」ではなく「順序効果」で、 木の深さを増やせば 2 番手も活躍する。

パターン 4: クラス不均衡時の IG 飽和。 クラス比が 95:5 の場合、 親ノードのエントロピーが既に 0.286 と低く、 IG の最大値もそれ以下。 「IG が 0.05 しかない」と落胆する前に、 親ノードのエントロピーを確認すべし。

パターン 5: 外れ値による閾値の極端化。 SSDSE データの東京のような極端な外れ値があると、 「東京 vs それ以外」という分割が最大 IG を獲得することがある。 これは情報的には正しいが、 ビジネス的には無意味(東京だけ別扱いしても汎化できない)。 外れ値の除外または対数変換で対処する。

パターン 6: 木を深くしても IG がほぼゼロになる。 ある深さを超えると、 ほとんどの葉ノードが純粋になり、 追加の分割では IG ≈ 0 になる。 これは「学習が完了した」サインだが、 過学習の兆候でもあるので、 適切な深さ(通常 5-10)で打ち切る。

パターン 7: 同じ IG だが分割位置が変わる現象。 サンプル順を変えると同じ IG でも別の閾値が選ばれる場合がある。 これは「最良候補が複数ある」ことの帰結で、 random_state 固定が必須。

パターン 8: 訓練データでのみ高 IG、 テストでは低い。 「人口」のような連続値特徴量で、 訓練データの極端な閾値(最小値や最大値付近)を学習してしまうと、 テストデータでは効かない。 クロスバリデーションで確認すれば早期発見できる。

パターン 9: IG ベースの重要度と Permutation Importance が乖離。 単木の IG ベース重要度は「木構造で選ばれた」特徴量を高く評価するが、 Permutation Importance は「予測性能への寄与」を測る。 両者が乖離する場合、 「IG では選ばれたが実は冗長」「IG では選ばれなかったが汎化に貢献」という特徴量を発見できる。

パターン 10: 数値の桁が違う特徴量で IG が偏る。 sklearn の決定木はスケール不変だが、 一部のライブラリでは特徴量のスケーリングが IG 計算に影響することがある。 「人口(万人単位)」と「労働力率(%)」のように桁が大きく違う場合、 念のため正規化してから比較するのが安全。

これら 10 パターンを意識しながら IG を眺めると、 「数値だけを見て一喜一憂する」段階を卒業し、 「データの構造を読む」レベルに到達できる。 機械学習エンジニアの実力は、 こうした「教科書外の現象」をどれだけ多く経験し、 自分の引き出しに整理できているかで決まる。 SSDSE-B-2026 のような小規模公的データは、 実験と観察のサイクルを高速に回せるため、 IG を含む各種指標の挙動を体感的に学ぶ最高の素材である。

補論 K: 関連概念との位置づけ整理

情報利得(IG)の理解を深めるためには、 関連概念との位置関係を把握することが不可欠である。 ここでは IG を中心に据え、 上位概念・並列概念・派生概念を整理する。

上位概念: 情報理論。 IG はクロード・シャノンの情報理論を機械学習に応用したものである。 情報理論には他にも「相互情報量(Mutual Information)」「KL ダイバージェンス」「クロスエントロピー」「条件付きエントロピー」など、 多くの指標があり、 IG はその中でも「分類タスクでの分割基準」という特定の用途に特化したものと位置づけられる。

並列概念: ジニ不純度・分散減少。 同じく「分割の質」を測る指標として、 ジニ不純度(分類用)と分散減少(回帰用)がある。 これらは数式的にも IG と似ており、 実務上はほぼ同等の結果を返す。 sklearn の criterion 引数で切り替えるだけなので、 状況に応じて使い分ければよい。

派生概念: ゲイン比・IG ratio。 C4.5 で導入された「ゲイン比」は、 IG をカテゴリ数の対数で割って正規化した指標で、 多値カテゴリ変数の過大評価を補正する。 数式は $\text{GR} = \text{IG} / \text{SplitInfo}$ で、 SplitInfo は分割の「内在的情報量」を表す。 IG だけでは ID 列のような変数が暴走するが、 ゲイン比なら抑制できる。

応用概念: 特徴量重要度。 訓練済み決定木モデルから「どの特徴量が重要か」を取り出す機能は、 ほぼすべての実装で IG ベースで計算される。 sklearn の feature_importances_ は「その特徴量が貢献した IG の総和」を正規化したもの。 Random Forest や Gradient Boosting でも同じ仕組みで、 ただし複数の木にまたがって平均化される。

代替概念: Permutation Importance・SHAP。 IG ベースの重要度の弱点(高相関特徴量の隠れ、 訓練データへの過適合)を補うため、 近年は Permutation Importance や SHAP(SHapley Additive exPlanations)が併用される。 これらは「予測性能への寄与」を直接測る手法で、 IG とは異なる視点を提供する。 両方を組み合わせることで、 より頑健な特徴量解釈が得られる。

これらの関連概念を体系的に理解すれば、 「IG はどの場面で使い、 どこで限界に達し、 何を組み合わせれば補えるか」が見通せるようになる。 機械学習のエコシステム全体において、 IG は古くからあるが今も中核的な役割を果たす指標であり、 その理解は決して時代遅れではなく、 むしろ最新手法を読み解くための基礎言語である。

補論 L: IG と実務プロジェクトの統合事例

情報利得は教科書の概念にとどまらず、 実プロジェクトでも中核的な役割を果たす。 ここでは SSDSE-B-2026 のような都道府県データを用いたプロジェクト想定で、 IG がどのように意思決定に組み込まれるかを示す。

シナリオ 1: 地域マーケティングの優先順位付け。 全国 47 都道府県のうち、 ある新商品を投入する際に「優先的に攻める県」を絞りたい。 過去の販売データから「ヒットした県(クラス 1)」「ヒットしなかった県(クラス 0)」を 2 値ラベルとし、 SSDSE データの「人口」「世帯数」「労働力率」「商業販売額」などを特徴量として決定木を構築する。 IG が最大の特徴量が「世帯所得中央値」だった場合、 マーケティング部門は「所得帯ベースのターゲティング」に注力すべきという判断が得られる。 IG を見ることで、 「直感(人口が多い県を狙うべき)」と「データの示唆(所得帯の方が効く)」のどちらが正しいかが定量的に分かる。

シナリオ 2: 公共政策の効果測定。 ある政策(例: 子育て支援補助金)を導入した県と導入しなかった県で、 出生率の変化に差があるかを分析する。 「政策あり/なし × 出生率上昇/低下」の 2x2 表を作り、 IG を計算すれば、 「政策の有無が出生率変化を説明する力」が定量化できる。 IG が大きければ「政策は効果あり」、 小さければ「他要因(経済状況、 年齢構成)の方が重要」と判断できる。 政策評価にも IG は応用可能で、 統計的有意性検定と組み合わせることで強力なツールになる。

シナリオ 3: 採用予測モデルの説明。 ある県の自治体職員採用試験で、 過去の合格者・不合格者データから「合格しやすい属性」を分析する。 決定木で IG を計算し、 「年齢」「学歴」「居住地」「面接スコア」のうちどれが合否を最も説明するかを可視化する。 IG ベースの分析は「説明可能 AI」として、 結果を委員会や報道機関に提示する際にも理解されやすい。 「面接スコア > 80 点なら合格率 95%」のようなルールが自動抽出され、 ブラックボックスにならない。

シナリオ 4: 異常検知の判別ルール作成。 工場のセンサーデータから「正常運転」と「異常発生前兆」を判別したい。 IG を使えば、 多数のセンサーの中から「異常を最もよく予兆する 3-5 個」を自動選択でき、 軽量な判別ルールが作れる。 ディープラーニングほどの精度は出ないが、 「なぜ異常と判定したか」が説明できる利点があり、 現場のオペレーターが納得できる。

シナリオ 5: 医療データのリスク層別化。 患者の検査データから「将来発症リスクの高い患者」を抽出する。 IG ベースの決定木は、 医師が直接理解できる「IF-THEN ルール」の形で出力できるため、 医療現場での受け入れが良い。 ロジスティック回帰や深層学習では出せない「視覚的な木構造」が、 医師との対話を促進する。

これら 5 つのシナリオに共通するのは、 IG が「数値の精度」だけでなく「説明可能性」「ルール抽出」「意思決定の支援」という観点で活用される点である。 ディープラーニング全盛の時代でも、 決定木と IG が現役で使われ続ける理由は、 まさにこの「透明性」にある。 SSDSE-B-2026 のような公的データで IG の基礎を身につけることは、 こうした実プロジェクトへの直接的な準備となる。

補論 M: IG をマスターしたあとの次の学習ステップ

情報利得を完全に理解したら、 次に進むべき学習トピックを 7 つ示す。 これらは IG を土台として段階的に発展していくため、 順番に取り組むのが推奨される。

ステップ 1: ジニ不純度の習得。 IG とジニは双子のような関係なので、 IG が分かればジニも自然に理解できる。 sklearn のデフォルトはジニなので、 実務では両方読めるようにしておく。

ステップ 2: 単木決定木のチューニングmax_depthmin_samples_splitmin_samples_leaf などのハイパーパラメータが IG ベースの分割にどう影響するかを実験する。 SSDSE データなら数秒で実行できるので、 試行錯誤しやすい。

ステップ 3: Random Forest の動作原理。 単木の IG が「ブートストラップ + 特徴量サブサンプリング」でどう平均化されるかを理解する。 単木と Random Forest の重要度を比較する実験を行う。

ステップ 4: Gradient Boosting の登場。 XGBoost、 LightGBM、 CatBoost の違いと共通点を学ぶ。 すべて IG(または類似の不純度指標)をベースとしているが、 「逐次学習」「ヒストグラム方式」「カテゴリ変数自動処理」など独自の工夫がある。

ステップ 5: Permutation Importance と SHAP。 IG ベースの重要度の限界を補う手法を学ぶ。 特に SHAP は「ゲーム理論に基づく公平な貢献度分配」という強力な理論基盤を持ち、 説明可能 AI の中核技術となっている。

ステップ 6: 因果推論との接続。 IG は「相関的説明力」を測る指標だが、 これを「因果効果」に発展させるには Causal Forest、 Double Machine Learning などの手法が必要。 公的データを使った政策評価ではこの観点が不可欠。

ステップ 7: 情報理論の全体像。 IG の源流である情報理論を一通り学ぶ。 シャノンエントロピー、 KL ダイバージェンス、 相互情報量、 クロスエントロピー、 条件付きエントロピーまで網羅すれば、 深層学習の損失関数(クロスエントロピー)から VAE(KL ダイバージェンス)まで一気に理解が広がる。

この 7 ステップを順に踏破すれば、 IG という小さな概念を起点として、 機械学習・データサイエンスの主要分野をほぼ網羅できる。 「ひとつの概念を深く掘ると、 関連分野が芋づる式に理解できる」という学習の真髄を、 IG はよく体現している。 学習効率を最大化したい人にとって、 IG を起点に据えるのは賢明な選択である。

まとめ — IG を 1 行で表現すると

情報利得(IG)とは、 ある特徴量で分割したときに減少する「不確かさ」の量である。 数式では $\text{IG} = H(S) - \sum_v \frac{|S_v|}{|S|} H(S_v)$ と書かれるが、 本質は「分割前と分割後の純度の差」に尽きる。 散布図で縦線を引いたときに左右でクラスが鋭く分かれるなら IG は大きく、 ぐちゃぐちゃに混ざるなら IG は小さい。 この直感を持っていれば、 決定木の挙動も Random Forest の重要度も、 ブラックボックスではなく「データの構造を映す鏡」として読めるようになる。

SSDSE-B-2026 都道府県データのような実データで何度も計算と可視化を繰り返すことで、 「この特徴量の IG はだいたいこのくらい」という感覚が身につく。 そうなれば、 新しいデータセットでも「まず IG を眺め、 異常な値があれば疑う」という熟練者のワークフローが自然に実践できるようになる。 教科書の数式から実務の道具へ — その橋渡しが本章の目的である。

🧭 情報利得を特徴量選択で使う時の補強ノート

情報利得は、 ある変数でデータを分けたときに目的変数の不確実性がどれだけ減るかを測る指標です。 決定木では、 分割前のエントロピーから分割後の加重平均エントロピーを引き、 最も不確実性を減らす変数と閾値を選びます。 したがって、 情報利得が大きいとは「その変数を知ると分類の迷いが減る」という意味であり、 必ずしも因果的に重要という意味ではありません。

SSDSE-B-2026 のような都道府県データでは、 地域ブロック、人口規模、産業構成、医療資源、教育指標などを説明変数にし、 例えば「高齢化率が全国中央値を超えるか」を分類対象にできます。 このとき情報利得が高い変数は、 高齢化率の高低をよく分ける変数です。 ただし、 都市規模や地域ブロックに引きずられて高くなることがあるため、 分割結果を地図や表で確認し、 社会的に解釈できるかを点検します。

確認観点見るもの注意点
不確実性の減少分割前後のエントロピー差差が小さい時は分類の根拠として弱い
分割の偏り左右のサンプル数片側に少数しか入らない分割は不安定
解釈可能性選ばれた変数名と閾値社会的説明ができない閾値は発表で弱い
汎化性交差検証での選択安定性折ごとに選ばれる変数が違うなら過信しない

実務では、 情報利得をランキング表として出すだけでなく、 上位変数で実際にどう分割されたかを示します。 「A指標の閾値を超える県では高齢化率が高い県が多い」という文章にできれば、 指標と社会的文脈がつながります。 逆に、 変数名が似た派生指標ばかり上位に並ぶ場合は、 同じ情報を重複して測っている可能性があります。 その場合は相関の高い変数をまとめるか、 代表指標を一つに絞ります。

情報利得はカテゴリ変数や離散化された数値変数と相性がよい一方、 連続値を細かく切りすぎると偶然の分割に過適合します。 コンペでは、 目的変数を作った後に同じ情報を説明変数へ入れてしまうリーケージにも注意します。 例えば「高齢化率が高いか」を予測するのに、 高齢化率から直接計算した指標を使うと、 情報利得は高くても分析としては意味がありません。 特徴量の由来を点検し、 予測時点で利用可能な情報だけを使うことが重要です。

情報利得を発表で使う場合は、 「上位変数がなぜ上位になったのか」を一段掘って説明します。 例えば人口総数が高い情報利得を示したとしても、 それは人口そのものが高齢化率を決めているという意味ではなく、 大都市圏と地方圏の構造差をまとめて表しているだけかもしれません。 この場合、 地域ブロック別のクロス集計、散布図、閾値前後の県名リストを併用し、 分割が社会的に納得できるものかを確認します。 指標値だけを示すより、 分割後の中身を見せる方が説得力は高くなります。

また、 情報利得はサンプル数が少ないデータで特に揺れやすい指標です。 SSDSE-B-2026 の都道府県データは47件しかないため、 1県が左右どちらに入るかでエントロピーの減少量が変わります。 そのため、 単一の分割で得たランキングを確定的な結論として扱わず、 ブートストラップや交差検証で上位変数がどの程度安定して選ばれるかを確認します。 上位5変数が再標本化のたびに大きく入れ替わるなら、 そのランキングは探索的結果として控えめに示すべきです。

連続変数を離散化して情報利得を計算する場合、 ビンの切り方も重要です。 等幅ビン、等頻度ビン、中央値分割、四分位分割では、 同じ変数でも情報利得が変わります。 発表では、 「中央値で二分した」や「四分位でカテゴリ化した」のように、 どのルールで分けたかを明記します。 さらに、 閾値を少し動かしても上位変数が変わらないかを確認すると、 分析が恣意的な切り方に依存していないことを示せます。

情報利得は、 目的変数の定義にも強く依存します。 「高齢化率が中央値を超えるか」と「高齢化率が上位25%に入るか」では、 同じ説明変数でも分割の有効性が変わります。 前者は全国を半分に分けるため安定しやすく、 後者は高齢化が特に進んだ県を見つける問題になるため、 地方部を識別する変数がより強く出る可能性があります。 したがって、 目的変数の作り方を複数試し、 共通して高い変数と特定定義でだけ高い変数を分けて解釈します。

最後に、 情報利得はモデルの入り口として使うのが適切です。 上位変数をそのまま結論にするのではなく、 それらを使って単純な決定木、ロジスティック回帰、ランダムフォレストを比較し、 予測性能と解釈の両方を点検します。 情報利得で候補を絞り、 モデルで妥当性を確認し、 可視化で人間が読める説明に戻すという流れにすると、 数理指標と社会的解釈がずれにくくなります。 これがコンペ発表で情報利得を使う時の実務的な位置づけです。

ランキングを結論に変える時の手順

情報利得ランキングを作った後は、 まず上位変数をそのまま表に貼るのではなく、 似た概念をまとめます。 総人口、15歳未満人口、65歳以上人口、出生数が同時に上位へ来る場合、 それらは「都市規模」を別々の角度から測っている可能性があります。 この時は、 個別列の順位だけでなく、 それらが同じ構造を表すグループであることを示し、 代表変数を一つ選ぶか、 主成分や標準化スコアとしてまとめます。

次に、 上位変数で実際に分割した時の左右の中身を確認します。 例えば「第三次産業比率が高い県」と「低い県」で高齢化率の高低が分かれるなら、 左右それぞれの県名、中央値、四分位範囲、外れ値を見ます。 情報利得が高くても、 片側に数県しか入らない分割や、 1県の極端値に支配された分割は、 発表の中心根拠としては弱くなります。 指標値と実データの顔ぶれを必ず対応させます。

さらに、 情報利得の比較対象を明確にします。 決定木の分割候補として見るのか、 フィルタ型の特徴量選択として見るのか、 説明用の探索指標として見るのかで、 評価の厳しさは変わります。 予測モデルに入れるなら訓練データだけで情報利得を計算し、 テストデータは最後まで見ないようにします。 探索分析として使うなら、 「このランキングは仮説生成であり、 決定的証拠ではない」と位置づけます。

欠損値の扱いも情報利得へ影響します。 欠損を一つのカテゴリとして扱うと、 「欠損であること」自体が目的変数を分ける場合があります。 これは実務上は有益な情報である一方、 調査方法や記録方法の違いを拾っているだけかもしれません。 平均補完、中央値補完、欠損カテゴリ化、欠損行の除外を試し、 上位変数がどの処理でも安定しているかを確認します。 欠損処理に敏感な情報利得は、 慎重に解釈します。

最後に、 発表スライドでは、 情報利得を一つの棒グラフだけで終わらせない構成にします。 1枚目でランキング、 2枚目で上位変数の分割図、 3枚目で交差検証や再標本化による安定性、 4枚目で社会的解釈を示すと、 数理指標から結論までの流れが自然になります。 「なぜこの変数に注目したのか」「その分割は安定か」「社会的にどう読めるか」の三点がつながれば、 情報利得は単なる機械学習用語ではなく、 分析ストーリーを支える証拠になります。

実装面では、 情報利得を計算する前に目的変数と説明変数の作成順を固定します。 目的変数を作った後で、 その目的変数と同じ元列から派生した説明変数を残してしまうと、 情報利得は高くなりますが、 実質的には答えを入力している状態になります。 例えば「高齢化率が高いか」を目的変数にしながら、 高齢化率そのもの、 高齢者人口比率から直接作ったカテゴリ、 目的変数と同じ閾値で作ったフラグを説明変数に入れるのは避けます。

評価時には、 情報利得の絶対値よりも差の意味を考えます。 1位と2位の差がごく小さいなら、 その順位に大きな意味を持たせるべきではありません。 逆に、 上位数個だけが明確に高く、 その後がなだらかに低下するなら、 データには目的変数を分ける主要軸が存在する可能性があります。 棒グラフでは順位だけでなく値の間隔も見せ、 「上位グループ」と「参考程度の変数」を分けて説明します。

情報利得を他の指標と比較することも有効です。 Gini重要度、相互情報量、ロジスティック回帰の係数、ランダムフォレストのPermutation importanceは、 それぞれ違う観点から変数の有用性を見ます。 複数指標で同じ変数が上位に出るなら解釈は安定しやすく、 指標ごとに上位が大きく変わるなら、 データ構造やモデル仮定に依存している可能性があります。 発表では、 一つの指標に依存しすぎない姿勢が信頼性につながります。

小さなデータでは、 情報利得が高い変数ほど外れ値を拾っている可能性もあります。 分割の片側に東京都や沖縄県のような特徴的な観測が入り、 それだけで純度が大きく改善する場合があります。 これは必ずしも悪いことではありませんが、 「一般的な傾向」なのか「特定県の影響」なのかを分けて示す必要があります。 Leave-one-outで情報利得を再計算し、 特定の観測を外すと順位が崩れるかを確認すると、 分析の安定性を評価できます。

報告文では、 「情報利得が高い」だけでなく、 「何の不確実性が減ったのか」を明記します。 分類対象が高齢化率なら高齢化率の高低の不確実性、 雇用指標なら雇用状態の分類不確実性、 地域類型なら地域カテゴリの不確実性です。 目的変数を言葉で書かずに指標名だけを出すと、 聴き手は何が改善したのかを追えません。 情報利得の説明は、 目的変数、分割変数、分割後の純度を一文にまとめると読みやすくなります。

最後の確認として、 情報利得で選んだ変数が発表の問いに直接答えているかを見直します。 予測精度に効く変数でも、 研究の問いと関係が薄ければ主役にはしにくいです。 逆に、 指標値は中程度でも、 仮説に沿っていて説明しやすい変数は、 補助的な根拠として価値があります。 数理的な順位と発表上の重要度を分けて考えることで、 モデル任せではない分析になります。

発表前には、 上位変数について「なぜ高いのか」「どの観測に支えられているのか」「別の目的変数でも高いのか」を一行ずつ確認します。 この三点を答えられない変数は、 ランキング上は高くても主張の根拠として弱くなります。 情報利得は探索を始めるための地図であり、 結論そのものではありません。

🧾 発表前の最終確認

情報利得を示す時は、 どの目的変数の不確実性が減ったのかを明記します。 上位変数は因果原因ではなく、 分割後の純度を高めた変数なので、 分割後の件数と解釈可能性も確認します。

⚠️ よくある落とし穴(5 つ)

❌ 多値属性に偏る
ID 列のように値が多い属性は分割で純度を高めやすく、 IG が過大に出る。 C4.5 の ゲイン比 で正規化するか属性を制限する。
❌ 連続値はしきい値探索が必要
連続変数の IG はあらゆる候補しきい値で計算し最大値を採用。 sklearn の DecisionTreeClassifier が内部で実施。
❌ 単独の IG で重要度を決め打ち
IG は「1 段目」の貢献。 木の上層で使われた変数は重要に見えるが、 アンサンブルの importance や Permutation Importance と併用すべき。
❌ クラス不均衡時の過大評価
極端な不均衡だと親エントロピーが小さく、 IG 自体も小さくなりがち。 ジニ不純度や Balanced クラス重みも試す。
❌ ノード分割が増えるほど IG は単調増加に近い
葉ノードを増やすと過学習。 IG が小さくなった時点で剪定する閾値設計が肝要。

⚠️ さらに 5 つの落とし穴 — 実務で痛い目を見るパターン

❌ デフォルト設定をそのまま信じる
ライブラリのデフォルト引数は「平均的なケース」向け。 あなたのデータが平均的でなければ、 必ず設定を再検討する必要があります。 公式 docstring を読む癖をつけましょう。
❌ スケーリングを忘れる
「総人口」(数百万) と「出生率」(0.0〜2.0) では値域が 10⁶ 倍違う。 距離ベースの手法では、 必ず StandardScaler / MinMaxScaler でスケールを揃えること。
❌ 訓練データでの前処理パラメータをテストに使わない
StandardScaler の fit訓練データだけに対して行い、 テストには transform のみを適用。 これを混同するとデータリーケージになる。
❌ メトリクスの単位を見落とす
RMSE を「絶対値で 100」と聞いて大きいか小さいかは、 目的変数のスケールによる。 「出生率」(0〜2) で RMSE=100 はあり得ない、 などのサニティチェックを必ず。
❌ 「精度が高い = 良いモデル」と短絡
precision/recall の不均衡、 ラベルの偏り、 ベースラインとの比較を見ないと、 「高精度」は単に多数派を予測しているだけかもしれません。

🕰 歴史的経緯と現代的意味

情報利得 は、 統計学と計算機科学の流れの中から生まれました。 下の年表はこの分野全体の流れで、 情報利得 固有の年表ではありません。 この用語がどの時代の産物かを掴むために置いています。

時期出来事この時代に起きたこと
前史統計学・情報理論の基盤整備数式的な土台
古典期機械学習の黎明(1960〜80 年代)「情報利得」の原型が登場
展開期scikit-learn / TensorFlow など実装の普及(2010〜)誰でも 1 行で使える時代に
現代大規模モデル時代(2020〜)「情報利得」の意味が再解釈される

現代の文脈では、 古典的な定義のままでは説明しきれない使い方も出てきています。 教科書の定義を出発点としつつ、 実務での「変奏」も知っておくとよいでしょう。

❓ よくある質問

Q1. なぜこの定義になっているの? 別の式じゃダメ?

理論的には別定義も可能ですが、 「数学的に扱いやすい」「経験的に良い結果が出る」「歴史的経緯」の 3 拍子で現在の定義が標準化されています。 学術論文では別定義を「変種」として議論することもよくあります。

Q2. データが少ない(47 県)でも意味ある分析になる?

教育用途・探索的分析では十分。 ただし「統計的有意」を主張するには n=47 は不足することが多いので、 解釈は慎重に。 ブートストラップで信頼区間を出すと頑健性が確かめられます。

Q3. scikit-learn 以外でも実装はある?

PyTorch / TensorFlow / XGBoost / LightGBM など多数。 ただし基本的な動作確認は scikit-learn が一番速いので、 まず sklearn で動かしてから他に移植するのがおすすめ。

Q4. 大規模データ(百万行)でも同じ方法でいける?

計算量・メモリの観点でアルゴリズムを切り替える必要があります。 mini-batch 版、 サブサンプリング、 近似アルゴリズムの利用を検討します。 47 県スケールで本質を理解した後の応用課題です。

Q5. 論文を書くとき、 この概念をどう引用すべき?

古典的な定義は原典(教科書や著名論文)、 実装は使用ライブラリのバージョン情報を併記するのが標準。 「Murphy 2012」「Hastie et al. 2009」あたりが定番引用です。

Q6. 関連用語との学習順序は?

下の「📚 関連グループ教材」セクションのリストが、 推奨される学習順序の一つです。 上位概念から入って詳細に降りる「トップダウン」と、 1 つの具体例から始めて他に広げる「ボトムアップ」、 どちらも一長一短。 自分の学び方に合わせて。

⚠️ 情報利得の落とし穴(深掘り 6 件)

① 多値属性バイアス
「都道府県 ID」のように値の種類が多い属性は、 各分岐がほぼ純粋になり IG が異常に高くなる。 GainRatio や Gini で補正、 または高基数列を事前除外。
② リーク(目的変数の派生属性)
ラベル生成に使った列をそのまま特徴量にすると IG が極端に高い。 学習時の F1 は完璧でも実運用では崩壊。 必ず特徴量と目的変数の生成過程を分離。
③ 連続値の閾値依存
同じ属性でも閾値次第で IG は大きく変動。 sklearn は全候補を探索するが、 自前実装では刻みが粗いと最適閾値を逃す。 quantile ベースの候補生成が無難。
④ 不均衡データ
クラス比が 95:5 のとき、 親 H(Y) が小さいため IG の絶対値も小さくなる。 「IG が低い」≠「無情報」。 同クラスでの分割評価には class_weight 併用。
⑤ 過学習リスク
IG だけを追って深くすると、 すべての葉が純粋になる「メモリ化」が発生。 必ず max_depth、 min_samples_leaf、 ccp_alpha などの剪定パラメータを併用。
⑥ 欠損値処理
欠損のある行をどう振り分けるかで IG が変わる。 ID3 は欠損非対応、 C4.5 は確率的に振り分け。 実装ごとに挙動が違うので必ず確認。

🗺 用語マインドマップ — 周辺概念の整理

「情報利得」を中央に置いて、 周辺概念を 5 つの方向に整理します。 これは記憶の足場になります。

方向隣接概念関係性
北 (上位)機械学習・統計学本用語を包含する大きな枠組み
南 (下位)具体的タスク・実装本用語を使う具体例
東 (発展)利得比 (Gain Ratio) / Gini 不純度情報利得が多値属性を過大評価する弱点を補う発展形
西 (前提)エントロピー / 条件付き確率情報利得の理解に必要な土台
中央情報利得本ページの主役

マインドマップは「学んだ用語を整理する道具」として優秀。 紙にこの 5 方向を書き、 自分なりの隣接概念を埋めると、 暗黙的にあった理解構造が可視化されます。

📝 自己検証クイズ — 5 問

「情報利得」を本当に理解できたか、 自分でテストできるクイズです。 答えは展開で確認。

Q1. 「情報利得」を 30 秒で同僚に説明するとしたら、 何を最初に言う?

模範回答:上の「💡 30秒結論」を参照。 ポイントは「何のために使うか」を最初に言うこと。 定義や数式から入ると相手が引きます。

Q2. 数式の左辺と右辺、 それぞれ「動かせる量」「固定する量」はどれ?

模範回答:データは観測値で固定、 パラメータは学習で動かす、 出力は計算結果。 上の「📐 数式の構造をもう一度」を参照。

Q3. SSDSE-B-2026 で「情報利得」を使ったとき、 何が変わる?

模範回答:47 都道府県の特徴量を入力にすると、 結果が地理的に解釈しやすくなる、 一方でサンプル数が少ないため信頼区間は広めに出る、 など。

Q4. 「情報利得」と類似手法の最大の違いは?

模範回答:上の「🌐 似た概念との比較」表を参照。 1 文で言える違いを持っておくと、 「なぜこっちを選んだか」を説明できます。

Q5. 「情報利得」を使うときに最も気をつけるべき落とし穴は?

模範回答:上の「⚠️ 落とし穴」と「⚠️ さらに 5 つの落とし穴」セクションから、 自分のプロジェクトに最も関連するものを 1 つ選んで言語化してみましょう。

🗺 情報利得の歴史と発展

情報利得は 80 年近く前の Shannon の概念がそのまま現代の Kaggle 上位ソリューションまで貫いている、 非常に息の長い指標です。 数式を言葉で読み解くと「不確実性の削減」というシンプルな本質に行き着きます。

information gain エントロピー Gini 不純度 決定木 ID3 / C4.5 特徴量選択 相互情報量 I(X;Y) IG = H(親) − H(子)

🔗 隣接手法への橋渡し

情報利得 IG = H(親) - H(子) は決定木の分岐選択の中核で、 エントロピー計算と特徴選択を組み合わせて初めて意味を持つ。

IG だけだと「カテゴリ数が多い特徴 (例: ID 列)」を過大評価する偏りがある。 C4.5 は IG をエントロピーで正規化したゲイン比、 CART はジニ不純度を採用してこの問題を回避する。

🌳 手法選択フロー

分岐基準を、 タスクと変数性質で 3 段階で判定する。

  1. タスクは分類か回帰か? 分類 → IG / ジニ不純度、 回帰 → 分散減少 (variance reduction) または MSE 減少
  2. カテゴリ変数の水準数は? 少ない (2-5) → IG で問題なし、 多い (10+) or 連続 → ゲイン比 / ジニ不純度で偏りを回避
  3. 計算速度は? 学習速度重視 → ジニ不純度 (log を含まないので高速)、 解釈性重視 → 情報利得 (情報理論的に意味明瞭)

scikit-learn の DecisionTreeClassifier(criterion='entropy') で IG、 'gini' でジニ不純度を選べる。 実務では精度差は小さく、 デフォルトのジニで十分なケースが多い。

🔎 解説深化 — n=47 で測る IG は「偶然の利得」を含む

本ページの 🧮 実値計算では「高齢化率 ≥ 中央値」の分割で IG = 0.0562 bit を得ました。 ここでは一歩進んで、 その 0.0562 bit のうちどれだけが偶然かを、 同じ SSDSE-B-2026(2023 年・47 都道府県、 目的変数は 15 歳未満人口比率 A1301/A1101 ≥ 中央値の 2 値ラベル、 H(Y)=0.9997 bit)で実測します。 「IG は相互情報量の標本推定量であり、 小標本では正の方向に偏る」という、 本文の他セクションでは扱っていない角度です。

🎨 直感 — IG は相互情報量の「標本版」だから 0 にならない

$IG(X) = H(Y) - H(Y \mid X)$ は、 情報理論の相互情報量 $I(X;Y)$ をデータ中の頻度(プラグイン推定)で置き換えたものです。 真に無関係($I=0$)な属性でも、 標本では頻度が偶然に揺らぐため、 推定された IG はほぼ必ず正の値になります。 この正のバイアスは近似的に $\dfrac{(K-1)(V-1)}{2N\ln 2}$ bit($K$=クラス数、 $V$=分岐数、 $N$=標本数。 Miller の補正項)で、 2 値ラベル × 2 分岐・N=47 なら $\dfrac{1}{94 \ln 2} \approx 0.0153$ bit。 実際に 2023 年の実ラベルを 10,000 回シャッフル(シード 42 の置換検定)して「高齢化率 ≥ 中央値」分割の IG を測ると、 平均 0.0162 bitとなり理論近似とよく一致します。 つまり n=47 では、 何の情報も無くても平均 0.016 bit 程度の「見かけの利得」が出るのです。

⚠️ 落とし穴(重要) — 「IG > 0」は情報がある証拠にならない

以下はすべて実データ(SSDSE-B-2026、 2023 年断面)で実際に計算した値です。 比較用の帰無分布はシード 42・置換検定(固定分割 10,000 回/しきい値探索込み 2,000 回)による実測です。

分割実測 IG (bit)偶然の水準(置換検定)判定
都道府県コードが奇数/偶数(明らかに無意味)0.0003平均 0.0162 / 95% 点 0.0562偶然の範囲(今回はたまたま小さい側)
高齢化率 ≥ 中央値(本文 🧮 の分割)0.0562p = 0.084偶然の 95% 点とちょうど同水準。 5% 有意にならない
高齢化率・最良しきい値を全探索(46 候補の最大 IG)0.1733探索込み帰無分布:平均 0.0725 / 95% 点 0.1458 / p = 0.027探索を含めて検定すればぎりぎり有意

ここから 2 つの重要な教訓が読み取れます。

🚀 発展 — バイアス補正と「検定つき分割」へ

前提:情報エントロピー決定木。 本節の検定的視点:仮説検定p値多重検定カイ二乗検定ブートストラップ。 分割基準の比較:ジニ不純度。 アンサンブルでの緩和:ランダムフォレスト。 なお「相互情報量」「特徴量選択」「置換検定(permutation test)」の単独ページは本用語集には未作成のため、 本文の説明を参照してください。