如何计算Kendall tau与Pearson r相关系数的标准误及Python实现
计算Kendall tau和Pearson r的标准误(Python实现)
嘿,我来帮你搞定这个问题!首先得提一句:你代码里的x1和x2长度不一样(x1有4个元素,x2有5个),Scipy的相关系数函数要求两个输入变量的长度必须一致,不然会直接报错。咱们先把这个小问题修正,后面的示例我会用调整后的相同长度数组来演示。
第一步:修正输入数据并计算基础相关系数
先把数据调整为相同长度,再用Scipy计算核心的相关系数:
import scipy.stats as stats from scipy.stats.stats import pearsonr import numpy as np # 修正后的相同长度数据(你可以根据实际需求调整) x1 = [10, 18, 23, 24, 15] x2 = [2, 45, 7, 10, 0] # 计算Pearson相关系数及其p值 r, p_pearson = pearsonr(x1, x2) # 计算Kendall tau相关系数及其p值 tau, p_kendall = stats.kendalltau(x1, x2) print(f"Pearson r: {r:.4f}, p值: {p_pearson:.4f}") print(f"Kendall tau: {tau:.4f}, p值: {p_kendall:.4f}")
第二步:计算Pearson r的标准误
Scipy没有直接返回Pearson r标准误的函数,但我们可以用经典统计公式手动计算:
标准误公式:$SE_r = \sqrt{\frac{1 - r^2}{n - 2}}$
其中$n$是样本量,$r$是Pearson相关系数
实现代码:
n = len(x1) # 计算Pearson r的标准误 se_pearson = np.sqrt((1 - r**2) / (n - 2)) print(f"Pearson r的标准误: {se_pearson:.4f}")
第三步:计算Kendall tau的标准误
Kendall tau的标准误计算分无结和有结两种情况(结指数据中存在重复观测值),咱们分别处理:
情况1:无结数据(所有观测值唯一)
如果你的数据里没有重复值,可以用简化公式:
标准误公式:$SE_{\tau} = \sqrt{\frac{2(2n + 5)}{9n(n - 1)}}$
实现代码:
# 无结情况下的Kendall tau标准误 se_kendall_no_tie = np.sqrt((2 * (2 * n + 5)) / (9 * n * (n - 1))) print(f"无结时Kendall tau的标准误: {se_kendall_no_tie:.4f}")
情况2:有结数据(存在重复观测值)
如果数据里有重复值,需要用更复杂的公式,考虑x和y变量中的结组大小:
标准误公式:
$SE_{\tau} = \sqrt{ \frac{n(n-1)(2n+5) - \sum t_i(t_i-1)(2t_i+5) - \sum u_j(u_j-1)(2u_j+5)}{9n(n-1)(n-2)} }$
其中$t_i$是x变量中每个结组的元素个数,$u_j$是y变量中每个结组的元素个数
实现代码:
def calculate_kendall_se_with_ties(x, y): n = len(x) # 计算x中的结组大小 x_counts = np.unique(x, return_counts=True)[1] sum_t = np.sum([t*(t-1)*(2*t +5) for t in x_counts]) # 计算y中的结组大小 y_counts = np.unique(y, return_counts=True)[1] sum_u = np.sum([u*(u-1)*(2*u +5) for u in y_counts]) # 计算分子和分母 numerator = n*(n-1)*(2*n +5) - sum_t - sum_u denominator = 9*n*(n-1)*(n-2) # 计算标准误 se = np.sqrt(numerator / denominator) return se # 计算有结情况下的Kendall tau标准误 se_kendall_with_ties = calculate_kendall_se_with_ties(x1, x2) print(f"有结时Kendall tau的标准误: {se_kendall_with_ties:.4f}")
这样你就能得到两个相关系数的标准误啦!如果你的数据有特殊情况(比如样本量极小),可以根据实际需求调整计算逻辑。
内容的提问来源于stack exchange,提问作者erhan




