How to find degenerate rows/columns in a covariance matrix

后端 未结 1 599
栀梦
栀梦 2020-12-09 13:09

I am using numpy.cov to create a covariance matrix from a dataset of over 400 time series. Using linalg.det gives me a value of zero so matrix is singular. I can use linalg.

相关标签:
1条回答
  • 2020-12-09 13:26

    If you take the QR decomposition of a matrix A, the columns of R with a non-zero value along the diagonal correspond to linearly independent columns of A.


    import numpy as np
    linalg = np.linalg
    
    def independent_columns(A, tol = 1e-05):
        """
        Return an array composed of independent columns of A.
    
        Note the answer may not be unique; this function returns one of many
        possible answers.
    
        http://stackoverflow.com/q/13312498/190597 (user1812712)
        http://math.stackexchange.com/a/199132/1140 (Gerry Myerson)
        http://mail.scipy.org/pipermail/numpy-discussion/2008-November/038705.html
            (Anne Archibald)
    
        >>> A = np.array([(2,4,1,3),(-1,-2,1,0),(0,0,2,2),(3,6,2,5)])
        >>> independent_columns(A)
        np.array([[1, 4],
                  [2, 5],
                  [3, 6]])
        """
        Q, R = linalg.qr(A)
        independent = np.where(np.abs(R.diagonal()) > tol)[0]
        return A[:, independent]
    
    def matrixrank(A,tol=1e-8):
        """
        http://mail.scipy.org/pipermail/numpy-discussion/2008-February/031218.html
        """
        s = linalg.svd(A,compute_uv=0)
        return sum( np.where( s>tol, 1, 0 ) )
    
    
    matrices = [
        np.array([(2,4,1,3),(-1,-2,1,0),(0,0,2,2),(3,6,2,5)]),
        np.array([(1,2,3),(2,4,6),(4,5,6)]).T,
        np.array([(1,2,3,1),(2,4,6,2),(4,5,6,3)]).T,
        np.array([(1,2,3,1),(2,4,6,3),(4,5,6,3)]).T,
        np.array([(1,2,3),(2,4,6),(4,5,6),(7,8,9)]).T
        ]
    
    for A in matrices:
        B = independent_columns(A)
        assert matrixrank(A) == matrixrank(B) == B.shape[-1]
    

    assert matrixrank(A) == matrixrank(B) checks that the independent_columns function returns a matrix of the same rank as A.

    assert matrixrank(B) == B.shape[-1] checks that the rank of B equals the number of columns of B.

    0 讨论(0)
提交回复
热议问题