【Python・统计学】单因素方差分析(简单原理及代码)

前言

自学笔记,分享给对统计学原理不太清楚但需要在论文中用到的小伙伴,欢迎大佬们补充或绕道。ps:本文不涉及公式讲解(文科生小白友好体质)~

本文重点:单因素方差分析(以下:方差分析)

【1.方差分析简单原理和前提条件

2.方差分析和t检验的区别

3.方差分析代码(配对/独立+事后检验+效应量)

1.方差分析简单原理

 方差分析(ANOVA)又称“变异数分析”或“F检验”,是由罗纳德·费雪爵士发明的,用于两个及两个以上样本均数差别的显著性检验 。 方差分析作为一种常用的统计方法,能够分析不同因素对数据变异的影响,并确定哪些因素对数据的变异具有显著影响。

▷方差分析的原理可以通过以下几个步骤来简单理解(简单理解即可,↓看需要满足的条件去看自己的数据是否符合)

  1. 将数据分组:根据研究目的,将数据分为不同的组别(如处理A、处理B、对照组等)。
  2. 计算各组内的方差:组内方差反映了每个组内数据的离散程度,表示由随机误差引起的差异。
  3. 计算组间方差:组间方差反映了不同组别之间数据的离散程度,表示由不同处理或因素引起的差异。
  4. 比较组间方差和组内方差:通过计算F统计量(F = 组间方差 / 组内方差),比较组间差异和组内差异的相对大小。
    • 如果F值较大(即组间方差明显大于组内方差),说明不同组别之间的差异主要是由处理或因素引起的,此时可以推断各组均值存在显著差异。
    • 如果F值较小(即组间方差与组内方差相近),说明不同组别之间的差异主要是由随机误差引起的,此时可以推断各组均值不存在显著差异。
  5. 根据F分布确定显著性水平:根据F统计量的值和自由度,在F分布表中查找对应的p值,判断结果是否达到统计学显著性水平(通常为0.05或0.01)。
    • 如果p值小于显著性水平,说明各组均值差异显著,可以推断不同处理或因素对结果有显著影响。
    • 如果p值大于显著性水平,说明各组均值差异不显著,可以推断不同处理或因素对结果没有显著影响

▷方差分析需要满足的条件

  1. 独立性:各组数据应来自独立的随机样本,不同组别之间的数据相互独立。
  2. 正态性:各组数据应服从正态分布,或至少接近正态分布。这个条件对于大样本量(每组通常大于30)来说不太严格,但对于小样本量,正态性假设非常重要。

         ***正态性:最直观的方法可以通过图表来验证!(详细可参考t检验的正态性检验部分)

CSDNicon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/135490471

      3.方差齐性:不同组别的总体方差应该相等,即满足方差齐性假设。这意味着各组数据的离散程度应该相近。

      4.数据类型:因变量应该是连续型变量,自变量应该是分类型变量。

