【发布时间】: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