如何验证两个数组来自不相关分布?(无需正态分布假设)
问题:检验两个数组是否来自不相关分布(无需正态假设)
我有两个数组array1和array2,想要判断它们背后的分布是否不相关,并且需要通过p值来判断结论的置信度,只看相关系数不够。
我原本用了下面的代码:
import numpy as np from scipy.stats import pearsonr array1 = np.array([1, 2, 3, 4, 5]) array2 = np.array([5, 4, 3, 2, 1]) # 计算皮尔逊相关系数和p值 res = pearsonr(array1, array2, alternative='two-sided') correlation_coefficient, p_value = res.statistic, res.pvalue # 输出结果 print(f"皮尔逊相关系数: {correlation_coefficient}") print(f"P值: {p_value}") # 设定置信水平(比如95%) confidence_level = 0.95 # 根据p值得出结论 if p_value < (1 - confidence_level): print(f"我有{confidence_level * 100}%的把握认为这两个数组存在相关性。")
输出结果:
皮尔逊相关系数: -1.0 P值: 0.0 我有95.0%的把握认为这两个数组存在相关性。
但这个方法有问题:pearsonr的原假设是样本背后的分布不相关且服从正态分布,而我只需要检验分布是否不相关,不需要考虑分布类型(正态或其他)。有没有替代方案?
我的两个初步思路
- 模拟不相关数组的分布:生成和
array1长度相同的随机数组,重复计算相关系数得到不相关数组的系数分布,再以此计算实际系数的p值。但担心numpy随机生成器的分布影响结果,而且不想额外写太多代码。 pearsonr的method参数是否可用?:不清楚method参数的作用,尤其是设置为PermutationMethod时,能不能解决我的问题?
解决方案
1. 使用pearsonr的置换检验(PermutationMethod)
这完全匹配你的需求!scipy.stats.pearsonr的method参数支持置换检验,这种方法不需要正态分布假设,原假设就是两个变量不相关。
置换检验的核心逻辑是:在“变量不相关”的原假设下,随机打乱其中一个数组的顺序,重新计算相关系数;重复该过程数千次后,得到相关系数的零分布,再通过实际相关系数在该分布中的位置计算p值。
代码示例:
import numpy as np from scipy.stats import pearsonr, PermutationMethod array1 = np.array([1, 2, 3, 4, 5]) array2 = np.array([5, 4, 3, 2, 1]) # 使用置换检验计算p值 res = pearsonr(array1, array2, alternative='two-sided', method=PermutationMethod(n_resamples=10000)) correlation_coefficient, p_value = res.statistic, res.pvalue print(f"皮尔逊相关系数: {correlation_coefficient}") print(f"置换检验P值: {p_value}") confidence_level = 0.95 if p_value < (1 - confidence_level): print(f"我有{confidence_level * 100}%的把握认为这两个数组存在相关性。")
n_resamples是置换次数,次数越多p值精度越高,一般设10000次即可满足需求。- 该方法完全避开正态分布假设,直接检验“是否不相关”的核心问题。
2. 非参数替代:斯皮尔曼秩相关检验
如果你的需求不仅是避开正态假设,还希望检验变量间的单调相关性(而非严格线性),可以使用scipy.stats.spearmanr。这也是非参数方法,原假设为两个变量不存在单调相关,同样不依赖正态分布。
代码示例:
import numpy as np from scipy.stats import spearmanr array1 = np.array([1, 2, 3, 4, 5]) array2 = np.array([5, 4, 3, 2, 1]) res = spearmanr(array1, array2, alternative='two-sided') correlation_coefficient, p_value = res.statistic, res.pvalue print(f"斯皮尔曼秩相关系数: {correlation_coefficient}") print(f"P值: {p_value}") confidence_level = 0.95 if p_value < (1 - confidence_level): print(f"我有{confidence_level * 100}%的把握认为这两个数组存在单调相关性。")
内容的提问来源于stack exchange,提问作者Anirban Chakraborty
相关产品推荐
相关产品推荐

