在 Python 中的 numpy/scipy 中拟合高斯 KDE

发布于 2024-08-29 18:42:48 字数 1667 浏览 3 评论 0原文

我将高斯核密度估计器拟合到一个变量,该变量是两个向量的差,称为“diff”,如下所示: gaussian_kde_covfact(diff, smoothing_param) -- 其中 gaussian_kde_covfact 定义为:

class gaussian_kde_covfact(stats.gaussian_kde):
    def __init__(self, dataset, covfact = 'scotts'):
        self.covfact = covfact
        scipy.stats.gaussian_kde.__init__(self, dataset)

    def _compute_covariance_(self):
        '''not used'''
        self.inv_cov = np.linalg.inv(self.covariance)
        self._norm_factor = sqrt(np.linalg.det(2*np.pi*self.covariance)) * self.n

    def covariance_factor(self):
        if self.covfact in ['sc', 'scotts']:
            return self.scotts_factor()
        if self.covfact in ['si', 'silverman']:
            return self.silverman_factor()
        elif self.covfact:
            return float(self.covfact)
        else:
            raise ValueError, \
                'covariance factor has to be scotts, silverman or a number'

    def reset_covfact(self, covfact):
        self.covfact = covfact
        self.covariance_factor()
        self._compute_covariance()

这有效,但存在边缘情况其中 diff 是全 0 的向量。在这种情况下,我收到错误:

 File "/srv/pkg/python/python-packages/python26/scipy/scipy-0.7.1/lib/python2.6/site-packages/scipy/stats/kde.py", line 334, in _compute_covariance
    self.inv_cov = linalg.inv(self.covariance)
  File "/srv/pkg/python/python-packages/python26/scipy/scipy-0.7.1/lib/python2.6/site-packages/scipy/linalg/basic.py", line 382, in inv
    if info>0: raise LinAlgError, "singular matrix"
numpy.linalg.linalg.LinAlgError: singular matrix

有什么方法可以解决这个问题?在这种情况下,我希望它返回一个密度,该密度基本上在差异为 0 时完全达到峰值,其他地方没有质量。

谢谢。

I am fitting a Gaussian kernel density estimator to a variable that is the difference of two vectors, called "diff", as follows: gaussian_kde_covfact(diff, smoothing_param) -- where gaussian_kde_covfact is defined as:

class gaussian_kde_covfact(stats.gaussian_kde):
    def __init__(self, dataset, covfact = 'scotts'):
        self.covfact = covfact
        scipy.stats.gaussian_kde.__init__(self, dataset)

    def _compute_covariance_(self):
        '''not used'''
        self.inv_cov = np.linalg.inv(self.covariance)
        self._norm_factor = sqrt(np.linalg.det(2*np.pi*self.covariance)) * self.n

    def covariance_factor(self):
        if self.covfact in ['sc', 'scotts']:
            return self.scotts_factor()
        if self.covfact in ['si', 'silverman']:
            return self.silverman_factor()
        elif self.covfact:
            return float(self.covfact)
        else:
            raise ValueError, \
                'covariance factor has to be scotts, silverman or a number'

    def reset_covfact(self, covfact):
        self.covfact = covfact
        self.covariance_factor()
        self._compute_covariance()

This works, but there is an edge case where the diff is a vector of all 0s. In that case, I get the error:

 File "/srv/pkg/python/python-packages/python26/scipy/scipy-0.7.1/lib/python2.6/site-packages/scipy/stats/kde.py", line 334, in _compute_covariance
    self.inv_cov = linalg.inv(self.covariance)
  File "/srv/pkg/python/python-packages/python26/scipy/scipy-0.7.1/lib/python2.6/site-packages/scipy/linalg/basic.py", line 382, in inv
    if info>0: raise LinAlgError, "singular matrix"
numpy.linalg.linalg.LinAlgError: singular matrix

What's a way to get around this? In this case, I'd like it to return a density that's essentially peaked completely at a difference of 0, with no mass everywhere else.

thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

静赏你的温柔 2024-09-05 18:42:48

质量在某一点达到峰值的密度不是高斯分布,因此严格来说,您想要做的事情是未定义的(并且这种分布不具有有限协方差)。

现在,就您的情况而言,对于全为零的向量,您可以对其进行特殊处理,绕过整个基础设施。检测这种情况的一个简单方法是计算 diff 的最大值并将其与 eps 进行比较(向量 x 的 numpy.finfo(x.dtype).eps)。您也可以通过捕获 LinalgError 来简单地检测它,但您必须小心区分协方差定义不明确和 0 条目的情况。

A density peaked whose mass is at one point is not Gaussian, so strictly speaking, what you want to do is undefined (and such distribution does not have a finite covariance).

Now, in your case, for a vector which is all zero, you could special-case it, bypassing the whole infrastructure. A simple way to detect the case is to compute the max of the diff and compare this to eps (numpy.finfo(x.dtype).eps for the vector x). You could also simply detect it by catching the LinalgError, but you would have to be careful to differentiate the cases where covariance is ill defined and 0 entries.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文