赞
踩
自学笔记,分享给对统计学原理不太清楚但需要在论文中用到的小伙伴,欢迎大佬们补充或绕道。ps:本文不涉及公式讲解(文科生小白友好体质)~(部分定义等来源于知乎)
本文重点:多因素方差分析
【1.多因素方差分析简单原理】
【2.多因素方差分析步骤】
【3.多因素方差分析代码(配对/独立+事后检验)】
多因素方差分析,用于研究一个因变量是否受到多个自变量(也称为因素)的影响,它检验多个因素取值水平的不同组合之间,因变量的均值之间是否存在显著的差异。多因素方差分析既可以分析单个因素的作用(主效应),也可以分析因素之间的交互作用(交互效应),还可以进行协方差分析,以及各个因素变量与协变量的交互作用。
也就是说,
如果只有主效应显著,说明各因素独立地影响观测指标。
如果交互效应显著,说明因素之间存在相互影响,需要进一步分析交互效应的性质和方向。
之前学的时候写的笔记(虽然是日语)
- ①交互作用の検定
- ②交互作用OK: 単純主効果の検定→3水準以上(多重比較)
- 交互作用No: 主効果の検定→3水準以上(多重比較)
检验方差是否满足方差齐性,以及数据的正态性(详情参考之前的t检验和单因素方差分析)
使用的是一组教育学数据进行两因素方差分析
有实验组(Group1)和对照组(Group2)进行两种不同的方法教学,其中再把她们分成10人,20人和30人的班(Size),集中教学一段时间后进行测试(成绩为Score)
检验group(教学方法)和班级规模(size)的两因素,是否对最后的学生测试成绩有影响
- import pandas as pd
- from scipy.stats import levene
- from statsmodels.stats.anova import AnovaRM
-
- # 从 CSV 文件读取数据
- df = pd.read_csv('/content/taionasi.csv')
- balanced_df = pd.DataFrame(columns=df.columns)
-
- # 按照 group 进行抽样,确保每个组的样本大小相同
- for group in df['group'].unique():
- group_data = df[df['group'] == group]
-
- # 对每个组进行抽样,使得样本大小相同
- min_size = min(group_data['size'])
- sampled_data = group_data.groupby('size', group_keys=False).apply(lambda x: x.sample(min_size, random_state=42))
-
- # 将抽样后的数据添加到平衡的 DataFrame 中
- balanced_df = balanced_df.append(sampled_data, ignore_index=True)
-
- # 检查平衡后的数据结构
- print(balanced_df.head())
-
- # 对平衡后的数据进行 Levene's Test
- grouped_data_balanced = [balanced_df[balanced_df['group'] == group]['score'].values for group in balanced_df['group'].unique()]
- statistic, p_value = levene(*grouped_data_balanced)
- # 打印 Levene's Test 的结果
- print(f"Levene's Test Statistic: {statistic}")
- print(f"P-value: {p_value}")
-
- # 根据 P-value 判断方差齐性
- alpha = 0.05 # 有意水準
- if p_value < alpha:
- print('帰無仮説を棄却:データのグループ間に等分散性がない可能性が高いです。')
- else:
- print('帰無仮説は棄却されません:データのグループ間に等分散性があると考えられます。')

