2016-02-08 66 views
5

scipy.stats.multivariate_normalを使用しようとしていますが、あなたのお手伝いができるかもしれません。scipy.stats.multivariate_normal私の共分散行列が可逆であっても、 `LinAlgError:singular matrix`を引き上げる

私は、numpy.linalg.inv()を使用しての逆を見つけることが可能である2x2の行列を持って、私はmultivariate_normalで共分散行列としてそれを使用しようとすると、しかし、私はそれが特異行列であることを示すLinAlgError受け取る:

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) and 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 
+2

どのnumpyのバージョンを使用しますか?私はnumpy 1.10.1でコードを成功裏に実行できます。行列が技術的に*可逆であっても、ひどくスケーリングされていることに注意してください。 – kazemakase

+0

こんにちは、それはバージョン1.9.2です。 – Jonnyishman

答えて

8

デフォルトでは、multivariate_normalは、共分散行列の固有値のいずれかが、そのdtypeとその最大固有値の大きさに基づいて選択された許容誤差よりも小さいかどうかをチェックします(詳細はscipy.stats._multivariate._PSDおよびscipy.stats._multivariate._eigvalsh_to_epsのソースコードを参照してください)。

@kazemakaseは、あなたの共分散行列がnp.linalg.invで使用される基準に従って可逆でありながら、まだ非常に悪条件であるとmultivariate_normalで使用されるより厳格なテストに失敗し、前述したように。

allow_singular=Truemultivariate_normalを渡して、このテストをスキップすることができますが、一般に、そのような悪条件共分散行列を最初に通過させないようにデータを再スケーリングする方がよいでしょう。

+0

こんにちはali_m、 ご協力ありがとうございます。 multivariate_normalのソースコードの内部でチェックを行っているのがわかりました。私は、このような悪条件共分散行列を避けるためにデータを標準化するつもりです。 – Jonnyishman

関連する問題