はじめに
前回までに水準間平方和と残差平方和を学びました。ただ、水準間平方和と残差平方和を算出したけど、これって結局どうやって扱えばいいの?って疑問が。よく見ると、F検定をやって初めて価値のあるものらしいです。そのため、今回はF検定を学んでいきます!!
✅ F検定とは?グループ間に差があるかを検定する方法
水準間平方和(SSB)や残差平方和(SSE)を計算しただけでは、「差があるかどうか」は判断できません。
F検定を使うことで、グループ間に統計的に有意な差があるかを評価できます。
✅ F値とは?
F検定では、以下のように**「グループ間のばらつき」と「グループ内のばらつき」**を比べます。
$$
F = \frac{\text{水準間分散(MSB)}}{\text{残差分散(MSE)}}
$$
✅ 分散の求め方
- グループ数:$k$、データ総数:$N$
- $\text{MSB} = \dfrac{SSB}{k - 1}$(水準間平方和 ÷ 自由度)
- $\text{MSE} = \dfrac{SSE}{N - k}$(残差平方和 ÷ 自由度)
✅ P値で判断する
- F値が大きい → グループ間に差がある可能性が高い
- F値をもとにF分布からP値を求める
- P値 < 0.05(有意水準)なら、「有意な差がある」と判断
✅ 問題設定
ある学校で、A組・B組・C組の3クラスについて、テストの点数を調査しました。
クラス | 点数 |
---|---|
A組 | 60, 65, 70 |
B組 | 80, 75 |
C組 | 50, 55, 60 |
この3つのクラスに、平均点に有意な差があるかをF検定で確認します。
✅ ステップ1:平方和の計算
▶ 各クラスの平均と全体平均
- A組の平均:65
- B組の平均:77.5
- C組の平均:55
- 全体の平均:64.375
▶ 水準間平方和(SSB)
$$
SSB = \sum n_j(\bar{y}_j - \bar{y})^2 = 609.375
$$
- A組: $3 \times (65 - 64.375)^2 = 1.1719$
- B組: $2 \times (77.5 - 64.375)^2 = 344.531$
- C組: $3 \times (55 - 64.375)^2 = 263.672$
▶ 残差平方和(SSE)
$$
SSE = \sum (y_{ij} - \bar{y}_j)^2 = 112.5
$$
- A組: $(60-65)^2 + (65-65)^2 + (70-65)^2 = 50$
- B組: $(80-77.5)^2 + (75-77.5)^2 = 12.5$
- C組: $(50-55)^2 + (55-55)^2 + (60-55)^2 = 50$
✅ ステップ2:F値の計算
項目 | 計算内容 | 値 |
---|---|---|
グループ数 | $k = 3$ | |
全データ数 | $N = 8$ | |
自由度 | $df_1 = k - 1 = 2$、$df_2 = N - k = 5$ | |
$MSB$ | $SSB / df_1 = 609.375 / 2$ | 304.688 |
$MSE$ | $SSE / df_2 = 112.5 / 5$ | 22.5 |
F値 | $F = MSB / MSE = 304.688 / 22.5$ | 13.53 |
ここから、P値を算出する。
# 📌 ライブラリのインポート(scipyからf分布を使う)
from scipy.stats import f
# ✅ 入力値(F値と自由度)
F_value = 13.53 # 計算済みのF値
df1 = 2 # 自由度(グループ間)
df2 = 5 # 自由度(グループ内)
# ✅ P値の計算(右側の確率)
p_value = 1 - f.cdf(F_value, dfn=df1, dfd=df2)
# ✅ 出力
print(f"F値: {F_value}")
print(f"自由度 (df1, df2): ({df1}, {df2})")
print(f"P値: {p_value:.5f}")
# ✅ 判定
if p_value < 0.05:
print("→ 有意差あり(P < 0.05)")
else:
print("→ 有意差なし(P ≥ 0.05)")
F値: 13.53
自由度 (df1, df2): (2, 5)
P値: 0.00961
→ 有意差あり(P < 0.05)