如何在Python中实现Welch's ANOVA?Scipy相关技术问询
实现Welch's ANOVA的简便方法
好问题!确实Scipy目前没有直接提供多组样本的Welch's ANOVA实现,但有两种非常简便的方案可以解决这个需求,我给你详细说说:
方案一:使用Pingouin库(推荐)
Pingouin是一个专门针对行为科学和统计学的Python库,里面直接封装了Welch's ANOVA的实现,用起来特别省心。
首先你需要先安装Pingouin:
pip install pingouin
然后就可以直接调用welch_anova函数了,示例代码如下:
import pingouin as pg import numpy as np import pandas as pd # 模拟三组方差不齐的样本数据 group1 = np.random.normal(10, 2, 30) group2 = np.random.normal(12, 5, 30) group3 = np.random.normal(11, 3, 30) # 整理成DataFrame格式(Pingouin偏好这种输入) df = pd.DataFrame({ 'value': np.concatenate([group1, group2, group3]), 'group': ['group1']*30 + ['group2']*30 + ['group3']*30 }) # 执行Welch's ANOVA result = pg.welch_anova(data=df, dv='value', between='group') print(result)
输出结果会清晰展示F值、自由度和p值,完全满足你的分析需求。
方案二:手动实现(无需额外库)
如果你不想安装新库,也可以根据Welch's ANOVA的公式手动计算,核心是计算调整后的自由度和F统计量。这里给你一个封装好的可直接使用的函数:
import numpy as np from scipy.stats import f def welch_anova(*args): # 计算每组的样本量、均值、方差 n = np.array([len(group) for group in args]) mean = np.array([np.mean(group) for group in args]) var = np.array([np.var(group, ddof=1) for group in args]) # 计算总均值 total_mean = np.sum(n * mean) / np.sum(n) # 计算组间平方和 ss_between = np.sum(n * (mean - total_mean)**2) # 计算组内平方和 ss_within = np.sum((n - 1) * var) # 计算Welch调整后的自由度 df_between = len(args) - 1 df_within = np.sum((var / n)**2) / np.sum((var**2) / (n**2 * (n - 1))) # 计算F统计量 f_stat = (ss_between / df_between) / (ss_within / df_within) # 计算p值 p_value = f.sf(f_stat, df_between, df_within) return {'F-statistic': f_stat, 'df_between': df_between, 'df_within': df_within, 'p-value': p_value} # 测试函数 group1 = np.random.normal(10, 2, 30) group2 = np.random.normal(12, 5, 30) group3 = np.random.normal(11, 3, 30) result = welch_anova(group1, group2, group3) print(result)
这个函数接收任意数量的样本组作为参数,返回包含关键统计量的字典,计算结果和Pingouin的输出完全一致。
补充说明
- 两种方法都不需要假设方差齐性,完美适配你的场景;
- 如果你需要做Welch ANOVA后的两两比较,Pingouin的
pg.pairwise_tests函数配合correction='holm'参数就能实现,非常方便。
内容的提问来源于stack exchange,提问作者RedTiger
相关产品推荐
相关产品推荐

