如何计算皮尔逊相关矩阵并仅保留有效值?

2024-04-26 15:11:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个4乘3的矩阵X,并且希望形成3乘3皮尔逊相关矩阵C,通过计算X的所有3个可能的列组合之间的相关性得到。然而,C的条目对应于统计上不显著的相关性,应该设置为零。你知道吗

我知道如何使用scipy.stats中的pearsonr获得成对相关性和显著性值。例如

import numpy as np
from scipy.stats.stats import pearsonr

X = np.array([[1, 1, -2], [0, 0, 0], [0, .2, 1], [5, 3, 4]])
pearsonr(X[:, 0], X[:, 1])

返回(0.9915008164289165, 0.00849918357108348)X的第1列和第2列之间的相关性约为.9915,p值为.0085。你知道吗

我可以使用嵌套循环轻松获得所需的矩阵:

  1. C预先填充为3乘3的零矩阵。你知道吗
  2. 嵌套循环的每个过程将对应于X的两列。与这对列对应的C条目将被设置为成对相关,前提是p值小于或等于我的阈值,例如.01。你知道吗

我想知道有没有更简单的方法。我知道在Pandas中,我可以在一行中创建相关矩阵C

import pandas as pd

df = pd.DataFrame(data=X)
C_frame = df.corr(method='pearson') 
C = C_frame.to_numpy()

有没有办法得到p值的矩阵或数据帧P,而不需要循环?如果是这样的话,如果P中对应的p值超过我的阈值,我如何将C的每个条目设置为零?你知道吗


Tags: importnumpydfasstatsnp条目矩阵
1条回答
网友
1楼 · 发布于 2024-04-26 15:11:03

在文档中查找^{}揭示了用于计算相关性的公式。使用矢量化来获得矩阵的每一列之间的相关性应该不太困难。你知道吗

虽然可以使用pandas计算C的值,但我将展示整个过程的纯numpyan实现。你知道吗

首先,计算r值:

X = np.array([[1,  1, -2],
              [0,  0,  0],
              [0, .2,  1],
              [5,  3,  4]])
n = X.shape[0]

X -= X.mean(axis=0)
s = (X**2).sum(axis=0)
r = (X[..., None] * X[..., None, :]).sum(axis=0) / np.sqrt(s[:, None] * s[None, :])

考虑到scipy中beta分布的存在,计算p值变得很简单。直接取自文件:

dist = scipy.stats.beta(n/2 - 1, n/2 - 1, loc=-1, scale=2)
p = 2 * dist.cdf(-abs(r))

您可以使用阈值从p生成一个掩码,并将其应用于r以生成C

mask = (p <= 0.01)
C = np.zeros_like(r)
C[mask] = r[mask]

更好的选择可能是修改r

r[p > 0.1] = 0

函数形式:

def non_trivial_correlation(X, threshold=0.1):
    n = X.shape[0]
    X = X - X.mean(axis=0) # Don't modify the original
    x = (X**2).sum(axis=0)
    r = (X[..., None] * X[..., None, :]).sum(axis=0) / np.sqrt(s[:, None] * s[None, :])
    p = 2 * scipy.stats.beta(n/2 - 1, n/2 - 1, loc=-1, scale=2).cdf(-abs(r))
    r[p > threshold] = 0
    return r

相关问题 更多 >