在 Python 中的 numpy/scipy 中拟合高斯 KDE
我将高斯核密度估计器拟合到一个变量,该变量是两个向量的差,称为“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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
质量在某一点达到峰值的密度不是高斯分布,因此严格来说,您想要做的事情是未定义的(并且这种分布不具有有限协方差)。
现在,就您的情况而言,对于全为零的向量,您可以对其进行特殊处理,绕过整个基础设施。检测这种情况的一个简单方法是计算 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.