▷配对(対応あり)和独立(対応なし)方差分析的区别:

  1. 配对方差分析:
    • 对应设计中,不同组别的数据是成对采集的,每一对数据来自同一个个体相匹配的个体。(例如:学生学习完某课程之前之后的成绩,教育学数据常用
    • 常见于重复测量设计,如前后测设计,每个个体接受不同的处理,然后比较处理前后的结果。
    • 另一个例子是匹配受试者设计,如比较一对双胞胎或匹配的病例-对照组之间的差异。
    • 对应设计可以消除个体间的差异对结果的影响,提高统计效力。
    • 对应设计需要使用重复测量方差分析或配对t检验等方法进行分析。
  2. 独立方差分析:
    • 无对应设计中,不同组别的数据是独立采集的,每个个体只接受一种处理或属于一个组别。(语言学数据常用
    • 常见于完全随机化设计,如将受试者随机分配到不同的处理组,然后比较不同组别之间的结果。
    • 无对应设计中,个体间的差异可能会影响结果,需要较大的样本量来检测处理效应。
    • 无对应设计需要使用单因素方差分析或独立样本t检验等方法进行分析。

2.方差分析和t检验的区别

方差分析(ANOVA)和t检验都是统计学中常用的假设检验方法,用于比较不同组别之间的均值差异是否显著。它们的主要区别如下:

  1. 适用场景(最主要区别!!时间紧的小伙伴读到这里直接确认自己的数据适合哪种):
    • t检验:适用于比较两个组别的均值差异。
    • 方差分析:适用于比较三个或更多组别的均值差异。
  2. 原理:
    • t检验:基于t分布,计算t统计量,并根据自由度得到p值,判断两组均值差异的显著性。
    • 方差分析:基于F分布,通过比较组间和组内方差的比值(F统计量),判断各组均值差异的显著性。
  3. 事后检验:
    • t检验:若比较多个组别,需要进行多次t检验,容易增加第一类错误(假阳性)的风险。
    • 方差分析:若方差分析的结果显著,可以进行事后检验(如Tukey检验、Bonferroni校正等),进一步确定具体哪些组别之间存在显著差异。
  4. 统计效力:
    • t检验:适用于小样本量的情况,但统计效力较低。
    • 方差分析:适用于大样本量的情况,统计效力较高,更容易检测出组间差异。

    总之,t检验适用于比较两个组别的均值差异,而方差分析适用于比较三个或更多组别的均值差异。在实际研究中,应根据研究设计和数据特点选择合适的方法。当需要比较多个组别时,方差分析是更优选的方法,并可通过事后检验进一步探究组间差异的具体情况。

3.方差分析代码(配对/独立+事后检验)

▷独立样本方差分析(语言学数据常用)

    步骤:方差齐性检验→方差分析→事后检验→效应量 

#安装需要的包(Google coloab的话要在pip前+“!”→!pip)
#检查python版本如果是python3需要安装pip3
pip install pandas scipy
pip install pingouin
pip install tabulate # 美化输出结果的,可以不用
import pandas as pd
import pingouin as pg
from tabulate import tabulate
# 创建示例数据
data = pd.DataFrame({
    'Group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C'],
    'Score': [10, 12, 8, 15, 20, 18, 22, 19, 9, 7, 11, 8]
})
# 方差齐性检验(Levene检验)
levene_result = pg.homoscedasticity(data, dv='Score', group='Group', method='levene')
print("Levene's test for equality of variances:")
print(tabulate(levene_result, headers='keys', tablefmt='grid'))
# 单因素方差分析
anova_result = pg.anova(data, dv='Score', between='Group', detailed=True)
print("\nOne-way ANOVA:")
print(tabulate(anova_result, headers='keys', tablefmt='grid'))
# 事后检验(Tukey HSD检验)
posthoc_result = pg.pairwise_tukey(data, dv='Score', between='Group')
print("\nPost-hoc tests (Tukey HSD):")
print(tabulate(posthoc_result, headers='keys', tablefmt='grid'))

输出结果: 

Levene's test for equality of variances:
┌────────┬──────────────────┬──────────┬─────────┐
│ Source │         W        │   ddof1  │   p-unc │
╞════════╪══════════════════╪══════════╪═════════╡
│ Group  │ 1.704761904761905 │ 2.0     │ 0.23628 │
└────────┴──────────────────┴──────────┴─────────┘
One-way ANOVA:
┌───────────────────────────┬─────────┬──────────┬─────────┬───────────┬─────────────────────┐
│ Source                    │ ddof1   │   ddof2  │       F │      p    │   np2               │
╞═══════════════════════════╪═════════╪══════════╪═════════╪═══════════╪═════════════════════╡
│ Group                     │ 2       │ 9        │ 41.25   │ 3.14e-05  │ 0.9015567765567765  │
└───────────────────────────┴─────────┴──────────┴─────────┴───────────┴─────────────────────┘
Post-hoc tests (Tukey HSD):
┌───────────┬─────────┬─────────┬───────────┬────────────┬───────────┐
│ A         │      B  │      C  │    hedges │     p-tukey │   p-tukey │
│           │         │         │           │             │   (corrected) │
╞═══════════╪═════════╪═════════╪═══════════╪════════════╪═══════════╡
│ A         │         │         │           │            │           │
├───────────┼─────────┼─────────┼───────────┼────────────┼───────────┤
│ B         │ -7.8125 │         │  5.83333  │ 2.3e-05    │ 6.9e-05   │
├───────────┼─────────┼─────────┼───────────┼────────────┼───────────┤
│ C         │ 2.375   │ 10.1875 │ -1.66382  │ 0.176      │ 0.176     │
└───────────┴─────────┴─────────┴───────────┴────────────┴───────────┘

分析:在独立方差分析的结果中,Levene检验的p值大于0.05,表明满足方差齐性假设。单因素方差分析的结果显示,组间差异显著(p=3.14e-05),事后检验(Tukey HSD检验)显示A组与B组之间存在显著差异(p=6.9e-05),而A与C、B与C之间的差异不显著(p值大于0.05)。

**具体在论文中如何呈现会根据期刊要求不同而不同,包括现在有些心理学和语言学期刊也会要求呈现效应量效应量大小的标准贴在本文最后+参考文献)。

