に示すKLダイバージェンスのノンパラメトリック推定を実装しようとしていますが、私のコードは次のとおりです。
import numpy as np
import math
import itertools
import random
from scipy.interpolate import interp1d
def log(x):
if x > 0: return math.log(x)
else: return 0
g = lambda x, inp,N : sum(0.5 + 0.5 * np.sign(x-inp))/N
def ecdf(x,N):
out = [g(i,x,N) for i in x]
fun = interp1d(x, out, kind='linear', bounds_error = False, fill_value = (0,1))
return fun
def KL_est(x,y):
ex = min(np.diff(sorted(np.unique(x))))
ey = min(np.diff(sorted(np.unique(y))))
e = min(ex,ey) * 0.9
N = len(x)
x.sort()
y.sort()
P = ecdf(x,N)
Q = ecdf(y,N)
KL = sum(log(v) for v in ((P(x)-P(x-e))/(Q(x)-Q(x-e))))/N
return KL
私のトラブルは、scipyのダウンロードinterp1dです。私はinterp1dから返された関数を使って、新しい入力の値を見いだしています。問題は、入力値の一部が非常に近く(10^-5離れている)、関数が両方の値が同じ値を返すことです。上のコードでは、Q(x)-Q(x-e)はゼロ除算エラーにつながります。ここで
は、問題を再現するいくつかのテストコードです:
x = np.random.normal(0, 1, 10)
y = np.random.normal(0, 1, 10)
ex = min(np.diff(sorted(np.unique(x))))
ey = min(np.diff(sorted(np.unique(y))))
e = min(ex,ey) * 0.9
N = len(x)
x.sort()
y.sort()
P = ecdf(x,N)
Q = ecdf(y,N)
KL = sum(log(v) for v in ((P(x)-P(x-e))/(Q(x)-Q(x-e))))/N
にはどうすれば、より正確な補間を取得しに行きますか?
恐ろしい!それは完璧に働いた。助けてくれてありがとう! – darkyoda182