首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SciPy KDE梯度

SciPy KDE梯度
EN

Stack Overflow用户
提问于 2014-10-13 17:37:50
回答 1查看 348关注 0票数 2

我使用的是内核密度估计(KDE) (http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.gaussian_kde.html)的SciPy实现,到目前为止它工作得很好。但是,我现在想要获得KDE在特定点处的梯度。

我已经查看了该库的Python源代码,但还不能确定如何轻松地实现此功能。有没有人知道这样做的方法?

EN

回答 1

Stack Overflow用户

发布于 2018-02-23 21:26:36

如果您查看您引用的源,您将看到密度估计是根据数据集中所有点的贡献构建的,假设目前只有一个点points[:,i]需要评估(第219-222行):

代码语言:javascript
复制
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

代码语言:javascript
复制
d = D - p
t = Cov^-1 d
e = 1/2 d^T t
r = exp(-e)

您要查找的梯度是grad(r) = (dr/dx, dr/dy)

代码语言:javascript
复制
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,并将其与您已经获得的结果相乘。

代码语言:javascript
复制
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,以获得与评估pp+delta在所有四个方向的密度估计一致的结果,这是一个迹象,我当然可能在这里走得很远。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26336883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档