独立样本效应量 :
#效应量
# 单因素方差分析
anova_result = pg.anova(data, dv='Score', between='Group', detailed=True)
print("One-way ANOVA:")
print(tabulate(anova_result, headers='keys', tablefmt='grid'))
# 计算η²
eta_squared = anova_result['SS'][0] / anova_result['SS'][2]
print(f"η² (Eta-squared): {eta_squared:.3f}")
# 计算partial η²
partial_eta_squared = anova_result['SS'][0] / (anova_result['SS'][0] + anova_result['SS'][1])
print(f"Partial η² (Partial Eta-squared): {partial_eta_squared:.3f}")
One-way ANOVA:
┌───────────────────────────┬─────────┬──────────┬─────────┬───────────┬─────────────────────┐
│ Source                    │ ddof1   │   ddof2  │       F │      p    │   np2               │
╞═══════════════════════════╪═════════╪══════════╪═════════╪═══════════╪═════════════════════╡
│ Group                     │ 2       │ 9        │ 41.25   │ 3.14e-05  │ 0.9015567765567765  │
└───────────────────────────┴─────────┴──────────┴─────────┴───────────┴─────────────────────┘
η² (Eta-squared): 0.902
Partial η² (Partial Eta-squared): 0.902

η²和partial η²的值都为0.902,表示组别可以解释因变量变异的90.2%,效应量非常大。

▷配对样本方差分析(医学,心理学,教育学研究常用)

 步骤:方差齐性检验→方差分析→事后检验→效应量

import pandas as pd
import pingouin as pg
from tabulate import tabulate
# 创建示例数据
data = pd.DataFrame({
    'Subject': [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5],
    'Treatment': ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C'],
    'Score': [10, 12, 8, 15, 11, 13, 14, 10, 16, 12, 9, 11, 7, 14, 10]
})
# 重塑数据为宽格式
data_wide = data.pivot(index='Subject', columns='Treatment', values='Score')
# 方差齐性检验(Levene检验)
levene_result = pg.homoscedasticity(data_wide, method='levene')
print("Levene's test for equality of variances:")
print(tabulate(levene_result, headers='keys', tablefmt='grid'))
# 重复测量方差分析
rm_anova_result = pg.rm_anova(data_wide, detailed=True)
print("\nRepeated measures ANOVA:")
print(tabulate(rm_anova_result, headers='keys', tablefmt='grid'))
# 事后检验(配对t检验,使用Bonferroni校正)
posthoc_result = pg.pairwise_ttests(data_wide, padjust='bonferroni')
print("\nPost-hoc tests (paired t-tests with Bonferroni correction):")
print(tabulate(posthoc_result, headers='keys', tablefmt='grid'))

输出结果: 

