python - scipy.stats.multivariate_normal raising `LinAlgError: singular matrix` even though my covariance matrix is invertible -


i having trouble trying use scipy.stats.multivariate_normal, 1 of might able help.

i have 2x2 matrix possible find inverse of using numpy.linalg.inv(), when attempt use covariance matrix in multivariate_normal receive linalgerror stating singular matrix:

in [89]: cov = np.array([[3.2e5**2, 3.2e5*0.103*-0.459],[3.2e5*0.103*-0.459, 0.103**2]])  in [90]: np.linalg.inv(cov) out[90]: array([[  1.23722158e-11,   1.76430200e-05],        [  1.76430200e-05,   1.19418880e+02]])  in [91]: multivariate_normal([0,0], cov) --------------------------------------------------------------------------- linalgerror                               traceback (most recent call last) <ipython-input-91-44a6625beda5> in <module>() ----> 1 multivariate_normal([0,0], cov)  /mnt/ssd/enthought_jli199/canopy_64bit/user/lib/python2.7/site-packages/scipy/stats/_multivariate.pyc in __call__(self, mean, cov, allow_singular, seed)     421         return multivariate_normal_frozen(mean, cov,     422                                           allow_singular=allow_singular, --> 423                                           seed=seed)     424     425     def _logpdf(self, x, mean, prec_u, log_det_cov, rank):  /mnt/ssd/enthought_jli199/canopy_64bit/user/lib/python2.7/site-packages/scipy/stats/_multivariate.pyc in __init__(self, mean, cov, allow_singular, seed)     591         """     592         self.dim, self.mean, self.cov = _process_parameters(none, mean, cov) --> 593         self.cov_info = _psd(self.cov, allow_singular=allow_singular)     594         self._dist = multivariate_normal_gen(seed)     595  /mnt/ssd/enthought_jli199/canopy_64bit/user/lib/python2.7/site-packages/scipy/stats/_multivariate.pyc in __init__(self, m, cond, rcond, lower, check_finite, allow_singular)     217         d = s[s > eps]     218         if len(d) < len(s) , not allow_singular: --> 219             raise np.linalg.linalgerror('singular matrix')     220         s_pinv = _pinv_1d(s, eps)     221         u = np.multiply(u, np.sqrt(s_pinv))  linalgerror: singular matrix 

by default multivariate_normal checks whether of eigenvalues of covariance matrix less tolerance chosen based on dtype , magnitude of largest eigenvalue (take @ source code scipy.stats._multivariate._psd , scipy.stats._multivariate._eigvalsh_to_eps full details).

as @kazemakase mentioned above, whilst covariance matrix may invertible according criteria used np.linalg.inv, still ill-conditioned , fails more stringent test used multivariate_normal.

you pass allow_singular=true multivariate_normal skip test, in general better rescale data avoid passing such ill-conditioned covariance matrix in first place.


Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -