33
40

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Pythonでカーネル密度推定

Posted at

カーネル密度推定(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.png

kdeオブジェクトのresample()メソッドとか使えば、測定データに近い分布のシミュレーション用のデータ生成とか捗ります。詳しくは公式ドキュメントで。

33
40
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
40

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?