このページで扱うキーワード(クリックで該当節へジャンプ):
🍰 まずはやさしく
なめらかな線で表すグラフです。
データの集まり具合を調べるために使います。
テストの点数の分布を見る時に便利です。
この手法の特徴と注意点を学びます。
scipy.stats.gaussian_kde または seaborn.kdeplot がワンライナー🍰 まずはやさしく
データの形を描いた曲線です。
分布の様子を正しく読み取るために使います。
スマホの利用時間の偏りを調べる時に使えます。
この曲線がどう作られるのかを解説します。
論文の図や報告書で、こんな曲線を見たはずです:
この「なめらかな曲線」が カーネル密度推定(KDE) の出力です。ヒストグラムは「ビン幅・端点」で見た目が変わる一方、KDE は各点に小さな山を重ねることで「ビンの恣意性」を回避し、分布の形を 1 本の連続曲線で表します。観察データの分布形(単峰/双峰、歪み、外れ値)を読み取る基本ツールです。
🍰 まずはやさしく
小さな山をたくさん重ねるイメージです。
データの密度を視覚的に出すために使います。
部活のメンバーの身長分布で考えます。
山を足して曲線を作る仕組みを説明します。
47 都道府県の 総人口 $x_1, x_2, \dots, x_{47}$ が手元にあるとします。各 $x_i$ の場所に、幅 $h$ の小さな鐘形の山(カーネル)を置きましょう。
カーネルの形は「正規分布(ガウス)」が一番よく使われます。すると:
点が密集する場所では山が重なって高くなり、まばらな場所では低い丘になります。つまり「データ点が密な場所ほど曲線が高い」 = 密度推定そのもの。
| 項目 | ヒストグラム | KDE |
|---|---|---|
| 形状 | 階段状の棒 | 連続したなめらかな曲線 |
| 調整パラメータ | ビン幅・ビン端点 | バンド幅 $h$・カーネル種類 |
| 端点依存性 | あり(同じ幅でも端点を 1 万人ずらすと形が変わる) | なし |
| 外れ値の表現 | その箱が「孤立した棒」になる | その点の周りに小さなコブ |
| 双峰分布の検出 | ビン幅次第で見落としやすい | $h$ が適切なら検出しやすい |
| 境界(0 以上の量など) | 自然に止まる | 負の領域にしみ出す(境界補正が必要) |
代表的カーネル関数:
| カーネル | 式 | 特徴 | 効率比 |
|---|---|---|---|
| Gaussian | $\frac{1}{\sqrt{2\pi}}e^{-u^2/2}$ | 滑らか・最もポピュラー | 0.951 |
| Epanechnikov | $\frac{3}{4}(1-u^2)_+$ | MISE 最適 | 1.000 |
| Uniform (矩形) | $\frac{1}{2}\mathbb{1}_{|u|\le1}$ | 階段状 | 0.929 |
| Triangular | $(1-|u|)_+$ | 計算軽い | 0.986 |
| Biweight | $\frac{15}{16}(1-u^2)^2_+$ | Epanechnikov より滑らか | 0.994 |
| Cosine | $\frac{\pi}{4}\cos(\pi u/2)$ | 理論的興味 | 0.999 |
カーネル選択は本質的にあまり重要ではなく、 バンド幅 $h$ の選択が決定的。 Gaussian カーネルは scipy/sklearn のデフォルトで、 微分可能性が必要な場合に推奨。
🍰 まずはやさしく
計算で曲線を出すためのルールです。
正確な分布の形を求めるために使います。
買い物で使う金額のばらつきを計算します。
計算に使う数式と設定について学びます。
$n$ 個の観測値 $x_1, x_2, \dots, x_n$ に対して、点 $x$ における密度推定値は:
カーネル $K$ は通常、次を満たします:
歪んだ分布や外れ値に頑健な改良版:
つまり KDE は「データ点ごとに小さな確率の山を置き、それらを足して大きな密度関数を作る」 という、極めて直感的な操作です。
KDE は「各データ点に置いた小さな山(カーネル)を足し合わせる」だけの操作です。下のキャンバスで実際に体感しましょう。薄い青の曲線が 1 点ごとのカーネル、濃い赤の曲線がそれらの合計=密度推定 $\hat{f}_h(x)$ です。キャンバスの空いた場所をクリック/タップすると点を追加できます。
試してほしいこと: ① h を小さくすると曲線がギザギザになり(各カーネルの山がそのまま見える=過適合/分散大)、 ② h を大きくすると 1 つの釣鐘に潰れて構造が消えます(過平滑/バイアス大)。 ③ 「推奨 h(Silverman)」を押すと $h=0.9\,\min(\hat{\sigma},\mathrm{IQR}/1.34)\,n^{-1/5}$(頑健版)で計算した目安のバンド幅にジャンプします。 ④ カーネルをガウス/矩形/三角で切り替えても、密度曲線の大枠はほとんど変わりません——「カーネルの種類より h の選択が決定的」を体感できます。
このおもちゃが示す 4 つの原理:(1) 密度=カーネルの重ね合わせ(薄い山の総和が濃い曲線)、 (2) h がバイアス・分散を支配(交差検証や Silverman則で選ぶ)、 (3) ビン端点に依存しない(ヒストグラムとの最大の違い)、 (4) 同じ「カーネル」の発想は次元削減の カーネル PCA や カーネル回帰 にも通じます。左端 0 付近では山が負側にしみ出す 境界バイアスも観察できます。
SSDSE-B-2026 の A1101(総人口)を 47 都道府県ぶん読み込み、人口分布の KDE を求めます。
| 統計量 | 値 |
|---|---|
| サンプル数 $n$ | 47(都道府県) |
| 最小値(鳥取) | 約 55 万人 |
| 中央値 | 約 175 万人 |
| 最大値(東京) | 約 1,400 万人 |
| 平均 | 約 268 万人 |
| 標準偏差 $\hat{\sigma}$ | 約 274 万人 |
| IQR | 約 152 万人 |
本物の 47 県データでこれを行えば、東京・大阪・神奈川のような大人口県はピーク右側に薄い裾を作り、地方県の密集が左側に高いピーク(約 100〜200 万人付近)を作ります。
KDE の漸近的平均積分二乗誤差 (AMISE) は次のように分解できます:
$$\mathrm{AMISE}(h) = \frac{R(K)}{nh} + \frac{1}{4} h^4 \sigma_K^4 R(f'')$$
第一項は分散(バンド幅が小さいほど大)、 第二項はバイアス(バンド幅が大きいほど大)。 微分して $0$ を解くと、 最適バンド幅は
$$h^\star = \left( \frac{R(K)}{n \sigma_K^4 R(f'')} \right)^{1/5}$$
この $h^\star$ は $n^{-1/5}$ のオーダーで縮みます。 $R(f'')$ は真の密度の二階微分の二乗積分で、 これを推定するのが Sheather-Jones の plug-in 法の核心。 SSDSE-B-2026 ($n=47$) では $h^\star \propto 47^{-0.2} = 0.46$ のオーダー、 SD の半分弱がベースライン値です。
$d$ 次元 KDE では $\mathrm{AMISE} = O(n^{-4/(d+4)})$ に劣化。 $d=10$ では $n=10^7$ が必要というのが「次元の呪い」の正体です。
合成 3 点データで x=4 の KDE 密度を計算する。
1 2 3 4 5 | import numpy as np from scipy.stats import gaussian_kde data = np.array([2, 4, 6]) kde = gaussian_kde(data, bw_method=1.0/np.std(data, ddof=1)) print(f"f(4) = {kde(4)[0]:.3f}") |
💬 手計算 (Step 2) 0.169 と Python 出力が完全一致。
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 | # SSDSE-B 都道府県人口の KDE import pandas as pd import numpy as np import matplotlib.pyplot as plt from scipy.stats import gaussian_kde # 1) データ読込(2 行目までヘッダ、1 行スキップ) df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1], encoding='cp932') pop = df['A1101'].values # 総人口 # 2) KDE オブジェクトを作る(バンド幅自動) kde = gaussian_kde(pop) # Scott のルール(デフォルト) kde_silver = gaussian_kde(pop, bw_method='silverman') # 3) 評価点を作って密度を計算 xs = np.linspace(pop.min(), pop.max(), 500) ys = kde(xs) ys_silver = kde_silver(xs) # 4) ヒストグラムと重ねて可視化 fig, ax = plt.subplots(figsize=(9, 5)) ax.hist(pop, bins=15, density=True, alpha=0.4, color='steelblue', label='Histogram') ax.plot(xs, ys, color='crimson', lw=2, label='KDE (Scott)') ax.plot(xs, ys_silver, color='darkgreen', lw=2, linestyle='--', label='KDE (Silverman)') ax.set_xlabel('Population'); ax.set_ylabel('Density') ax.legend(); plt.tight_layout(); plt.show() |
1 2 3 4 5 6 7 8 9 10 11 | import seaborn as sns import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1], encoding='cp932') # ヒストグラム + KDE を一気に sns.histplot(df['A1101'], kde=True, bins=15) # KDE 単独・バンド幅指定 sns.kdeplot(df['A1101'], bw_adjust=0.5) # 半分にして細かく sns.kdeplot(df['A1101'], bw_adjust=2.0) # 2倍にして滑らかに |
1 2 3 4 5 6 7 8 | # h を変えると何が起きるか可視化 import matplotlib.pyplot as plt fig, axes = plt.subplots(1, 4, figsize=(16, 4), sharey=True) for ax, bw in zip(axes, [0.1, 0.3, 1.0, 3.0]): kde = gaussian_kde(pop, bw_method=bw) ax.plot(xs, kde(xs)) ax.set_title(f'bw_method={bw}') plt.show() |
1 2 3 4 | # 2 変数の同時密度(等高線) sns.kdeplot(data=df, x='A1101', y='A1303', fill=True, cmap='mako') plt.xlabel('Population'); plt.ylabel('Elderly ratio (%)') plt.show() |
statsmodels の cut=0 オプション、 (c) 反射法・境界補正カーネル。
Q. なぜヒストグラムでなく KDE?
A. ヒストグラムはビン境界が人工的で、 同じデータでもビン幅・原点を変えると印象が変わります。 KDE は各点に滑らかなカーネルを置くので、 境界の任意性が消え、 微分可能で連続です。 SSDSE-B-2026 の人口分布のように歪んだデータでは、 ヒストグラムと KDE で見える特徴が異なることがあります。
Q. カーネル選択はどれくらい重要?
A. 本質的に重要ではありません。 Gaussian、 Epanechnikov、 三角など主要カーネルはどれも MISE 効率が 0.93 以上で大差なし。 「バンド幅選択」が桁違いに重要です。
Q. バンド幅自動選択の精度は?
A. Silverman は正規分布前提で過大評価する傾向。 Sheather-Jones plug-in は理論的に最良。 実務では複数手法を試して目視確認するのが安全です。
Q. 多次元 KDE は使える?
A. 2-3 次元までは実用的。 高次元では「次元の呪い」で必要サンプルが指数的に増えるため、 GMM や Mixture Model に切り替えるのが現実的。
Q. 境界バイアスの対処は?
A. 有界データ(例:年齢 0-100)で境界付近に密度が下がる現象。 反射法、 対数変換、 ベータカーネルで補正できます。
Q. 離散データに KDE を当ててもよい?
A. 推奨しません。 整数値の人数データに KDE を当てると人工的滑らかさが出ます。 離散変数なら確率質量関数、 または十分なジッターを加えた後 KDE が代替案。
金融
リスク管理で VaR (Value at Risk) を非パラメトリック分位点として推定。
生態学
動物の活動範囲 (home range) を空間 KDE で可視化。
交通工学
交通事故密度の地理的可視化。
医療画像
腫瘍の輝度分布を KDE で表現。
マーケティング
顧客の購買間隔分布の推定。
スポーツ分析
バスケのシュート位置の密度マップ。
犯罪マッピング
犯罪密度の地理的予測 (hot spot 分析)。
生物統計
遺伝子発現量の分布推定。
分布の可視化・推定
├── パラメトリック密度推定
│ ├── 正規分布のあてはめ(平均・分散を推定)
│ ├── 混合正規(GMM)
│ └── 一般指数族
├── ノンパラメトリック密度推定 ◀ ここに KDE
│ ├── ヒストグラム(階段状)
│ ├── KDE(なめらか) ◀ このページ
│ │ ├── ガウス KDE(最頻出)
│ │ ├── Epanechnikov KDE(最適)
│ │ ├── 適応的 KDE
│ │ └── 多変量 KDE
│ ├── 最近傍密度推定
│ └── オルソゴナル級数推定
├── 累積分布関数の推定
│ ├── Empirical CDF
│ └── 平滑 ECDF
└── 応用分野
├── 異常検知(密度が低い → 異常)
├── クラスタリング(Mean Shift など)
├── カーネル回帰(Nadaraya-Watson)
└── ベイズ事後分布の可視化
カーネル密度推定 (KDE) は、 離散的観測値 $\{x_1, \ldots, x_n\}$ から滑らかな密度関数を推定します。 ヒストグラムが「ビン境界の人工的な階段」を作るのに対し、 KDE は各観測点に「小さな山」(カーネル関数)を置き、 それを足し合わせるイメージです。
$$\hat f_h(x) = \frac{1}{nh} \sum_{i=1}^{n} K\!\left(\frac{x - x_i}{h}\right)$$
SSDSE-B-2026 の 47 都道府県人口データに KDE を適用すると、 東京・大阪のような大都市が右側に長い裾を作り、 多くの県が中央に固まる「右に歪んだ密度」が観察できます。 ヒストグラムでは見えにくい「双峰性」「希少な裾」が KDE では浮き彫りに。
KDE はバンド幅 h とカーネル選択によって描かれる滑らかな密度推定であり、 上流のヒストグラム探索と下流の分布検定・サンプリングへ橋渡しすることで本領を発揮する。
上流のヒストグラムでビンに頼らず分布形状を確認し、 並列の正規分布あてはめ・GMM と比較してパラメトリック仮定の妥当性を検証し、 下流の異常検知/密度比推定で KDE の出力 (確率密度) を直接判定スコアに使う流れで真価を発揮する。
カーネル密度推定 (KDE) を実際の課題に当てはめるとき、 用語固有の判断軸に沿って次の 3 段階で適切な選択を行う。
このフローはノンパラメトリック密度推定の基本方針。 KDE はバンド幅 h の選択が結果を左右するため、 Scott/Silverman の経験則や交差検証で h を慎重に決定する。
KDE は突然思いつかれた道具ではなく、 ヒストグラムの弱点を一つずつ潰していくと自然に到達します。 上の 🎨 直感 セクションを踏まえ、 「なぜ滑らかにするのか」をもう一段深掘りします。
同じデータでも、 ヒストグラムは作り手の選択で見た目が変わります。 これが ビン境界問題(binning problem) です。
ヒストグラムを「各データ点の上に幅 $w$・高さ一定の矩形の箱を積む」操作だと読み替えてみます。 すると、 この箱こそが 一様カーネルそのもの。 KDE はここで 2 つの改良を加えます。
残った ① だけが バンド幅 $h$ として KDE に引き継がれます。 つまり $h$ はヒストグラムのビン幅に相当し、 「どれだけ滑らかにするか」というただ 1 つの本質的な自由度に集約されたのです。 カーネルの種類(改良 A)はほとんど効かず、 $h$(元のビン幅)だけが決定的、 という 落とし穴 ⑤ の理由もここにあります。
別の見方をすると、 KDE は評価点 $x$ の周りで「近い観測点ほど重く数える加重平均」です。 重み $K\!\big((x-x_i)/h\big)$ は $x$ に近い点ほど大きい。 これは時系列の移動平均と同じ発想で、 $h$ は「窓の広さ」に対応します。 窓が狭い($h$ 小)ほど局所的でギザギザ、 広い($h$ 大)ほど大域的でなめらか——という直感がそのまま成り立ちます。
📝 補足:ヒストグラムそのものの詳細は histogram.html、 「密度」という量の定義は「確率密度」の項(本サイトに個別ページ未整備のため、 probability-distribution.html の密度関数の節)を参照。
上の ⚠️ 落とし穴 を、 SSDSE-B-2026 の 2023 年・総人口(A1101, 47 都道府県, $n=47$)の実測値で具体化します。 数値はすべて実データからの計算です。
同じデータに 3 つの経験則を当てると、 バンド幅が 2.7 倍も食い違います。
| 経験則 | 式 | 実測バンド幅 $h$ | 効果 |
|---|---|---|---|
| Scott 則 | $\hat{\sigma}\,n^{-1/5}$ | 約 1,295,265 | やや過平滑 |
| Silverman 則 | $1.06\,\hat{\sigma}\,n^{-1/5}$ | 約 1,372,981 | 過平滑(東京の外れ値に $\hat{\sigma}$ が引きずられる) |
| 頑健版 Silverman | $0.9\min(\hat{\sigma},\mathrm{IQR}/1.34)\,n^{-1/5}$ | 約 498,329 | IQR を使うので歪みに強い |
Scott / Silverman は正規分布を前提にした式です。 東京都という一つの巨大な外れ値が $\hat{\sigma}$ を約 280 万に押し上げ、 バンド幅が中央値付近の県間隔(数十万人)より大きくなってしまう。 結果、 「200 万人未満に 31 県が密集」という本当の峰が塗り潰される過平滑が起きます。 IQR を使う頑健版(約 50 万)の方がこのデータには適切で、 上の 📐 数式 の頑健版 Silverman が実務で推奨される理由が数値で確認できます。
人口は必ず正の量ですが、 ガウス KDE は鳥取県(537,000 人)の左側にも鐘の裾を伸ばし、 0 人・負の人口という物理的にありえない領域に密度を配ってしまいます。 $h \approx 137$ 万(Silverman)ではこのしみ出しが顕著。 対処は 落とし穴 ② の通りで、 実測では対数変換が特に有効です:対数スケールの Silverman バンド幅は約 0.394(頑健版 0.291)と桁が扱いやすく、 右歪みも同時に緩和されます。
$h$ を小さくすれば東京・大阪・愛知あたりに小さなコブが次々現れますが、 それらは ノイズ由来の偽の峰(でっち上げ)かもしれません。 逆に $h$ を大きくすれば「200 万人未満の 31 県」という本物の峰を見落とす。 $n=47$ という小標本ではこの判定が特に難しく、 「東京・大阪・愛知が外れ値で、 残りは実質単峰」という解釈も十分あり得ます。 異なる $h$ で頑健に残る峰だけを信じ、 必要ならブートストラップ検定で裏を取ります。 パラメトリックに多峰性を検証したいなら混合ガウス(→ gaussian-mixture.html)と併用します。
1 変数では快適な KDE も、 変数を増やすと急速に無力化します。 これは 次元の呪い(curse of dimensionality)で、 収束のために必要なサンプル数が次元 $d$ に対して指数的に膨らむためです。
| 次元 $d$ | 収束レート | 同じ精度に必要な相対サンプル数(目安) |
|---|---|---|
| 1(総人口だけ) | $n^{-4/5}$ | 基準(例:47) |
| 2(+世帯数) | $n^{-4/6}$ | 数倍 |
| 5 | $n^{-4/9}$ | 数百倍以上 |
| 10 以上 | $n^{-4/14}$ | 事実上、 到達不能 |
SSDSE-B の $n=47$ では、 2〜3 次元が実用上の限界。 高次元密度を扱いたいときは KDE をあきらめ、 パラメトリックな混合ガウス(GMM)や次元削減 → 低次元 KDE に切り替えるのが定石です(→ gaussian-mixture.html、 nonparametric.html)。
「$h$ を手で選ぶのは大変」という声に応える古典的な自動則が Scott / Silverman です。 どちらも $h \propto \hat{\sigma}\,n^{-1/5}$ という同じ骨格を持ちます(1 次元の場合)。
$-1/5$ という指数の意味:バイアス(過平滑)とバリアンス(ギザギザ)のトレードオフを最小化すると、 理論的に最適な $h$ は $n^{-1/5}$ のオーダーになります。 サンプルが増えるほど $h$ をゆっくり縮めるべき、 ということ。 上の実測では $n^{-1/5}=0.4630$ がこの因子でした。
カーネルを変えても結果はほとんど変わりません。 これを定量化するのが 相対効率で、 最適な Epanechnikov カーネルを 1.000 とした比です(上の 🎨 直感 の表を参照)。 ガウスカーネルでさえ効率 0.951——つまり同じ精度を出すのに必要なサンプルが約 5% 多いだけ。 実務では、
を選べば十分です。 「どのカーネルか」より「$h$ をどう決めるか」に労力を割く——これが KDE 運用の鉄則です。
ガウス KDE と GMM は、 じつは「ガウスの和で密度を表す」という同じ家族に属します。 違いはガウスをいくつ・どこに・どんな幅で置くかだけです。
| 項目 | ガウス KDE | 混合ガウス(GMM) |
|---|---|---|
| 成分の数 | $n$ 個(データ点ごとに 1 つ) | $K$ 個($K \ll n$、 事前に選ぶ) |
| 中心 | 各データ点に固定 | EM で推定(自由に動く) |
| 幅 | 全成分で共通の $h$ | 成分ごとに共分散を推定 |
| 重み | 全成分で等しく $1/n$ | 混合比 $\pi_k$ を推定 |
| 性質 | ノンパラメトリック | パラメトリック(半) |
| 高次元 | 次元の呪いで破綻 | 相対的に頑健 |
言い換えると、 KDE は「成分数を $n$ に固定し、 一切学習しない究極のノンパラメトリック GMM」。 逆に GMM は「成分を数個に絞って場所・幅・重みを学習した圧縮版 KDE」と言えます。 少数の峰がはっきりしていて解釈やサンプリングが目的なら GMM、 分布形状を先入観なく眺めたいなら KDE、 と使い分けます(→ gaussian-mixture.html)。
📝 補足:ここで挙げた数値(バンド幅 130 万 vs 50 万、 $n^{-1/5}=0.4630$ など)はすべて SSDSE-B-2026 2023 年・総人口の実測に基づく。 合成データは用いていない。