Python

Python seaborn チュートリアル プロット機能 データの分布を可視化 (2)

原文のドキュメントはこちらから。

カーネル密度推定

ヒストグラムは、観測値・結果をビン詰めしてカウントすることで、データを生成した基礎となる確率密度関数を近似することを目的としている。カーネル密度推定(KDE)は、同じ問題に対して異なる解決策を提供する。KDE プロットでは、ガウス・カーネルで観測値・結果を平滑化し、連続的な密度推定値を生成する。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="darkgrid")

penguins = sns.load_dataset("penguins")
sns.displot(penguins, x="flipper_length_mm", kind="kde")

plt.show()

平滑化の帯域幅の選択

ヒストグラムのビンサイズと同様に、KDEがデータを正確に表現できるかどうかは、平滑化の帯域幅の選択に依存する。過剰に平滑化された推定値は意味のある特徴を消し、過少に平滑化された推定値はランダムノイズの中にある真の形状を不明瞭にする可能性がある。推定値のロバスト性を確認する最も簡単な方法は、デフォルトの帯域幅を調整することである。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="darkgrid")

penguins = sns.load_dataset("penguins")
sns.displot(penguins, x="flipper_length_mm", kind="kde", bw_adjust=.25)

plt.show()

帯域幅が狭いと様相性がより顕著になるが曲線はスムーズでなくなり、対照的に帯域幅を大きくするとほぼ完全に不明瞭になる。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="darkgrid")

penguins = sns.load_dataset("penguins")
sns.displot(penguins, x="flipper_length_mm", kind="kde", bw_adjust=2)

plt.show()

他の変数への条件付け

ヒストグラムの場合と同様に、色相変数を割り当てると、その変数の各レベルに対して別々の密度推定値が計算される。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="darkgrid")

penguins = sns.load_dataset("penguins")
sns.displot(penguins, x="flipper_length_mm", hue="species", kind="kde")

plt.show()

多くの場合、レイヤーに分けられたKDEはレイヤーに分けられたヒストグラムよりも解釈しやすいため、比較のタスクには良い選択となることが多い。複数の分布を解決するための同じオプションの多くはKDEにも適用される。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="darkgrid")

penguins = sns.load_dataset("penguins")
sns.displot(penguins, x="flipper_length_mm", hue="species", kind="kde", multiple="stack")

plt.show()

積層プロットでは、デフォルトで各曲線間の領域が塗りつぶされていることに注目する。デフォルトのアルファ値 (不透明度) は異なるが、単一または層状密度の曲線を塗りつぶすことも可能で、個々の密度をより簡単に解決できる。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="darkgrid")

penguins = sns.load_dataset("penguins")
sns.displot(penguins, x="flipper_length_mm", hue="species", kind="kde", fill=True)

plt.show()

カーネル密度推定の落とし穴

KDE プロットには多くの利点がる。データの重要な特徴(中心傾向、様相性、歪み(スキュー))を見分けるのが簡単で、部分集合間の比較も簡単である。KDEが基礎となるデータをうまく表現できていない状況もある。これは、KDEのロジックが、基礎となる分布が滑らかで束縛されていないことを前提とするためである。可変量が自然に束縛された量を反映している場合、失敗する。境界に近いところにある観測値・結果がある場合(負にできない変数の小さな値など)、KDE 曲線は非現実的な値にまで伸びる可能性がある。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="darkgrid")

tips = sns.load_dataset("tips")
sns.displot(tips, x="total_bill", kind="kde")

plt.show()

これは、曲線が極端なデータポイントを超えてどこまで伸びるかを指定するカット・パラメータで部分的に回避できる。これは、曲線が描かれる場所にのみ影響を与える。密度の推定値は、データが存在しない範囲でも平滑化され、分布の極端な部分では人工的に低くなる。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="darkgrid")

tips = sns.load_dataset("tips")
sns.displot(tips, x="total_bill", kind="kde", cut=0)

plt.show()

KDEアプローチは、離散的なデータや、データが自然に連続しているが、特定の値が過剰に表現されている場合にも失敗する。重要なことは、データ自体が滑らかでない場合でも、KDEは常に滑らかな曲線を表示することである。ダイヤモンドの重みの分布を考える。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="darkgrid")

diamonds = sns.load_dataset("diamonds")
sns.displot(diamonds, x="carat", kind="kde")

plt.show()

KDEは特定の値にピークがあることを示唆しているが、ヒストグラムはよりギザギザした分布を示している。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="darkgrid")

diamonds = sns.load_dataset("diamonds")
sns.displot(diamonds, x="carat")

plt.show()


妥協点として、これら2つのアプローチを組み合わせることも可能である。ヒストグラムでは、 displot() (histplot() と同様に) 、平滑化された KDE 曲線を含むオプションがある (kde=True であり、 kind=”kde” ではないことに注意すること)。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="darkgrid")

diamonds = sns.load_dataset("diamonds")
sns.displot(diamonds, x="carat", kde=True)

plt.show()