问题描述
我正在使用内核密度估计(KDE)的SciPy实现( http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.gaussian_kde.html ),到目前为止,它的运行情况还不错.但是,我现在想获取特定点的KDE梯度.
I am using the SciPy implementation of the kernel density estimate (KDE) (http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.gaussian_kde.html), which is working fine so far. However, I would now like to obtain the gradient of the KDE at a particular point.
我看过了该库的Python源代码,但是还没有弄清楚如何轻松实现此功能.有人知道这样做的方法吗?
I have looked at the Python source for the library, but haven't been able to figure out how to easily implement this functionality. Is anybody aware of a method to do this?
推荐答案
如果查看所引用的源,您会发现密度估计是根据数据集中所有点的贡献构建的.假设只有一个点points[:,i]
您现在要评估(第219-222行):
If you look at the source you referenced, you'll see that the density estimation is constructed from contributions from all points in the dataset Assuming there's only one point points[:,i]
you want to evaluate for the moment (lines 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
进行写
In matrix notation (no LaTeX available?), this would be written, for a single point D
from the dataset and point p
to be evaluated as
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
并将其与您已经获得的结果相乘.
Likewise for dr/dy
. Hence all you need to do is calculate the term Cov^-1 d
and multiply it with the result you already obtained.
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
处的密度估计值一致的结果,这当然是我可能会想到的迹象离开这里.
For some reason I needed to drop the -1
when calculating grad
to obtain results coherent with a evaluating the density estimation at p
and p+delta
in all four directions, which is a sign I might of course be way off here.
这篇关于SciPy KDE渐变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!