2 次元配列のsklearn.neighbors.KernelDensityとscipy.stats.gaussian_kdeのパフォーマンスを比較しようとしています。
この記事から、帯域幅 (bw) が関数ごとに異なる方法で処理されていることがわかります。この記事では、正しい bw を に設定するためのレシピを提供しているscipy
ため、 で使用されているものと同等になりますsklearn
。基本的に、bw をサンプルの標準偏差で割ります。結果は次のとおりです。
# For sklearn
bw = 0.15
# For scipy
bw = 0.15/x.std(ddof=1)
x
KDE を取得するために使用しているサンプル配列はどこにありますか。これは 1D では問題なく機能しますが、2D では機能しません。
これが私が得たMWE
ものの一部です:
import numpy as np
from scipy import stats
from sklearn.neighbors import KernelDensity
# Generate random data.
n = 1000
m1, m2 = np.random.normal(0.2, 0.2, size=n), np.random.normal(0.2, 0.2, size=n)
# Define limits.
xmin, xmax = min(m1), max(m1)
ymin, ymax = min(m2), max(m2)
# Format data.
x, y = np.mgrid[xmin:xmax:100j, ymin:ymax:100j]
positions = np.vstack([x.ravel(), y.ravel()])
values = np.vstack([m1, m2])
# Define some point to evaluate the KDEs.
x1, y1 = 0.5, 0.5
# -------------------------------------------------------
# Perform a kernel density estimate on the data using scipy.
kernel = stats.gaussian_kde(values, bw_method=0.15/np.asarray(values).std(ddof=1))
# Get KDE value for the point.
iso1 = kernel((x1,y1))
print 'iso1 = ', iso[0]
# -------------------------------------------------------
# Perform a kernel density estimate on the data using sklearn.
kernel_sk = KernelDensity(kernel='gaussian', bandwidth=0.15).fit(zip(*values))
# Get KDE value for the point.
iso2 = kernel_sk.score_samples([[x1, y1]])
print 'iso2 = ', np.exp(iso2[0])
(ログ値を返すためiso2
、指数として表示されます)sklearn
私が得た結果は異なりiso1
、iso2
帯域幅を(どちらの関数でも)どのように影響させて(必要に応じて)等しくする必要があるのか わかりません。
追加
で同等の結果を得るには、 でカーネルを計算する前にsklearn
値をスケーリングする必要があることを (ep から) チャットでアドバイスされました。(x,y)
scipy
sklearn
だからこれは私がやったことです:
# Scale values.
x_val_sca = np.asarray(values[0])/np.asarray(values).std(axis=1)[0]
y_val_sca = np.asarray(values[1])/np.asarray(values).std(axis=1)[1]
values = [x_val_sca, y_val_sca]
kernel = stats.gaussian_kde(values, bw_method=bw_value)
scipy
つまり、カーネルを取得する前に、カーネルを取得する行をそのままにして、両方の次元をスケーリングしましたsklearn
。
これにより、より良い結果が得られましたが、取得されたカーネルにはまだ違いがあります。
赤い点は(x1,y1)
コード内のポイントです。ご覧のとおり、非常に小さいものではありますが、密度推定の形状にはまだ違いがあります。おそらくこれが達成できる最高のものでしょうか?