06.2.2
密度プロット
sns.kdeplot(data=df, x="sepal_length") を列ごとに呼べば Iris の 4 変数を 1 枚に重ねられ、「花弁の長さは山が 2 つ、がく片の幅は 1 つ」のような形の違いが線で比べられます。読み終えると、bw_adjust を 0.5 と 2 で描き比べて形が安定する幅を選び、0 以下に伸びた裾のような推定の副作用を clip や cut で抑えられるようになります。直感 #
アヤメ 150 個の「がく片の長さ」をヒストグラムにすると、階級の幅を 0.5 cm にするか 0.3 cm にするかで山の形が変わり、どちらが本当の形か迷います。密度プロットは階級を作りません。150 個の点それぞれの位置に、同じ幅・同じ高さの小さな釣鐘型の山を置き、150 個の山を全部足し合わせて 1 本の曲線にします。点が集まっている場所では山が重なって高くなり、点が少ない場所では低くなるので、曲線の高さがそのまま「データの密度」になります。階級の切れ目に左右されない反面、置く山の幅を広くすると曲線は滑らかになりすぎて 2 つの山が 1 つにつながり、狭くすると点ごとのギザギザが残ります。
何が起きているか(ステップで見る) #
コードを読む前に、この手法が図の上で何をしているかを追ってみましょう。「再生」を押すか、スライダーを動かすと 1 手順ずつ進みます。
見るポイント:密度曲線は「各点に置いた小さな山の合計」。階級の切れ目に左右されない代わりに、山の幅(バンド幅)が形を決める。
Python で描く #
次のコードは Iris の 4 つの測定値それぞれに sns.kdeplot を呼び、色を変えて同じ軸に 4 本の密度曲線を重ねます。
| |

実行結果の読み方 #
petal_width(オレンジ)は 0.2 cm 付近に鋭い山があり、1〜2.5 cm に低い山が続く 2 山の形です。petal_length(緑)も 1.5 cm と 4〜5 cm の 2 山で、どちらも setosa とそれ以外の品種が混ざっているサインです。sepal_width(水色)は 3 cm 付近に 1 つの山だけで、品種で分けられない変数だと読めます。曲線は 0 以下にもわずかに伸びていますが、これは山の裾がはみ出した推定の副作用で、長さが負のデータが存在するわけではありません。
使いどころと落とし穴 #
密度プロットが向くのは、100 点以上あるデータの形を複数系列で重ねて比べたいときです。20 点程度しかないデータでは、バンド幅の選び方で山の数が変わってしまい、形を信じられないので ヒストグラム か ECDF に切り替えます。落とし穴は 2 つあります。第一に、bw_adjust が小さすぎるとギザギザ、大きすぎると特徴が潰れるので、既定値の前後で描き比べる必要があります。第二に、KDE は 0 以上しか取らないデータでも負の領域に密度を伸ばします。価格や長さのような列では clip=(0, None) か cut=0 を渡して裾をデータ範囲で切ります。
- ヒストグラム — 度数分布をビンで表示
- 2次元KDE — 2変数の密度を等高線で表示
- リッジラインプロット — カテゴリ別の分布を重ねて比較