news 2026/5/31 1:24:11

用Python实战斯皮尔曼相关系数:从手动推导到Pandas/Scipy一键调用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Python实战斯皮尔曼相关系数:从手动推导到Pandas/Scipy一键调用

用Python实战斯皮尔曼相关系数:从手动推导到Pandas/Scipy一键调用

在数据分析领域,理解变量间的关系往往比单纯计算数字更重要。想象你手头有一组学生的数学和物理成绩,想知道这两门学科的表现是否存在某种关联——是数学好的学生物理也普遍优秀,还是两者毫无规律可循?这时候,斯皮尔曼相关系数就像一把精准的尺子,能测量出这种关系的强度和方向。

与常见的皮尔逊相关系数不同,斯皮尔曼系数不要求数据呈正态分布,也不受异常值的过度影响。它通过比较数据的排名而非原始值,揭示的是单调关系(一个变量增加时,另一个变量是否倾向于同向或反向变化)。这种特性使其在真实世界的数据分析中尤为实用,因为完美符合统计假设的理想数据集实在太罕见了。

1. 手动计算:深入理解算法本质

要真正掌握一个统计概念,没有什么比亲手计算一次更有效。让我们从一个简单的数据集开始:

# 示例数据:10名学生的数学和物理成绩(满分100) math_scores = [78, 92, 65, 88, 56, 72, 85, 90, 62, 80] physics_scores = [82, 95, 60, 86, 50, 75, 88, 92, 58, 84]

1.1 数据转换为秩次

斯皮尔曼相关性的核心在于秩次(rank)转换。我们将原始分数转换为它们在各自科目中的排名:

import numpy as np def get_ranks(scores): # 使用scipy的rankdata处理相同值的情况 from scipy.stats import rankdata return rankdata(scores) math_ranks = get_ranks(math_scores) physics_ranks = get_ranks(physics_scores) print("数学成绩排名:", math_ranks) print("物理成绩排名:", physics_ranks)

注意:当存在相同分数时(即出现"结"tie),通常采用平均秩次。例如两个并列第三的分数会都获得3.5的秩次。

1.2 计算秩次差异

接下来,我们计算每对学生两科排名的差值(d)及其平方:

学生数学排名 (Rx)物理排名 (Ry)d = Rx - Ry
14400
2910-11
...............
d_squared = (math_ranks - physics_ranks)**2

1.3 应用斯皮尔曼公式

对于没有相同秩次的数据,可以使用简化公式:

$$ \rho = 1 - \frac{6 \sum d_i^2}{n(n^2 - 1)} $$

其中n是样本量。我们的Python实现:

n = len(math_scores) spearman_rho = 1 - (6 * np.sum(d_squared)) / (n * (n**2 - 1)) print(f"手动计算的斯皮尔曼系数: {spearman_rho:.3f}")

这个结果(约0.95)表明数学和物理成绩排名之间存在极强的正相关——数学排名高的学生,物理排名也倾向于较高。

2. 处理相同秩次(Tie)的情况

现实数据中经常出现相同值,这时需要采用更通用的皮尔逊相关系数公式计算秩次间的相关性:

from scipy.stats import pearsonr # 使用pearsonr计算秩次的相关性 rho, p_value = pearsonr(math_ranks, physics_ranks) print(f"考虑相同秩次的斯皮尔曼系数: {rho:.3f}")

重要提示:当数据中存在大量相同秩次时,简化公式会高估相关系数。使用皮尔逊公式计算秩次是更可靠的方法。

3. 使用Scipy进行高效计算

虽然手动计算有助于理解,但在实际工作中我们更倾向于使用优化过的库函数。Scipy的spearmanr函数不仅能快速计算相关系数,还提供统计显著性检验:

from scipy.stats import spearmanr rho, p_value = spearmanr(math_scores, physics_scores) print(f"Scipy计算结果 - 相关系数: {rho:.3f}, p值: {p_value:.4f}")

3.1 解读p值

p值(此处应远小于0.05)告诉我们,如果数学和物理成绩实际上毫无关联,我们观察到如此强相关性的概率有多大。低p值支持"两科成绩确实存在关联"的结论。

常见误解警示:p值大小并不直接反映相关性强弱,只说明相关性是否"显著"。强相关性可能因样本量小而p值不显著,反之亦然。

4. Pandas批量计算多变量相关性

当需要分析多个变量间的相关性时,Pandas提供了极其便捷的接口。假设我们有一个包含多科成绩的DataFrame:

import pandas as pd data = { '数学': math_scores, '物理': physics_scores, '化学': [75, 88, 62, 85, 52, 70, 82, 87, 60, 78], '生物': [80, 90, 58, 82, 55, 72, 85, 88, 63, 75] } df = pd.DataFrame(data) # 计算斯皮尔曼相关矩阵 corr_matrix = df.corr(method='spearman') print(corr_matrix)

这将输出一个漂亮的对称矩阵,展示所有学科两两之间的相关性:

数学 物理 化学 生物 数学 1.000 0.945 0.927 0.891 物理 0.945 1.000 0.964 0.927 化学 0.927 0.964 1.000 0.945 生物 0.891 0.927 0.945 1.000

4.1 可视化相关矩阵

为了更直观地理解,我们可以用热图可视化:

import seaborn as sns import matplotlib.pyplot as plt plt.figure(figsize=(8, 6)) sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1) plt.title("学科成绩斯皮尔曼相关矩阵") plt.show()

5. 实际应用中的注意事项

5.1 样本量要求

