Python 概率计算工作流:scipy.stats 实战

06-实践与误区 核心 约 20 分钟 #Python#scipy#统计检验#工作流 更新 2026-10-02
当前状态:未学
本文基于模型知识整理(生成时未联网核对),API 细节以 scipy.stats 官方文档为准。

一句话定义

Python 把本库的概念一一映射成 API:scipy.stats 的每个分布对象自带 pdf/pmf/cdf/ppf/rvs(密度/累积/分位数/采样四大件),检验函数(ttest_ind/chi2_contingency)封装 kp-021 的流水线,numpy.random 的 Generator 是蒙特卡洛(kp-026)的引擎——学习循环仍是"手算小例 → 代码验证 → 图形检查"。

为什么重要

概率的实战产出(检验报告、置信区间、模拟结论)几乎都在代码里完成;但 API 用错(如单双侧混淆、参数是方差还是标准差)比手算错误更隐蔽。把"概念 ↔ API 参数"的映射表焊死,是从"会算"到"敢交付"的最后一步。

前置知识

kp-006~009(分布族)、kp-017/021(检验);Python/NumPy 基础。

核心概念(API ↔ 概念对照)

import numpy as np
from scipy import stats

rng = np.random.default_rng(42)        # 复现纪律 (kp-028 姊妹)

# ---- 分布四大件 (以 N(170, 8²) 为例) ----
X = stats.norm(loc=170, scale=8)       # 注意: scale=标准差(不是方差!)
X.pdf(178)                             # 密度 f (kp-006: 不是概率)
X.cdf(178)                             # P(X≤178) ≈ 0.8413 (kp-006 CDF)
X.ppf(0.975)                           # 分位数=逆CDF (kp-027 逆变换的现成件)
X.rvs(size=1000, random_state=rng)     # 采样 (kp-026/027)

# ---- 检验 ----
t, p = stats.ttest_ind(a_group, b_group, equal_var=False)  # Welch t (kp-021)
chi2, p, dof, tab = stats.chi2_contingency(table)          # 独立性 χ² (kp-017)

# ---- 拟合 ----
lam_hat, loc, _ = stats.expon.fit(wait_times, floc=0)      # MLE 拟合 (kp-018)

# ---- 蒙特卡洛验证定理 ----
means = [rng.normal(0, 1, 100).mean() for _ in range(5000)]
np.std(means)                          # ≈ 1/√100 = 0.1  → CLT 实测 (kp-015)

原理与机制

分布对象的"冻结参数"模式:stats.norm(170, 8) 返回冻结分布——之后 pdf/cdf/ppf/rvs 全部共享参数,避免每处重传;批量任务(扫描不同 μ)用 stats.norm.pdf(x, loc=…) 的未冻结形态。

rvs 与可复现性:random_state=rng 把随机流钉在显式 Generator 上——同一 seed 同一序列(kp-028 的复现纪律);default_rng 是新一代生成器(优于全局 np.random.seed)。

检验函数的"读输出"纪律:ttest_ind 返回 (统计量, p 值)——p 值语义照 kp-021(数据的罕见度而非假设概率);equal_var=False 选 Welch(方差不等时更稳,默认应选它);chi2_contingency 返回的 expected_freq 应全 ≥5,否则 χ² 近似失效(kp-030 精神)。

验证循环:每用新 API,先用手算已知例验证(正态 CDF(μ)=0.5、指数均值=1/λ);再画直方图与理论密度叠加(plt.hist(density=True) + plot(X.pdf))——视觉对齐是最快的参数理解器。

实例或案例

CLT 的 30 行验证:模拟 n=100 的标准正态均值 5000 次——均值直方图呈钟形、标准差 ≈0.1=1/√n、stats.probplot 上点贴直线——三大极限定理从背诵变成观察。

AB 检验完整跑一遍:stats.binomtest(58, 1000, 0.05).pvalue(精确二项)或两比例 z 检验;再画 Beta(1+k, 1+n−k) 后验密度对比(kp-022)——频率与贝叶斯两套答案同屏。

指数分布拟合实战:stats.expon.fit(wait_times, floc=0) 得 λ̂=1/x̄;QQ 图核对拟合质量、stats.kstest 验分布——kp-017/018 的联合实战。

常见误区

  • 误区一:"scale 当方差传"。scipy 的 norm/expon/t 全部用 scale=标准差(或率)——方差 64 传 64 会得到 σ=64 的分布(宽 8 倍)。
  • 误区二:"ttest 的 p 值当'组间有差'的概率"。p 值语义照 kp-021;且默认 equal_var=True(Student t)——方差不齐时应显式 Welch。
  • 误区三:"fit 不锁 loc 参数"。三参数拟合常把指数的 loc 拟成非零导致 λ 失真——已知支撑起点时 floc=0 固定。

与其他知识点的关系

  • kp-006~009/017:API 的概念底座。
  • kp-018/021/026:fit/检验/MC 的实现层。
  • kp-033:历史流派的工具化对照(贝叶斯用 PyMC/ArviZ 补全)。

自测题

  1. 用 scipy 验证"标准正态的 97.5% 分位数≈1.96"。

答:stats.norm.ppf(0.975) → 1.959964(kp-020 区间临界值的来源)。

  1. 二项检验:n=100、k=58、p₀=0.5,写双侧 p 值代码。

答:stats.binomtest(58, 100, 0.5).pvalue(或 2×(1−cdf(57)) 的近似式——注意精确二项优于正态近似)。

  1. 如何用代码验证 CLT 的 √n 律?

答:对 n∈{10,100,1000} 各模拟大量样本均值、算 std——应得 σ/√n(0.316、0.1、0.0316);对数坐标下斜率 −1/2。

延伸阅读

  • scipy.stats 官方教程(每个分布的 Methods 列表)。
  • 《Python for Data Analysis》(Wes McKinney)随机数章。
  • statsmodels 文档(更完整的检验与模型层)。