2

我将高斯核密度估计器拟合到一个变量,该变量是两个向量的差,称为“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 的差异处达到峰值,其他地方没有质量。

谢谢。

4

1 回答 1

2

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

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

于 2010-04-22T02:41:43.673 回答