虽然斯皮尔曼相关对小样本也能计算,但解释结果时需要谨慎:

  • n < 10时,任何相关性结论都应视为初步探索
  • n > 30时,结果通常更稳定可靠
  • 当p值接近显著性阈值(如0.05)时,应考虑收集更多数据

5.2 非线性单调关系

斯皮尔曼能检测到皮尔逊相关可能遗漏的非线性单调关系。例如:

x = np.arange(0, 10, 0.1) y = x**2 + np.random.normal(0, 1, len(x)) pearson_r = pearsonr(x, y)[0] spearman_r = spearmanr(x, y)[0] print(f"皮尔逊系数: {pearson_r:.3f}, 斯皮尔曼系数: {spearman_r:.3f}")

虽然y与x是二次关系而非线性,斯皮尔曼仍能检测到完美的单调关系(系数≈1),而皮尔逊相关则会低估这种关联。

5.3 异常值鲁棒性

对比皮尔逊相关,斯皮尔曼对异常值更稳健:

x_clean = np.random.normal(0, 1, 100) y_clean = x_clean + np.random.normal(0, 0.5, 100) # 添加一个极端异常值 x_outlier = np.append(x_clean, 10) y_outlier = np.append(y_clean, -10) print("干净数据:") print(f"皮尔逊: {pearsonr(x_clean, y_clean)[0]:.3f}") print(f"斯皮尔曼: {spearmanr(x_clean, y_clean)[0]:.3f}") print("\n含异常值数据:") print(f"皮尔逊: {pearsonr(x_outlier, y_outlier)[0]:.3f}") print(f"斯皮尔曼: {spearmanr(x_outlier, y_outlier)[0]:.3f}")

可以看到异常值对皮尔逊相关的影响远大于斯皮尔曼。

6. 进阶应用:时间序列分析

斯皮尔曼相关在分析时间序列的单调趋势时特别有用。例如分析某股票价格与交易量之间的关系:

# 示例:股票价格与交易量的30天滚动斯皮尔曼相关 def rolling_spearman(price, volume, window=30): return price.rolling(window).corr(volume, method='spearman') # 假设df_stock包含'price'和'volume'列 df_stock['rolling_corr'] = rolling_spearman(df_stock['price'], df_stock['volume'])

这种分析可以揭示市场行为的变化模式,比如价格上升初期可能伴随成交量放大(正相关),而价格高位时可能转为负相关。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/31 1:23:45

树莓派Pico W调用ChatGPT API:嵌入式AI语音助手开发实战

1. 项目概述与核心价值最近在捣鼓一个智能语音助手的原型&#xff0c;核心想法是让一个巴掌大的树莓派Pico W板子&#xff0c;不仅能听懂人话&#xff0c;还能像ChatGPT一样“聪明”地回话。这听起来像是把大象塞进冰箱&#xff0c;但得益于如今成熟的云端AI API&#xff0c;这…

作者头像 李华
网站建设 2026/5/30 22:11:56

VMware里装CentOS 7.6,从镜像下载到分区配置的保姆级避坑指南

VMware虚拟机安装CentOS 7.6全流程实战指南在本地开发环境中搭建Linux系统是每个技术从业者的必修课。作为最稳定的企业级Linux发行版之一&#xff0c;CentOS 7.6至今仍是许多开发者和运维人员的首选。本文将带您从零开始&#xff0c;在VMware Workstation Pro中完成CentOS 7.6…

作者头像 李华
网站建设 2026/5/30 23:49:20

3PEAK思瑞浦 TPA6032-SO1R SOP8 运算放大器

特性 供电电压:2.5V至5.5V 低供电电流:每通道100安培 优异的电容负载驱动能力 偏移电压:3.5mV 偏移电压温度漂移:1V/C 轨到轨输入和输出 单位增益带宽:1.5MHz 峰值瞬态响应率:0.7V/us 优异的EMI抑制性能 低噪声:1kHz时为22nV/vHz 工作温度范围:-40C至125C

作者头像 李华
网站建设 2026/5/30 13:10:18

从CentOS Stream 8的坑说起:一次GitLab SSH克隆失败的完整排错实录

从CentOS Stream 8到GitLab SSH克隆&#xff1a;一次环境兼容性引发的深度排错最近在CentOS Stream 8上部署GitLab时&#xff0c;遇到了一个令人费解的问题&#xff1a;配置完SSH密钥后&#xff0c;执行git clone操作时系统不断要求输入密码&#xff0c;而无论输入什么密码都无…

作者头像 李华
网站建设 2026/5/30 13:26:14

VMware虚拟化环境下的iPXE实战:一键批量克隆Ubuntu 22.04系统镜像

VMware虚拟化环境下的iPXE实战&#xff1a;一键批量克隆Ubuntu 22.04系统镜像在企业IT基础设施管理中&#xff0c;虚拟化技术的普及使得快速部署大量标准化系统成为可能。VMware作为业界领先的虚拟化平台&#xff0c;其强大的网络功能和资源管理能力为自动化系统部署提供了理想…

作者头像 李华
网站建设 2026/5/30 14:43:55

AI犯罪防控:从预测警务到智能感知的实战解析

1. 从科幻到现实&#xff1a;AI如何重塑现代犯罪防控体系小时候看《蝙蝠侠》&#xff0c;最让人着迷的除了那身酷炫的装备&#xff0c;大概就是无所不能的“蝙蝠电脑”了。它能瞬间锁定罪犯位置、分析犯罪模式、甚至在罪恶发生前就发出预警。那时觉得&#xff0c;这不过是科幻作…

作者头像 李华