基础类 (Base Classes)

统计检验模块的基础类定义了通用的数据结构和接口,为所有统计检验方法提供一致的返回格式和操作方式。

class TestResult

所有统计检验方法的统一返回对象,包含检验的完整结果信息。

属性:

test_name: str

检验方法的名称

statistic: float

检验统计量的值

p_value: float

检验的p值

reject_null: bool

是否拒绝原假设(True表示拒绝原假设)

critical_value: float | None

临界值(如果适用)

confidence_interval: Tuple[float, float] | None

置信区间(如果适用)

effect_size: float | None

效应量(如果适用)

additional_info: Dict

额外的检验相关信息

示例:

>>> from pywayne.statistics import NormalityTests
>>> import numpy as np
>>>
>>> nt = NormalityTests()
>>> data = np.random.normal(0, 1, 100)
>>> result = nt.shapiro_wilk(data)
>>>
>>> print(f"检验名称: {result.test_name}")
>>> print(f"统计量: {result.statistic:.4f}")
>>> print(f"p值: {result.p_value:.4f}")
>>> print(f"拒绝原假设: {result.reject_null}")
class BaseStatisticalTest

所有统计检验类的基类,提供通用的方法和属性。

方法:

get_class_description() str

返回检验类的详细描述信息。

返回:

  • str: 包含类的功能描述、适用场景等信息

list_tests() List[str]

返回该类中所有可用的检验方法名称。

返回:

  • List[str]: 检验方法名称列表

示例:

>>> from pywayne.statistics import NormalityTests
>>>
>>> nt = NormalityTests()
>>> print(nt.get_class_description())
>>> print("可用方法:", nt.list_tests())

测试结果解释指南

p值解释

p值是假设检验中最重要的统计量,表示在原假设为真的情况下,观察到当前结果或更极端结果的概率。

解释原则:

  1. 显著性水平: 通常设定α = 0.05

  2. 判断规则: - p < α: 拒绝原假设(reject_null = True) - p ≥ α: 不能拒绝原假设(reject_null = False)

常见显著性水平:

  • 0.05: 标准显著性水平,5%的第一类错误率

  • 0.01: 严格显著性水平,1%的第一类错误率

  • 0.10: 宽松显著性水平,10%的第一类错误率

注意事项:

  • p值不是原假设为真的概率

  • p值不表示效应量的大小

  • 多重比较时需要校正

效应量

效应量衡量差异或关联的实际大小,是对统计显著性的重要补充。

常见效应量:

  1. Cohen’s d: 标准化的均值差异 - 小效应: d ≈ 0.2 - 中等效应: d ≈ 0.5 - 大效应: d ≈ 0.8

  2. 相关系数: 线性关联强度 - 弱相关: r < 0.3 - 中等相关: 0.3 ≤ r < 0.7 - 强相关: r ≥ 0.7

  3. eta-squared (η²): 方差解释比例 - 小效应: η² ≈ 0.01 - 中等效应: η² ≈ 0.06 - 大效应: η² ≈ 0.14

置信区间

置信区间提供参数估计的不确定性范围,比点估计更具信息量。

解释要点:

  1. 含义: 在重复抽样中,该区间包含真实参数值的概率

  2. 宽度: 反映估计的精确性

  3. 应用: 参数估计和假设检验的结合

示例:

>>> # 均值差异的95%置信区间
>>> if result.confidence_interval:
...     lower, upper = result.confidence_interval
...     print(f"95%置信区间: [{lower:.3f}, {upper:.3f}]")
...     if 0 not in result.confidence_interval:
...         print("差异显著(置信区间不包含0)")

错误类型与功效

第一类错误(α错误)

错误地拒绝了真实的原假设。

特点:

  • 概率由显著性水平α控制

  • 也称为”假阳性”错误

  • 通过设定较小的α值来控制

第二类错误(β错误)

错误地接受了错误的原假设。

特点:

  • 概率记为β

  • 也称为”假阴性”错误

  • 与样本量、效应量、α水平相关

统计功效

统计功效 = 1 - β,表示正确拒绝错误原假设的概率。

影响因素:

  1. 样本量: 样本越大,功效越高

  2. 效应量: 效应越大,功效越高

  3. 显著性水平: α越大,功效越高

  4. 测量精度: 误差越小,功效越高

功效分析:

>>> import numpy as np
>>> from scipy import stats
>>>
>>> # 计算所需样本量
>>> effect_size = 0.5  # Cohen's d
>>> alpha = 0.05
>>> power = 0.8
>>>
>>> # 使用功效分析确定样本量
>>> # (需要额外的统计包如statsmodels.stats.power)

多重比较校正

当进行多次假设检验时,需要调整显著性水平以控制整体错误率。

Bonferroni校正

最保守的校正方法,将显著性水平除以检验次数。

公式: α_corrected = α / m

特点: - 严格控制家族错误率(FWER) - 可能过于保守,降低统计功效

示例:

>>> # 进行5次检验的Bonferroni校正
>>> alpha = 0.05
>>> num_tests = 5
>>> corrected_alpha = alpha / num_tests
>>> print(f"校正后显著性水平: {corrected_alpha:.3f}")

Benjamini-Hochberg校正

控制错误发现率(FDR)的方法,相对不那么保守。

