【问题标题】:SciPy KDE gradientSciPy KDE 渐变
【发布时间】:2014-12-07 20:01:51
【问题描述】:

我正在使用内核密度估计 (KDE) (http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.gaussian_kde.html) 的 SciPy 实现,目前运行良好。但是,我现在想获得 KDE 在特定点的梯度。

我查看了该库的 Python 源代码,但无法弄清楚如何轻松实现此功能。有人知道这样做的方法吗?

【问题讨论】:

  • 你能提供一个独立的例子来说明你是如何使用这个函数的吗?
  • @pseudocubic 我不确定你到底是什么意思?基本上我想使用 scipy.stats.gaussian_kde() 函数计算 KDE,然后类似于 kde.evaluate(x) 函数,我希望能够调用类似 kde.gradient(x) where x是空间中的某个位置。

标签: python numpy scipy


【解决方案1】:

如果您查看您引用的来源,您会发现密度估计是根据数据集中所有点的贡献构建的 假设您目前只想评估一个点 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 以获得与在所有四个方向上评估 pp+delta 的密度估计一致的结果,这当然是我可能的标志远离这里。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-18
    • 2020-12-27
    • 2019-11-21
    • 2011-02-10
    • 2016-04-21
    • 2021-06-10
    • 2022-01-19
    • 1970-01-01
    相关资源
    最近更新 更多