我使用的是内核密度估计(KDE) (http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.gaussian_kde.html)的SciPy实现,到目前为止它工作得很好。但是,我现在想要获得KDE在特定点处的梯度。
我已经查看了该库的Python源代码,但还不能确定如何轻松地实现此功能。有没有人知道这样做的方法?
发布于 2018-02-23 21:26:36
如果您查看您引用的源,您将看到密度估计是根据数据集中所有点的贡献构建的,假设目前只有一个点points[:,i]需要评估(第219-222行):
diff = self.dataset - points[:, i, newaxis]
tdiff = dot(self.inv_cov, diff)
energy = sum(diff * tdiff, axis=0) / 2.0
result[i] = sum(exp(-energy), axis=0)在矩阵表示法中(没有可用的LaTeX?),这将写入数据集的单点D和要计算为的点p
d = D - p
t = Cov^-1 d
e = 1/2 d^T t
r = exp(-e)您要查找的梯度是grad(r) = (dr/dx, dr/dy)
dr/dx = d(exp(-e))/dx
= -de/dx exp(-e)
= -d(1/2 d^T Cov^-1 d)/dx exp(-e)
= -(Cov^-1 d) exp(-e)dr/dy也是如此。因此,您所需要做的就是计算术语Cov^-1 d,并将其与您已经获得的结果相乘。
result = zeros((self.d,m), dtype=float)
[...]
diff = self.dataset - points[:, i, newaxis]
tdiff = dot(self.inv_cov, diff)
energy = sum(diff * tdiff, axis=0) / 2.0
grad = dot(self.inv_cov, diff)
result[:,i] = sum(grad * exp(-energy), axis=1)由于某些原因,我在计算grad时需要去掉-1,以获得与评估p和p+delta在所有四个方向的密度估计一致的结果,这是一个迹象,我当然可能在这里走得很远。
https://stackoverflow.com/questions/26336883
复制相似问题