步骤: 1. 将p值从小到大排序 2. 计算每个p值的BH临界值 3. 从最大的p值开始,找到第一个小于临界值的p值

示例:

>>> import numpy as np
>>> from statsmodels.stats.multitest import multipletests
>>>
>>> # 多个p值的FDR校正
>>> p_values = [0.01, 0.05, 0.15, 0.03, 0.08]
>>> reject, p_corrected, alpha_sidak, alpha_bonf = multipletests(
...     p_values, alpha=0.05, method='fdr_bh')
>>> print("原始p值:", p_values)
>>> print("校正后p值:", p_corrected)
>>> print("拒绝原假设:", reject)

实际应用建议

结果报告

完整的统计检验结果应包含:

  1. 描述性统计: 样本量、均值、标准差等

  2. 检验统计量: 具体数值

  3. p值: 准确到合适的小数位

  4. 效应量: 及其置信区间

  5. 结论: 基于统计和实际意义

报告示例:

>>> def report_test_result(result, sample_stats=None):
...     print(f"统计检验结果报告")
...     print(f"=" * 30)
...     print(f"检验方法: {result.test_name}")
...     if sample_stats:
...         print(f"样本统计: {sample_stats}")
...     print(f"检验统计量: {result.statistic:.4f}")
...     print(f"p值: {result.p_value:.4f}")
...     if result.effect_size:
...         print(f"效应量: {result.effect_size:.4f}")
...     if result.confidence_interval:
...         print(f"95%置信区间: {result.confidence_interval}")
...     print(f"统计结论: {'拒绝原假设' if result.reject_null else '不能拒绝原假设'}")

假设检验的限制

  1. 假设依赖: 结果的有效性依赖于假设的满足

  2. 样本代表性: 样本应代表感兴趣的总体

  3. 测量误差: 测量精度影响检验结果

  4. 因果推断: 相关不等于因果

最佳实践

  1. 事前计划: - 明确研究假设和检验方法 - 进行功效分析确定样本量 - 预设显著性水平

  2. 数据探索: - 检验前进行描述性分析 - 验证假设检验的前提条件 - 识别异常值和缺失值

  3. 结果解释: - 结合统计和实际意义 - 考虑效应量和置信区间 - 避免过度解释非显著结果

  4. 重现性: - 报告完整的统计信息 - 提供数据和代码 - 描述分析过程和决策

代码示例:完整分析流程

from pywayne.statistics import NormalityTests, LocationTests
import numpy as np

def complete_analysis_example():
    """完整的统计分析示例"""

    # 1. 数据准备
    np.random.seed(42)
    group_a = np.random.normal(100, 15, 50)  # 对照组
    group_b = np.random.normal(110, 15, 50)  # 实验组

    print("统计分析完整流程示例")
    print("=" * 50)

    # 2. 描述性统计
    print("\n1. 描述性统计:")
    print(f"对照组: n={len(group_a)}, 均值={np.mean(group_a):.2f}, 标准差={np.std(group_a, ddof=1):.2f}")
    print(f"实验组: n={len(group_b)}, 均值={np.mean(group_b):.2f}, 标准差={np.std(group_b, ddof=1):.2f}")

    # 3. 假设检验前提条件检查
    print("\n2. 正态性检验:")
    nt = NormalityTests()

    norm_a = nt.shapiro_wilk(group_a)
    norm_b = nt.shapiro_wilk(group_b)

    print(f"对照组正态性: p={norm_a.p_value:.3f}, 正态={not norm_a.reject_null}")
    print(f"实验组正态性: p={norm_b.p_value:.3f}, 正态={not norm_b.reject_null}")

    # 4. 选择适当的检验方法
    lt = LocationTests()

    if not norm_a.reject_null and not norm_b.reject_null:
        # 数据正态,使用t检验
        result = lt.two_sample_ttest(group_a, group_b)
        test_type = "两样本t检验"
    else:
        # 数据非正态,使用非参数检验
        result = lt.mann_whitney_u(group_a, group_b)
        test_type = "Mann-Whitney U检验"

    # 5. 结果报告
    print(f"\n3. {test_type}结果:")
    print(f"统计量: {result.statistic:.4f}")
    print(f"p值: {result.p_value:.4f}")
    print(f"显著性: {'是' if result.reject_null else '否'}")

    # 6. 效应量计算
    if test_type == "两样本t检验":
        # Cohen's d
        pooled_std = np.sqrt(((len(group_a)-1)*np.var(group_a, ddof=1) +
                            (len(group_b)-1)*np.var(group_b, ddof=1)) /
                            (len(group_a)+len(group_b)-2))
        cohens_d = (np.mean(group_b) - np.mean(group_a)) / pooled_std
        print(f"Cohen's d: {cohens_d:.3f}")

    # 7. 实际意义解释
    print(f"\n4. 结论:")
    if result.reject_null:
        print("统计学意义: 两组存在显著差异")
        print("实际意义: 需要结合专业知识判断差异的实际重要性")
    else:
        print("统计学意义: 两组无显著差异")
        print("注意: 这不等于两组完全相同,可能是样本量不足或效应量较小")

# 运行示例
if __name__ == "__main__":
    complete_analysis_example()

该示例展示了从数据准备到结果解释的完整统计分析流程,体现了统计检验模块中基础类的设计理念和实际应用方式。