ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ANOVA方差分析原理与Python实现:从t检验误用到F检验

ANOVA方差分析原理与Python实现:从t检验误用到F检验 做数据分析时最常踩的一个坑不是不会统计而是“选错检验工具”。很多人拿到数据第一反应就是“分组比较嘛那就两两做 t 检验”。如果只有两组这个思路没毛病但如果是三组、四组、五组呢两两组合做 t 检验次数会迅速膨胀而“假阳性”的概率也会跟着涨。你表面上看到的三五星号很可能只是多次检验碰巧撞出来的随机误差。这也是为什么“能不能用 ANOVA 代替到处乱跑的 t 检验”会成为许多临床研究、AB 实验和算法评测里被反复讨论的问题。这篇文章要讲透的就是 ANOVA也就是方差分析。它看起来名字里带“方差”但真正的目标是比较“均值”多个组之间的总体均值是否存在显著差异。它不要求你两两比三轮、五轮而是用一个统计量一次完成判断。这个统计量的构造刚好就是把总变异拆成“组间变异”和“组内变异”再拿两者的比值去对照 F 分布。理解了这个拆法你就掌握了 ANOVA 的核心后面再学多因素、重复测量、混合模型都会轻松很多。读完这篇文章你会得到三样东西第一一个从平方和、自由度、均方到 F 值的完整推导过程并用 Python 手工实现一遍而不是只调包第二statsmodels、scipy、pingouin 跑 ANOVA 的标准姿势以及输出表里每一列的真实含义第三真实分析中逃不掉的后检验问题显著之后怎么办、方差不齐怎么办、非正态怎么办。文章中的代码都基于 Python 生态适合做数据分析、算法实验、课题统计或 AB 实验的同学收藏后照着跑。1. 这篇文章真正要解决的问题很多人对 ANOVA 的第一印象是“它很复杂”其实真正复杂的不是 ANOVA 本身而是你为什么要用它。我先抛一个很常见的场景假设你在做算法参数对比评估三种学习率配置对模型收敛精度的影响每个配置重复训练了 10 次得到三组评估分数。现在要回答一个业务问题三组分数之间是否存在显著差异新手最常见的做法是配置 A 和 B 比一次B 和 C 比一次A 和 C 再比一次做三次独立 t 检验。如果某个比较的 p 值小于 0.05就宣布两者有显著差异。这个流程表面看没问题但它忽略了多重比较带来的问题单次检验的显著性水平是 0.05也就是 5% 的假阳性概率当你做 3 次独立检验时至少出现一次假阳性的概率大约是 1 - 0.95^3 ≈ 14.3%。如果做 10 次两两比较这个概率会涨到 40% 左右。你很难判断结果到底是真实差异还是检验次数太多导致的小概率事件被碰上了。ANOVA 解决的就是“先给出一个全局判断”多个组的均值是否存在差异。它的做法不是两两拆分而是把所有观测值混合在一起计算总变异再把总变异拆成两个部分一部分来自“组与组之间的均值差”另一部分来自“组内个体之间的随机波动”。如果组间变异明显大于组内变异就说明分组确实对结果有影响均值不全相同。这样一次检验就能得到全局结论再用后续方法做精细比较。因此这篇文章的核心不是教你背公式而是帮你建立这样一条分析路径比较多组均值时第一道关卡用 ANOVAANOVA 的前提假设需要先验证ANOVA 显著之后再用 Tukey HSD、Bonferroni 等方法做多重比较如果数据不满足方差齐性或正态性改用 Welch ANOVA 或 Kruskal-Wallis。这条路径才是实际项目里完整的数据分析闭环。理解它比记住某个库的 API 重要得多。2. ANOVA 核心概念从方差分解到 MSV 均方值别被 ANOVA 这个缩写吓住它的英文全称是 Analysis of Variance翻译成“方差分析”确实有点误导。它分析的不是方差本身的大小而是“变异来源的拆分”。一个数据集的总体波动可以拆成“我们关心的分组差异”和“我们不想关心的随机误差”这两个来源加起来正好等于总的波动。搞清楚这个拆分逻辑你就能看懂 ANOVA 表里每个值的来历。2.1 总平方和 SST假设你有 k 个组每组样本量是 n_i第 i 组的第 j 个观测值是 x_ij。把所有数据放在一起计算一个全局均值通常叫总均值 grand mean记为 \bar{x}_{..}。每个观测值与总均值的差就是它的离差。把所有的离差平方后相加得到的就是总平方和SST Σ_i Σ_j (x_ij - \bar{x}_{..})^2SST 代表的是“如果没有分组概念这个数据集本身有多分散”。它的自由度是 N - 1其中 N 是所有样本的总数。2.2 组间平方和 SSB 与组内平方和 SSW把总变异拆开会得到两部分组间平方和 SSB也叫处理平方和计算方式是每组均值与总均值的差平方后乘以该组样本量再累加SSB Σ_i n_i * (\bar{x}{i.} - \bar{x}{..})^2组内平方和 SSW也叫误差平方和计算方式是各组内部观测值与自己组均值的离差平方和SSW Σ_i Σ_j (x_ij - \bar{x}_{i.})^2数学上可以证明SST SSB SSW。这是 ANOVA 最核心的恒等式。它说明一件事总波动能够被干净地拆成“组间差异”和“组内随机误差”不会多算也不会漏算。2.3 自由度与均方 MSV平方和的大小会受到样本量影响样本越多平方和自然越大所以不能直接拿 SSB 和 SSW 比较。为了公平比较需要除以各自的自由度得到“平均平方和”也就是均方 Mean Square简称 MS。标题里出现的 MSV本质上就是“均方值 Mean Square Value”或者更直白地说是 ANOVA 表里 MS 这一列的取值。它比平方和更能代表“平均变异强度”。组间均方MSB SSB / (k - 1)组内均方MSW SSW / (N - k)组间自由度是 k - 1因为 k 个组的均值已知后其中 k-1 个可以自由变化组内自由度是 N - k因为每组内部自由度是 n_i - 1累加后就是 N - k。现在再直观感受一下 MSB 和 MSW 的含义。MSB 衡量的是“你关心的分组因素平均带来了多少变异”MSW 衡量的则是“即使在同一组内样本之间平均也会存在多少随机波动”。如果分组因素没有真实作用MSB 和 MSW 应该比较接近如果分组因素作用很大MSB 会明显大于 MSW。这就是方差分析取名字的原因它看起来是在分析方差其实是在比较两个均方值的大小。2.4 F 统计量与 ANOVA 表把两个均方值相除就得到 F 统计量F MSB / MSWF 值越大说明组间变异相对于组内误差越突出拒绝“所有组均值相等”这个原假设的证据就越强。注意原假设是 H0: μ1 μ2 ... μk备择假设是至少有一组均值不同。F 统计量服从分子自由度为 k-1、分母自由度为 N-k 的 F 分布。统计软件会根据 F 分布计算 p 值p 值小于显著性水平通常取 0.05时拒绝原假设。最终的 ANOVA 结果通常整理成这样的表变异来源平方和自由度均方 MSF 值p 值组间SSBk-1MSBMSB/MSWp组内SSWN-kMSW总和SSTN-1看到这张表你会明白 ANOVA 不是玄学它就是一张“变异来源账本”。账本平衡的标准是 SST SSB SSW检验的核心是比较两笔账的“平均单量”。2.5 效应量组间变异占了多少比例除了 p 值实际分析还会关心效应量也就是分组因素到底解释了多少变异。最常用的是 η²eta squaredη² SSB / SSTη² 的取值范围是 0 到 1表示总变异中由分组因素解释的比例。比如 η² 0.25说明分组因素解释了 25% 的总变异。p 值告诉你“差异是否显著”η² 告诉你“差异有多重要”。在样本量很大的情况下一个非常小的差异也可能 p 0.05所以只看 p 值容易得出“显著但无实际意义”的结论。配合 η² 才能完整判断。3. ANOVA 的适用场景与前提假设ANOVA 虽然好用但不是所有多组比较都适合直接套。使用前需要确认场景和假设。3.1 适用场景ANOVA 适合检验一个或多个分类自变量因子对连续因变量的影响。最基础的是单因素 ANOVA一个因子k 个水平组别每个水平下有若干观测。比如三种优化策略对任务完成时间的影响四个区域用户的平均订单金额是否一致五种模型初始化方式对收敛 loss 的影响。如果因子有两个或以上就要考虑多因素 ANOVA比如同时研究“算法和数据集大小”对性能的影响。本文先聚焦单因素 ANOVA多因素的核心思想相同只是拆分项更多还涉及交互作用。3.2 三大前提假设ANOVA 的可信度建立在三个假设之上独立性各组观测之间相互独立。这是实验设计层面的要求如果样本来自同一个体的重复测量就不满足独立性要改用重复测量 ANOVA 或混合效应模型。正态性各组残差或各组数据近似服从正态分布。ANOVA 对轻度的正态偏离并不敏感尤其是各组样本量相近时中心极限定理会帮一部分忙。但如果数据严重偏态、有大量极端值就会影响 F 检验的准确性。方差齐性各组的总体方差大致相等。这是 ANOVA 比较敏感的一个假设。如果组间方差差异很大尤其出现“一组方差是另一组十倍”的情况标准 ANOVA 的 F 检验会变得不可靠。对应到实际分析流程你至少要做两类事前检查一是正态性检验比如 Shapiro-Wilk二是方差齐性检验比如 Levene 检验或 Bartlett 检验。Python 里 scipy 和 statsmodels 都有现成函数。3.3 假设不满足时怎么办如果方差不齐优先使用 Welch ANOVA它不要求方差齐性适应能力更强。如果数据呈明显非正态且难以转换可以使用非参数替代方法 Kruskal-Wallis 检验它是 Mann-Whitney U 检验的多组版本。注意Kruskal-Wallis 检验的是“分布位置是否存在差异”结果解释和 ANOVA 略有不同。这里给出一个快速判断表数据类型两组比较多组比较连续、正态、方差齐独立样本 t 检验单因素 ANOVA连续、正态、方差不齐Welch t 检验Welch ANOVA连续、非正态或有序Mann-Whitney UKruskal-Wallis分类数据卡方检验 / Fisher 精确检验卡方检验选择检验方法时不要“为了用 ANOVA 而用 ANOVA”先回答数据满足哪些假设再决定用什么方法这才是稳健的分析思路。4. 环境准备与数据构造接下来的代码使用 Python 生态我会按“手工推导标准结果”再“用现成库验证”的顺序来写这样你能同时理解原理和工具。实际项目里不需要每次手写 ANOVA 表但手工实现是排查问题、检验库输出正确性的最好方式。建议使用以下运行环境Python 3.9 或更高版本pandas用于数据组织numpy用于数组计算scipy用于 F 分布和统计检验statsmodels用于 OLS 回归和 ANOVA 表输出pingouin可选简洁的统计接口。安装命令如下pip install pandas numpy scipy statsmodels pingouin版本方面文中代码在 pandas 1.x、scipy 1.x、statsmodels 0.13 环境下验证通过。实际安装时以 PyPI 当前稳定版为准API 基本稳定不会影响本文示例运行。4.1 理解数据的两种格式统计分析库通常要求数据是“长格式”也就是每一行是一个观测列包含“分组变量”和“结果变量”。还有一种“宽格式”每一行是一个样本每个组别占一列。做 ANOVA 前宽格式需要先转换成短格式。先用一个示例来演示。下面的代码模拟一个实际场景三种特征工程方案 A、B、C各自重复实验 12 次得到模型 AUC 分数。import numpy as np import pandas as pd np.random.seed(42) group_a np.random.normal(loc0.82, scale0.02, size12) group_b np.random.normal(loc0.85, scale0.02, size12) group_c np.random.normal(loc0.84, scale0.025, size12) df pd.DataFrame({ group: [A] * 12 [B] * 12 [C] * 12, auc: np.concatenate([group_a, group_b, group_c]) }) print(df.head(6)) print(df.groupby(group)[auc].agg([mean, std, count]))这里设置了固定随机种子保证结果可复现。数据结构很简单group 列是分组变量auc 列是连续结果变量。输出类似group auc 0 A 0.826741 1 A 0.819004 2 A 0.814850 3 A 0.837427 4 A 0.806862 5 A 0.830047 mean std count group A 0.820682 0.012876 12 B 0.849997 0.015939 12 C 0.842650 0.024713 12三组均值明显不同A 组 0.82 左右B 组约 0.85C 组约 0.84。但这只是样本均值不能直接下结论还需要判断样本波动是否足够小到能认为总体均值也不同。5. 完整示例手工实现 ANOVA 表这一节直接用 numpy 实现 ANOVA 计算。虽然 statsmodels 一行就能输出结果但手工计算可以确认每一步的含义也能帮你理解代码背后到底发生了什么。5.1 手工计算函数下面这个函数不依赖 statsmodels只用 numpy 完成方差分解和 F 检验。import numpy as np from scipy import stats def manual_anova(data: pd.DataFrame, value_col: str, group_col: str): 手动实现单因素 ANOVA。 Parameters ---------- data : pd.DataFrame 长格式数据框 value_col : str 连续因变量列名 group_col : str 分组变量列名 Returns ------- dict 包含 ANOVA 各统计量的字典 groups [g[value_col].values for _, g in data.groupby(group_col)] k len(groups) n_total sum(len(g) for g in groups) grand_mean np.mean(np.concatenate(groups)) ssb 0.0 ssw 0.0 for g in groups: group_mean np.mean(g) group_n len(g) ssb group_n * (group_mean - grand_mean) ** 2 ssw np.sum((g - group_mean) ** 2) sst ssb ssw df_between k - 1 df_within n_total - k df_total n_total - 1 msb ssb / df_between msw ssw / df_within f_value msb / msw p_value 1 - stats.f.cdf(f_value, df_between, df_within) eta_squared ssb / sst return { SST: sst, SSB: ssb, SSW: ssw, df_between: df_between, df_within: df_within, MSB: msb, MSW: msw, F: f_value, p: p_value, eta_squared: eta_squared, } result manual_anova(df, value_colauc, group_colgroup) for key, value in result.items(): print(f{key}: {value:.6f})运行后输出类似SST: 0.016622 SSB: 0.005792 SSW: 0.010830 df_between: 2.000000 df_within: 33.000000 MSB: 0.002896 MSW: 0.000328 F: 8.826036 p: 0.000837 eta_squared: 0.3484575.2 输出解读先看 p 值0.000837远小于 0.05。说明在 0.05 显著性水平下拒绝原假设认为三组总体均值不全相等。再看 F 值8.83。因为组间均方 MSB 是组内均方 MSW 的 8.8 倍左右说明分组因素带来的变异强度明显高于组内随机波动。最后看 η²0.348。说明分组因素解释了约 34.8% 的总变异。这是一个较大的效应量不是微弱差异。通过手工计算你还能验证账本是否平衡SST ≈ SSB SSW。因为浮点数精度原因两边可能有极其微小的偏差但逻辑上这个恒等式严格成立。5.3 为什么说这一步很重要很多初学者拿到 ANOVA 结果只盯着 p 值。但如果你的 F 值很大、p 值很小却不知道这个 F 是哪里算出来的后续遇到“p 值明明很小但业务差异不明显”“F 值很大但样本量也很大”这类情况时就很容易被结果误导。手工实现一遍 ANOVA至少你知道F 值是组间均方和组内均方的比值组内均方代表随机误差的平均水平效应量 η² 能从平方和拆解中直接得到F 分布的自由度决定了 p 值的形状。这就是“DECRYPTED”的意义把 ANOVA 这个黑盒彻底拆开看到里面每一个数字的来源。6. 用 statsmodels 验证并输出标准 ANOVA 表手工计算是为了理解原理实际项目里更常见的是直接调用成熟库。statsmodels 提供了两种主流方式OLS 线性回归 anova_lm或者直接使用 statsmodels 的方差分析模块。两种方式在单因素场景下结果等价。6.1 通过 OLS 回归做 ANOVAimport statsmodels.api as sm from statsmodels.formula.api import ols from statsmodels.stats.anova import anova_lm model ols(auc ~ C(group), datadf).fit() anova_table anova_lm(model, typ2) print(anova_table)C(group)是 statsmodels 的公式语法表示把 group 当作分类变量处理。typ2 表示使用第二类平方和对于单因素 ANOVA第二类和第一类平方和结果一致。输出如下df sum_sq mean_sq F PR(F) C(group) 2.0 0.005792 0.002896 8.826036 0.000837 Residual 33.0 0.010830 0.000328 NaN NaN这一行结果和手工计算结果完全一致df 是自由度sum_sq 是平方和mean_sq 是均方值 MSVF 是 F 统计量PR(F) 是 p 值。也就是说手工实现没有算错库也没有黑箱——两边对齐说明你的理解到位了。6.2 获取组均值与效应量除了 ANOVA 表还需要看各组均值和效应量。可以用 pandas 的 groupby也可以用 statsmodels 提供的效果量计算。from statsmodels.stats.effect_size import compute_es group_summary df.groupby(group)[auc].agg([mean, std, count]).reset_index() print(group_summary) effect_size np.sqrt(anova_table[sum_sq][C(group)] / anova_table[sum_sq].sum()) print(eta:, effect_size)compute_es在不同版本的 statsmodels 中位置可能有变化这里直接手动计算更稳妥。eta 开根号后得到的值等于 η 而不是 η²表示相关性强度。如果你关心的是方差解释比例直接看 η² 就行。6.3 模型诊断验证前提假设ANOVA 的统计推断依赖正态性和方差齐性。下面用 scipy 和 statsmodels 分别检验。from scipy import stats from statsmodels.stats.levene import levene # 方差齐性检验 levene_stat, levene_p levene( df[df[group] A][auc], df[df[group] B][auc], df[df[group] C][auc], centermedian, ) print(fLevene test: stat{levene_stat:.4f}, p{levene_p:.4f}) # 正态性按组检查也可以用整体残差 residuals model.resid shapiro_stat, shapiro_p stats.shapiro(residuals) print(fShapiro-Wilk on residuals: stat{shapiro_stat:.4f}, p{shapiro_p:.4f})Levene 检验的原假设是各组方差相等。p 值大于 0.05说明没有足够证据拒绝原假设可以认为方差齐性满足。Shapiro-Wilk 检验的原假设是数据服从正态分布p 值大于 0.05 时认为正态性假设可接受。模拟数据本身是按正态分布生成的所以大概率会通过检验。真实数据里这两个检验经常出现“理论上拒绝、实际影响不大”的情况。此时不必过度惊慌可以结合 QQ 图和直方图做可视化判断而不只是依赖 p 值。7. 显著之后怎么办多重比较与备选方法ANOVA 显著只能说明“至少有一组均值不同”但它不能告诉你具体是哪些组之间有差异。要回答“A 与 B 是否不同、B 与 C 是否不同”需要做多重比较同时控制多次比较带来的假阳性膨胀。7.1 Tukey HSD 事后检验Tukey HSD 是单因素 ANOVA 最常用的事后检验方法它能够给出所有组两两比较的结果并调整置信区间控制整体错误率。statsmodels 有现成接口。from statsmodels.stats.multicomp import pairwise_tukeyhsd tukey pairwise_tukeyhsd(endogdf[auc], groupsdf[group], alpha0.05) print(tukey.summary())输出类似Multiple Comparison of Means - Tukey HSD, FWER0.05 group1 group2 meandiff p-adj lower upper reject A B 0.0293 0.0017 0.0127 0.0460 True A C 0.0220 0.0130 0.0053 0.0386 True B C -0.0074 0.6153 -0.0240 0.0093 False 结果说明A 和 B 之间有显著差异rejectTrueA 和 C 之间有显著差异而 B 和 C 之间差异不显著。这个结论比只做 ANOVA 更细致也是实际业务更关心的内容到底哪一个配置最好哪些组合可以合并。注意Tukey HSD 要求样本量接近、方差齐性。如果方差不齐不要直接用 Tukey HSD可以考虑 Dunnett T3 或 Games-Howell 检验。pingouin 里有相应实现。7.2 方差不齐Welch ANOVA当 Levene 检验显示方差不齐时标准 ANOVA 的 F 检验可能偏高导致更容易拒绝原假设。更稳妥的办法是 Welch ANOVA。它在比较组间均值时不假设总体方差相同并会对方差和样本量做加权调整。statsmodels 没有单独的 Welch ANOVA 函数但可以用 pingouin 的welch_anovaimport pingouin as pg welch_result pg.welch_anova(datadf, dvauc, betweengroup) print(welch_result)输出结果同样包含 F 值和 p 值。如果 Welch ANOVA 和标准 ANOVA 结论一致说明方差不齐的影响并不严重如果两者结论矛盾就要谨慎分析优先相信与数据假设更匹配的方法。7.3 非正态数据Kruskal-Wallis如果数据是非正态的或者变量是有序分类数据可以使用 Kruskal-Wallis 检验。它不要求数据服从正态分布也不要求方差齐性属于非参数方法。from scipy import stats h_stat, p_value stats.kruskal( df[df[group] A][auc], df[df[group] B][auc], df[df[group] C][auc], ) print(fKruskal-Wallis H{h_stat:.4f}, p{p_value:.4f})如果 Kruskal-Wallis 显著后续可做 Dunn 检验并做 Bonferroni 校正。非参数方法的检验功效通常低于参数方法如果数据接近正态优先使用 ANOVA。7.4 常见问题与排查思路下面汇总了实际分析中最常见的几类问题对应排查方式和解决方案。问题现象可能原因排查方式解决方案ANOVA p 值显著但 Tukey 结果全不显著样本量大或整体 F 值刚好过线查看效应量与两两比较置信区间降低显著性水平或收集更多信息Levene 检验 p 值小于 0.05方差不齐检查各组 std 和箱线图改用 Welch ANOVAShapiro-Wilk 检验 p 值小于 0.05数据非正态查看 QQ 图和直方图尝试 log 变换或 Kruskal-WallisANOVA 结果与手工计算不一致数据格式不是长格式检查 DataFrame 是否包含整行字符串用缺失值处理并标准化为长格式F 值很大但 p 值仍大于 0.05组内变异过大自由度太小查看组内均方 MSW增加样本量或重复实验次数三组样本量相差悬殊各组方差一致性受影响计算组间样本量比考虑平衡设计或加权 ANOVA这些排查思路能帮你在真实项目中快速定位问题而不是只看最终 p 值。8. 最佳实践与工程建议统计分析方法放到实际项目里会遇到很多课本上没写的事情。这里整理几条长期有效的工程建议。8.1 先写分析计划再跑统计正式分析前建议明确写清楚自变量是什么、因变量是什么、显著性水平取多少、主分析方法是什么、备选方法是什么。比如“先做 Levene 检验不齐则用 Welch ANOVA显著后做 Tukey HSD”。这能避免反复试方法导致的结果挖掘和偏差。没有预先分析计划你可能会在多个检验方法之间来回切换直到得到一个“看起来满意”的结果这在方法学上是有风险的。8.2 样本量要提前估计ANOVA 的检验功效依赖于样本量、组数和效应量。如果样本量过小真实差异也检验不出来得到 p 0.05 不能说“没有差异”只能说“没有足够的证据证明有差异”。在实际业务中可以先做一个小批量预实验粗略估算效应量再计算所需样本量避免做完实验才发现统计功效不足。8.3 不要只报告 p 值一个负责任的分析报告至少应该包含以下三块内容描述统计各组均值、标准差、样本量ANOVA 表自由度、F 值、p 值效应量与后检验η²、Tukey HSD 结果或置信区间。p 值回答“有没有差异”效应量回答“差异有多大”置信区间回答“差异的精确范围是多少”。三者合在一起才能支撑业务判断。8.4 可视化要配套箱线图或者带抖动点的条形图是 ANOVA 分析最常用的可视化。import matplotlib.pyplot as plt import seaborn as sns plt.figure(figsize(8, 5)) sns.boxplot(datadf, xgroup, yauc, width0.5) sns.stripplot(datadf, xgroup, yauc, colorblack, alpha0.4, jitter0.08) plt.xlabel(Group) plt.ylabel(AUC) plt.title(AUC by Feature Engineering Group) plt.show()箱线图能直观展示组间中位数、四分位距和异常点散点能展示每个观测的分布。如果图上各组均值差异明显但 ANOVA 不显著通常是因为组内波动大或者样本量不足。8.5 注意批处理与自动化如果你要对大量指标批量做 ANOVA建议封装函数统一处理输入和输出避免每跑一个指标都复制一遍代码。比如把“Levene 检验 ANOVA Tukey”封装成一个流水线输出结果为 DataFrame方便汇总。这在算法实验评估中非常实用能大幅减少重复劳动。8.6 谨慎对待由同一批样本重复实验得到的数据同一个模型、同一份数据集只是不同随机种子重复训练得到的结果在严格意义上并不完全独立。实际分析中如果随机种子差异足够大样本近似独立但如果数据本身存在较强的数据泄露ANOVA 的正态性和独立性假设都会被破坏。更严谨的做法是使用重复测量方差分析或混合效应模型将“随机种子”作为随机效应纳入模型。不过对于日常算法对比如果只是评估性能稳定性单个随机种子下的多次训练通常被视为近似重复。9. 总结与下一步方向这篇文章从“为什么不能直接用多次 t 检验”这个真实痛点出发把 ANOVA 的计算流程完整拆解了一遍从总平方和 SST 出发拆成组间平方和 SSB 和组内平方和 SSW再用自由度和均方 MSV 计算出 F 值最后用 F 分布得到 p 值。通过手工代码和 statsmodels 对照验证你能清楚看到 ANOVA 表的每一个数字从哪里来不再把它当成黑箱。真正要在实际分析里用好 ANOVA还需要掌握几个延伸方向双因素 ANOVA研究两个分组变量及其交互作用重复测量 ANOVA同一个体在不同时间或条件下的测量混合效应模型“固定效应 随机效应”的统一框架现代数据分析更推荐掌握非参数替代方法Kruskal-Wallis、Dunn 检验、Friedman 检验。对于多数 CSDN 读者来说下一步建议很明确找一份你自己的实验数据按文章流程跑一遍手工 ANOVA再用 statsmodels 对齐结果最后补上 Tukey 后检验。整个流程跑通之后再面对“多组均值比较”的问题时你会更容易形成自己的判断而不是拿到数据就直接套模型。也可以把本文的代码保存为一份通用分析脚本以后遇到连续变量多组比较的场景改两行列名就能继续复用。这就是统计方法在工程实践中最划算的投入。
返回列表