【问题标题】:python - how to compute correlation-matrix with nans in data-matrixpython - 如何使用数据矩阵中的 nans 计算相关矩阵
【发布时间】:2014-11-24 11:43:51
【问题描述】:

当数据中存在 NaN 时,我找不到一个函数来计算包含两个以上变量的观察值的数组的相关系数矩阵。有些函数对成对的变量执行此操作(或仅使用 ~is.nan() 屏蔽数组)。但是通过循环大量变量来使用这些函数,计算每对变量的相关性可能非常耗时。

所以我自己尝试并很快意识到这样做的复杂性是协方差正确标准化的问题。我会对你对如何做到这一点的意见非常感兴趣。

代码如下:

def nancorr(X,nanfact=False):
    X = X - np.nanmean(X,axis=1,keepdims = True)*np.ones((1,X.shape[1]))

    if nanfact:
        mask = np.isnan(X).astype(int)
        fact = X.shape[1] - np.dot(mask,mask.T) - 1    

    X[np.isnan(X)] = 0
    if nanfact:
        cov = np.dot(X,X.T)/fact
    else:
        cov = np.dot(X,X.T)

    d = np.diag(cov)
    return cov/np.sqrt(np.multiply.outer(d,d))

该函数假定每一行都是一个变量。它基本上是来自 numpy 的 corrcoeff() 的调整代码。 我相信有三种方法可以做到这一点:

(1) 对于每一对变量,您只取其中一个变量或另一个变量都不是 NaN 的那些观察值。这可以说是最准确但也是最难编程的一种,如果你想同时计算不止一对并且上面的代码没有涵盖。但是,为什么仅仅因为另一个变量的对应条目是 NaN 就丢弃每个变量的均值和方差的信息?因此,还有另外两个选择。

(2) 我们用 nanmean 贬低每个变量,每个变量的方差就是它的 nanvariance。对于协方差,其中一个或另一个变量为 NaN 但不是两者均为 NaN 的每个观测值都是无协变观测值,因此设置为零。那么协方差的因子是 1/(观察的数量,其中不是两个变量都是 NaN - 1),用 n 表示。相关系数分母中的两个方差均由其相应的非 NaN 观测数减 1 来分解,分别用 n1 和 n2 表示。这是通过在上面的函数中设置 nanfact=True 来实现的。

(3) 人们可能希望协方差和方差具有与没有 NaN 的相关系数的情况相同的因子。在这里执行此操作的唯一有意义的方法(如果选项 (1) 不可行)是简单地忽略 (1/n)/sqrt(1/n1*n2)。由于该数字小于 1,因此估计的相关系数(绝对值)将大于(2)中的值,但仍将保持在 -1,1 之间。这是通过设置 nanfact=False 来实现的。

我对您对方法 (2) 和 (3) 的意见非常感兴趣,尤其是,我非常希望看到不使用循环的 (1) 的解决方案。

【问题讨论】:

    标签: python numpy scipy correlation


    【解决方案1】:

    我认为您正在寻找的方法是来自 pandas 的 corr()。例如,如下的数据框。你也可以参考这个问题。 How to efficiently get the correlation matrix (with p-values) of a data frame with NaN values?

    import pandas as pd
    df = pd.DataFrame({'A': [2, None, 1, -4, None, None, 3],
                       'B': [None, 1, None, None, 1, 3, None],
                       'C': [2, 1, None, 2, 2.1, 1, 0],
                       'D': [-2, 1.1, 3.2, 2, None, 1, None]})
    
    df
    
        A       B       C       D
    0   2       NaN     2       -2
    1   NaN     1       1       1.1
    2   1       NaN     NaN     3.2
    3   -4      NaN     2       2
    4   NaN     1       2.1     NaN
    5   NaN     3       1       1
    6   3       NaN     0       NaN
    
    rho = df.corr()
    rho
    
           A          B            C           D
    A   1.000000     NaN       -0.609994    -0.441784
    B   NaN          1.0       -0.500000    -1.000000
    C   -0.609994    -0.5       1.000000    -0.347928
    D   0.041204     -1.0       -0.347928    1.000000
    

    【讨论】:

    • 所以 pandas 显然提供了我在上面选项 (1) 中描述的内容。也就是说,在计算成对相关性时,它仅使用在两列中都不是Nan 的那些观察值——即使用于计算均值和方差。我在上面没有提出的另一个问题是,我不确定这是否保证了半正定 Cov。顺便说一句,您似乎为您的示例数据框提供了错误的 corr-matrix。例如。 C,D 条目应为 -0.347928。
    • 更正了 corr-matrix 结果。
    • panda.corr 对于带有 nans 的数组来说非常慢。它基本上是一个手写的python循环。
    猜你喜欢
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 2016-06-12
    • 2015-05-17
    • 2020-10-20
    • 2023-02-04
    • 1970-01-01
    相关资源
    最近更新 更多