SciPy - 统计
SciPy - 统计模块 (scipy.stats)
Section titled “SciPy - 统计模块 (scipy.stats)”scipy.stats 模块是一个包含统计函数和概率分布的综合库。它提供了大量用于统计分析、假设检验(hypothesis testing)和处理随机变量(random variables)的工具。你可以在 Python 控制台中输入 help(scipy.stats) 或查阅 SciPy 官方文档,获取其功能的详细列表。
scipy.stats 中的概率分布(probability distributions)通过对象来表示。每个单变量分布(univariate distribution)是基础类的实例,分为连续型(continuous)或离散型(discrete):
| 类 | 描述 |
|---|---|
rv_continuous | 连续随机变量(continuous random variables)的通用基类,旨在通过继承定义具体的分布(例如,正态分布、均匀分布、卡方分布)。 |
rv_discrete | 离散随机变量(discrete random variables)的通用基类,旨在通过继承定义具体的分布(例如,二项分布、泊松分布、几何分布)。 |
rv_histogram | 生成由观测数据的直方图定义的分布。 |
处理连续随机变量:正态分布
Section titled “处理连续随机变量:正态分布”连续随机变量(continuous random variable)可以在给定范围内取任何值。正态分布(normal distribution),也称高斯分布(Gaussian distribution),是最常见的分布之一。在 scipy.stats 中,它由 norm 表示。关键字参数 loc 指定均值(mean,μ),scale 指定标准差(standard deviation,σ)。
norm 对象(以及其他分布对象)提供了以下方法:
.cdf(x): 累积分布函数 (Cumulative Distribution Function, CDF),$P(X \le x)$。.pdf(x): 概率密度函数 (Probability Density Function, PDF)(用于连续型),或.pmf(x): 概率质量函数 (Probability Mass Function, PMF)(用于离散型)。.ppf(q): 分位数函数 (Percent Point Function, PPF)(CDF 的逆函数),查找满足 $P(X \le x) = q$ 的 $x$。.rvs(size): 从分布中生成随机变量值(random variates,即样本)。.mean(),.std(),.var(): 计算分布的理论矩(theoretical moments)。
让我们计算标准正态分布(均值=0,标准差=1)在几个点上的 CDF:
from scipy.stats import normimport numpy as np
# Points at which to evaluate the CDFpoints = np.array([-2., -1., 0., 1., 2., 3.])
# Calculate CDF values (default norm is standard normal: loc=0, scale=1)cdf_values = norm.cdf(points)print(f"CDF values for points {points}:\n{cdf_values}")
# Example for a normal distribution with mean=5, std=2cdf_custom_norm = norm.cdf(points, loc=5, scale=2)print(f"\nCDF for N(5,2) at points {points}:\n{cdf_custom_norm}")输出将是:
CDF values for points [-2. -1. 0. 1. 2. 3.]:[0.02275013 0.15865525 0.5 0.84134475 0.97724987 0.9986501 ]
CDF for N(5,2) at points [-2. -1. 0. 1. 2. 3.]:[0.00023263 0.0013499 0.00620967 0.02275013 0.0668072 0.15865525]要查找分布的中位数(median,即第 50 百分位数),请使用分位数函数(PPF):
from scipy.stats import norm
median_std_normal = norm.ppf(0.5) # For standard normal (loc=0, scale=1)print(f"Median of standard normal distribution: {median_std_normal}")
median_custom_normal = norm.ppf(0.5, loc=10, scale=3)print(f"Median of N(10,3) distribution: {median_custom_normal}")输出:
Median of standard normal distribution: 0.0Median of N(10,3) distribution: 10.0要从分布生成随机样本,请使用带 size 参数的 rvs() 方法。为了获得可复现的结果,可以使用 np.random.seed() 设置随机种子,或者将 random_state 参数传递给 rvs()。
from scipy.stats import normimport numpy as np
np.random.seed(42) # For reproducibilityrandom_samples = norm.rvs(loc=0, scale=1, size=5)print(f"Random samples from N(0,1): {random_samples}")输出(由于设置了种子,结果将是一致的):
Random samples from N(0,1): [ 0.49671415 -0.1382643 0.64768854 1.52302986 -0.23415337]处理离散随机变量:二项分布
Section titled “处理离散随机变量:二项分布”二项分布(Binomial Distribution)模拟了在固定次数 n 的独立伯努利试验(Bernoulli trials)中成功的次数,每次试验的成功概率为 p。在 scipy.stats 中,它由 binom 表示。
from scipy.stats import binomimport numpy as np
# Parameters for binomial distributionn_trials = 10 # Number of trialsp_success = 0.3 # Probability of success in each trial
# Probability Mass Function (PMF): P(X=k)# Probability of exactly 5 successes in 10 trialsk_successes = 5pmf_value = binom.pmf(k_successes, n_trials, p_success)print(f"PMF P(X={k_successes} | n={n_trials}, p={p_success}): {pmf_value:.4f}")
# Cumulative Distribution Function (CDF): P(X <= k)# Probability of 5 or fewer successescdf_value = binom.cdf(k_successes, n_trials, p_success)print(f"CDF P(X<={k_successes} | n={n_trials}, p={p_success}): {cdf_value:.4f}")
# Generate random samplesnp.random.seed(123)random_binom_samples = binom.rvs(n_trials, p_success, size=8)print(f"Random samples from Binom({n_trials}, {p_success}): {random_binom_samples}")输出:
PMF P(X=5 | n=10, p=0.3): 0.1029CDF P(X<=5 | n=10, p=0.3): 0.9527Random samples from Binom(10, 0.3): [2 3 4 1 3 2 2 4]scipy.stats 还提供了对数据集(通常是 NumPy 数组)进行描述性统计(descriptive statistics)的函数。一些关键函数包括:
| 函数 | 描述 |
|---|---|
describe(array, ...) | 计算输入数组的几个描述性统计量(例如,均值、方差、偏度、峰度)。 |
gmean(array, ...) | 计算几何均值(geometric mean)。 |
hmean(array, ...) | 计算调和均值(harmonic mean)。 |
kurtosis(array, ...) | 计算峰度(kurtosis)(尾部厚度的度量)。默认使用 Fisher 定义(正态分布峰度为 0.0)。 |
mode(array, ...) | 返回众数(mode)(出现频率最高的值)及其计数。 |
skew(array, ...) | 计算偏度(skew)(分布不对称性的度量)。 |
iqr(array, ...) | 计算四分位距(Interquartile Range, IQR = 第 75 百分位数 - 第 25 百分位数)。 |
sem(array, ...) | 计算均值标准误(Standard Error of the Mean, SEM)。 |
zscore(array, ...) | 计算每个值相对于样本均值和标准差的 z 分数(z-score)。 |
使用 describe 和其他基本统计量的示例:
from scipy import statsimport numpy as np
data = np.array([1, 2, 2, 3, 3, 3, 4, 4, 5, 10])
print(f"Data: {data}")print(f"Mean: {np.mean(data):.2f}, Median: {np.median(data):.2f}")print(f"Standard Deviation: {np.std(data):.2f}, Variance: {np.var(data):.2f}")
# Using scipy.stats.describedescriptive_stats = stats.describe(data)print("\nDescriptive statistics from stats.describe():")print(f" Number of observations: {descriptive_stats.nobs}")print(f" Min and max: {descriptive_stats.minmax}")print(f" Mean: {descriptive_stats.mean:.2f}")print(f" Variance: {descriptive_stats.variance:.2f}")print(f" Skewness: {descriptive_stats.skewness:.2f}")print(f" Kurtosis: {descriptive_stats.kurtosis:.2f}")输出:
Data: [ 1 2 2 3 3 3 4 4 5 10]Mean: 3.70, Median: 3.00Standard Deviation: 2.26, Variance: 5.11
Descriptive statistics from stats.describe(): Number of observations: 10 Min and max: (1, 10) Mean: 3.70 Variance: 5.68 Skewness: 1.70 Kurtosis: 2.64注意:np.var 默认计算总体方差,而 stats.describe(以及 np.var(ddof=1))计算样本方差。这解释了在采用默认设置时,方差值可能存在的微小差异。
假设检验:T 检验
Section titled “假设检验:T 检验”T 检验(T-tests)用于判断两组均值之间,或样本均值与已知总体均值之间是否存在显著差异(significant difference)。理解其前提假设(例如,正态性、样本独立性、某些检验需要方差相等)至关重要。
ttest_1samp:单样本 T 检验
Section titled “ttest_1samp:单样本 T 检验”此检验检查单个样本的均值是否与已知或假设的总体均值(popmean)显著不同。这是一个双边检验(two-sided test),用于检验样本期望值(均值)等于给定总体均值的零假设(null hypothesis)。
from scipy import statsimport numpy as np
# Generate some sample data (e.g., from a normal distribution)np.random.seed(101)sample_data = stats.norm.rvs(loc=5.5, scale=1.5, size=30)
# Test if the sample mean is significantly different from 5.0population_mean_h0 = 5.0t_statistic, p_value = stats.ttest_1samp(sample_data, population_mean_h0)
print(f"Sample mean: {np.mean(sample_data):.2f}")print(f"T-statistic: {t_statistic:.3f}")print(f"P-value: {p_value:.3f}")
alpha = 0.05 # Significance levelif p_value < alpha: print(f"Reject null hypothesis: Sample mean is significantly different from {population_mean_h0}.")else: print(f"Fail to reject null hypothesis: No significant difference from {population_mean_h0}.")输出(由于随机抽样会有轻微差异,但种子使其可复现):
Sample mean: 5.60T-statistic: 2.166P-value: 0.038Reject null hypothesis: Sample mean is significantly different from 5.0.ttest_ind:独立双样本 T 检验
Section titled “ttest_ind:独立双样本 T 检验”此检验比较两个独立样本的均值。零假设是两个独立样本具有相同的平均值(期望值)。默认情况下,它假定总体方差相等(equal_var=True)。如果方差不相等,请设置 equal_var=False 以执行 Welch’s T 检验(Welch’s t-test)。
from scipy import statsimport numpy as np
np.random.seed(42)# Sample 1: e.g., scores from group Asample1 = stats.norm.rvs(loc=5, scale=2, size=100)# Sample 2: e.g., scores from group B (potentially different mean)sample2 = stats.norm.rvs(loc=5.8, scale=2, size=100)
# Perform t-test assuming equal variances (default)t_stat_eq_var, p_val_eq_var = stats.ttest_ind(sample1, sample2)print(f"Independent T-test (equal variances assumed):")print(f" T-statistic: {t_stat_eq_var:.3f}, P-value: {p_val_eq_var:.3f}")
# Perform Welch's t-test (variances not assumed equal)# Let's create another sample with different variance for illustrationsample3 = stats.norm.rvs(loc=5.8, scale=4, size=100) # Different scalet_stat_welch, p_val_welch = stats.ttest_ind(sample1, sample3, equal_var=False)print(f"\nWelch's T-test (unequal variances assumed for sample1 vs sample3):")print(f" T-statistic: {t_stat_welch:.3f}, P-value: {p_val_welch:.3f}")输出(取决于种子):
Independent T-test (equal variances assumed): T-statistic: -2.599, P-value: 0.010
Welch's T-test (unequal variances assumed for sample1 vs sample3): T-statistic: -1.872, P-value: 0.063解释 P 值:较小的 P 值(通常 < 0.05)表明如果在零假设为真的情况下,观测到的数据不太可能发生,因此导致拒绝零假设。较大的 P 值意味着数据与零假设一致。
scipy.stats 提供了更多分布(例如,uniform、poisson、chi2、f)和统计检验(例如,ANOVA 方差分析 (f_oneway)、Kolmogorov-Smirnov 检验 (kstest)、Shapiro-Wilk 正态性检验 (shapiro))。始终查阅文档以选择合适的检验并理解其前提假设。