カーネル密度推定(Kernel Density Estimation: KDE)とは
Wikipediaあたりご参考願います。
状況によっては(データ数が多い、滑らかな分布関数に従っている、etc.)、ヒストグラムよりデータの概要を把握するのに役立ちます。
適当なデータを作る
まずは必要なパッケージを読み込み、正規分布を重ねあわせた双峰性のデータセットを5個ほど作ります。
import numpy as np
from scipy.stats import gaussian_kde
import matplotlib.pyplot as plt
N = 5
means = np.random.randn(N,2) * 10 + np.array([100, 200])
stdev = np.random.randn(N,2) * 10 + 30
count = np.int64(np.int64(np.random.randn(N,2) * 10000 + 50000))
a = [
np.hstack([
np.random.randn(count[i,j]) * stdev[i,j] + means[i,j]
for j in range(2)])
for i in range(N)]
データから分布を推定してグラフを書く。
とんでもない外れ値があると面倒なので、0.1%から99.9%までの百分位点でデータを切ってしまいます。
(余談ですがnumpyではpercentile(array, x)
で0..100の範囲で指定なのに、pandasではSeries.quantile(x)
で0..1で指定です。ややこしい。)
続いてscipy.stats.gaussian_kde()
にデータを渡せば、ガウシアンカーネルで推定された密度関数を返してくれるので、numpy.linspace
と組み合わせればサクッとプロットできます。
limmin = min(np.percentile(x, 0.1) for x in a)
limmax = max(np.percentile(x, 99.9) for x in a)
ls = np.linspace(limmin, limmax, 100)
for n in range(N):
x = a[n]
x = x[(x > limmin)&(x < limmax)]
kde = gaussian_kde(x)
plt.plot(ls, kde(ls), label='data %d' % n)
plt.xlim([limmin, limmax])
plt.legend()
plt.title('data distributions')
plt.show()
kdeオブジェクトのresample()
メソッドとか使えば、測定データに近い分布のシミュレーション用のデータ生成とか捗ります。詳しくは公式ドキュメントで。