*注意:检验方差齐性的时候为了确保每组数据的个数一样,进行了数据抽样。如果不进行数据抽样虽然也不会报错但是数据结果截然相反。
结果:抽样数据显示满足方差齐性,可以进行多因素方差分析
- group size score
- 0 1 10 62
- 1 1 10 70
- 2 1 10 83
- 3 1 10 61
- 4 1 10 79
- Levene's Test Statistic: 1.2774939867588024
- P-value: 0.26301796308207803
- 帰無仮説は棄却されません:データのグループ間に等分散性があると考えられます。
- #交互作用プロット
- from statsmodels.graphics.factorplots import interaction_plot
- from matplotlib import pyplot as plt # import matplotlib.pyplot as plt グラフを描画するライブラリ
-
- fig = interaction_plot(df['size'], #x軸のデータ
- df['group'], #層別するデータ
- df['score'], #y軸のデータ
- colors=['red', 'blue'], #グラフの色を設定
- ms=15) #グラフの点の大きさの設定
- plt.show()
数据存在交点,证明存在交互效应(如果没有交互效应,两条线是平行的)
- #二元配置分散分析(交互作用あり)
- # 統計モデルを推定するライブラリ
- import statsmodels.formula.api as smf
- import statsmodels.api as sm
-
- anova_mod = smf.ols('score ~ group + size + group:size', data=df).fit()
- taionasi=sm.stats.anova_lm(anova_mod, type=2)
- taionasi.columns = ["自由度","平方和","平均平方和","F値","p値"] #列名を日本語に差し替え
- print("交互作用ありの結果:"+"\n"+str(taionasi))
- 交互作用ありの結果:
- 自由度 平方和 平均平方和 F値 p値
- group 1.0 26.450000 26.450000 0.261825 6.095178e-01
- size 2.0 11238.033333 5619.016667 55.621907 2.108493e-19
- group:size 2.0 4057.500000 2028.750000 20.082329 1.421430e-08
- Residual 174.0 17577.766667 101.021648 NaN NaN
- from statsmodels.stats.multicomp import pairwise_tukeyhsd
- from itertools import combinations
- import pandas as pd
- from IPython.display import display, HTML
-
- # df 是你的数据框
- # 调整数据类型
- df['group'] = df['group'].astype(str)
- df['size'] = df['size'].astype(str)
-
- # 初始化一个空的数据框,用于存储多重比较结果
- combined_results = pd.DataFrame(columns=['Group', 'Comparison', 'Mean Difference', 'Lower CI', 'Upper CI', 'Reject Null'])
-
- # 定义函数执行多重比较
- def run_tukey_comparison(group_label, group_data, size_values):
- group_combinations = combinations(group_data, 2)
- for size1, size2 in group_combinations:
- m_comp = pairwise_tukeyhsd(endog=pd.concat([size1['score'], size2['score']]),
- groups=pd.concat([pd.Series([f'{group_label}_size_{size_values[size1.iloc[0]["size"]]}'] * len(size1)),
- pd.Series([f'{group_label}_size_{size_values[size2.iloc[0]["size"]]}'] * len(size2))]),
- alpha=0.05)
- # 提取多重比较结果的重要信息
- comparison_results = pd.DataFrame({
- 'Group': [f'{group_label}'],
- 'Comparison': [f"{size1.iloc[0]['size']} vs {size2.iloc[0]['size']}"],
- 'Mean Difference': [m_comp.meandiffs[0]],
- 'Lower CI': [m_comp.confint[0, 0]],
- 'Upper CI': [m_comp.confint[0, 1]],
- 'Reject Null': [m_comp.reject[0]],
- })
- # 将结果添加到总的数据框中
- global combined_results
- combined_results = pd.concat([combined_results, comparison_results], ignore_index=True)
-
- # 运行 group1 的多重比较
- run_tukey_comparison('group1', group1_sizes, {'10': 10, '20': 20, '30': 30})
-
- # 运行 group2 的多重比较
- run_tukey_comparison('group2', group2_sizes, {'10': 10, '20': 20, '30': 30})
-
- # 调整表格显示顺序
- combined_results = combined_results[['Group', 'Comparison', 'Mean Difference', 'Lower CI', 'Upper CI', 'Reject Null']]
-
- # 打印合并结果
- print("Combined Results:")
- display(HTML(combined_results.to_html(index=False)))

事后检验结果:
- Group Comparison Mean Difference Lower CI Upper CI Reject Null
- group1 10 vs 20 -9.533333 -13.918702 -5.147965 True
- group1 10 vs 30 -30.266667 -35.333353 -25.199980 True
- group1 20 vs 30 -20.733333 -25.577774 -15.888892 True
- group2 10 vs 20 -9.533333 -13.918702 -5.147965 True
- group2 10 vs 30 -30.266667 -35.333353 -25.199980 True
- group2 20 vs 30 -20.733333 -25.577774 -15.888892 True
总的来说,这些结果表明:
这些发现表明,不同的 size 水平对因变量有显著影响,并且 size 水平越高,因变量的值越高。此外,Group1 和 Group2 表现出相同的模式,这表明 group 因素可能对 size 水平之间的差异没有显著影响。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。