Levene's test for equality of variances:
┌────────┬──────────────────┬──────────┬─────────┐
│ Source │         W        │   ddof1  │   p-unc │
╞════════╪══════════════════╪══════════╪═════════╡
│ Group  │ 0.5257142857142857 │ 2.0     │ 0.60512 │
└────────┴──────────────────┴──────────┴─────────┘
Repeated measures ANOVA:
┌───────────────────────────┬─────────┬──────────┬───────────┬───────────┬─────────────────────┐
│ Source                    │ ddof1   │   ddof2  │      F    │      p    │   np2               │
╞═══════════════════════════╪═════════╪══════════╪═══════════╪═══════════╪═════════════════════╡
│ Treatment                 │ 2       │ 8        │ 7.06667   │ 0.0165    │ 0.6386554621848739  │
├───────────────────────────┼─────────┼──────────┼───────────┼───────────┼─────────────────────┤
│ Subject                   │ 4       │ 8        │ 15.6444   │ 0.000837  │ 0.8866925064599483  │
└───────────────────────────┴─────────┴──────────┴───────────┴───────────┴─────────────────────┘
Post-hoc tests (paired t-tests with Bonferroni correction):
┌───────────┬────────────┬─────────┬─────────┬───────────┬─────────┬────────┐
│ Contrast  │   Paired   │     T   │     dof │ Tail      │  p-unc  │ p-corr │
╞═══════════╪════════════╪═════════╪═════════╪═══════════╪═════════╪════════╡
│ A - B     │ True       │ -3.1798 │ 4       │ two-sided │ 0.03364 │ 0.1009 │
├───────────┼────────────┼─────────┼─────────┼───────────┼─────────┼────────┤
│ A - C     │ True       │ 2.7386  │ 4       │ two-sided │ 0.05195 │ 0.1558 │
├───────────┼────────────┼─────────┼─────────┼───────────┼─────────┼────────┤
│ B - C     │ True       │ 4.4159  │ 4       │ two-sided │ 0.01153 │ 0.0346 │
└───────────┴────────────┴─────────┴─────────┴───────────┴─────────┴────────┘
配对样本的效应量:

对于配对样本的重复测量方差分析,可以使用以下方法计算效应量:

  1. partial η² (Partial Eta-squared):
    • partial η² = SSbetween / (SSbetween + SSerror)
    • 其中,SSbetween是处理的平方和,SSerror是处理与被试交互的平方和。
  2. Generalized η² (Generalized Eta-squared):
    • Generalized η² = SSbetween / SStotal
    • 其中,SSbetween是处理的平方和,SStotal是总平方和。
    • Generalized η²适用于重复测量设计,因为它考虑了处理与被试交互的影响。
import pingouin as pg
# 重复测量方差分析
rm_anova_result = pg.rm_anova(data_wide, detailed=True)
print("Repeated measures ANOVA:")
print(tabulate(rm_anova_result, headers='keys', tablefmt='grid'))
# 计算partial η²
partial_eta_squared = rm_anova_result['SS'][0] / (rm_anova_result['SS'][0] + rm_anova_result['SS'][1])
print(f"Partial η² (Partial Eta-squared): {partial_eta_squared:.3f}")
# 计算Generalized η²
generalized_eta_squared = rm_anova_result['SS'][0] / rm_anova_result['SS'].sum()
print(f"Generalized η² (Generalized Eta-squared): {generalized_eta_squared:.3f}")
Repeated measures ANOVA:
┌───────────────────────────┬─────────┬──────────┬───────────┬───────────┬─────────────────────┐
│ Source                    │ ddof1   │   ddof2  │      F    │      p    │   np2               │
╞═══════════════════════════╪═════════╪══════════╪═══════════╪═══════════╪═════════════════════╡
│ Treatment                 │ 2       │ 8        │ 7.06667   │ 0.0165    │ 0.6386554621848739  │
├───────────────────────────┼─────────┼──────────┼───────────┼───────────┼─────────────────────┤
│ Subject                   │ 4       │ 8        │ 15.6444   │ 0.000837  │ 0.8866925064599483  │
└───────────────────────────┴─────────┴──────────┴───────────┴───────────┴─────────────────────┘
Partial η² (Partial Eta-squared): 0.639
Generalized η² (Generalized Eta-squared): 0.275

在这里,partial η²为0.639,表示在控制被试个体差异后,处理可以解释因变量变异的63.9%。Generalized η²为0.275,表示处理可以解释总变异的27.5%。 

<效应量参照>

水本篤,竹内理 (2008) 研究論文における効果量の報告のために. 基礎的概念と注意点. 英語教育研究, 31:57-66