2010-04-20 150 views
2

我正在擬合一個變量的高斯核密度估計器,該變量是兩個向量的差異,稱爲「差異」,如下所示:gaussian_kde_covfact(diff,smoothing_param) - 其中gaussian_kde_covfact是定義爲:在Python中用numpy/scipy擬合高斯KDE

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的差值處完全達到峯值,其他地方沒有質量。

謝謝。

+0

以下是您提供的示例和完整示例代碼的鏈接(和作者):http://mail.scipy.org/pipermail/scipy-user/2010-January/023877.html – user333700 2010-10-19 15:17:58

回答

2

質量在一個點上達到峯值的密度不是高斯,所以嚴格地說,你想要做的是未定義的(並且這樣的分佈沒有有限的協方差)。

現在,在你的情況下,對於一個全零的向量,你可以繞過整個基礎設施來做一些特殊處理。檢測該案例的一種簡單方法是計算diff的最大值,並將其與eps(向量x的numpy.finfo(x.dtype).eps)進行比較。你也可以簡單地通過捕獲LinalgError來檢測它,但是你必須小心區分協變性不好的情況和0個條目。