はじめに
統計検定2級で出題されるt検定について学んでいこうと思います!
📘 T検定(t-test)とは?
T検定は、2つの平均に差があるかを調べる統計的手法です。たとえば「薬を飲んだグループと飲んでいないグループで効果に違いがあるか?」などを検証します。
🎯 目的
- 2つのグループの平均値に有意な差があるかを調べる
- 差が「たまたま」なのか「本当に違う」のかを判断する
🔢 種類と使い分け
種類 | 使うときの例 |
---|---|
1標本t検定 | 平均点が60点と違うか? |
対応のあるt検定 | 同じ人の前後で効果があるか?(例:ダイエット前後) |
対応のないt検定 | 男女で平均に違いがあるか? |
📐 計算の考え方(イメージ)
- 平均の差 ÷ 標準誤差 → t値
- t値が大きいほど、差が「偶然とは思えない」と判断される
📊 検定の流れ
-
**帰無仮説(H₀)**を立てる
→「差はない」と仮定 -
t値を計算し、p値を求める
-
p値 < 0.05なら
→ 帰無仮説を棄却(差があると判断)
✅ 問題(例題)
新しい学習教材を導入したクラスAと、従来通りの教材を使ったクラスBのテストの平均点に差があるかを検定したい。
各クラスのテスト点数は以下の通りである。
• クラスAの得点(n=8):78, 85, 82, 88, 90, 76, 84, 80
• クラスBの得点(n=8):72, 75, 70, 78, 74, 69, 73, 71
有意水準5%で、クラスAとBの平均点に有意な差があるか検定せよ。
T検定の考え方。比較対象のAとBは同じものという前提。同じなんだから、混ぜても平均や分散って大体一緒だよね。標本の取り方次第で差は出るもの。でも、その差が意味のあるの差なんだっけ?それとも、偶然の範囲の差なんだっけ?それを検定でしらべようねっていう、アプローチ。ようやくわかってきた
✏️ 独立2標本t検定の途中式(等分散を仮定)
✅ 問題設定
クラスAとクラスBのテストの平均点に差があるか、有意水準5%で検定する。
- クラスAの得点(n₁ = 8):78, 85, 82, 88, 90, 76, 84, 80
- クラスBの得点(n₂ = 8):72, 75, 70, 78, 74, 69, 73, 71
① 各群の平均と不偏分散を計算
クラスA
$$
\bar{x}_1 = \frac{78 + 85 + 82 + 88 + 90 + 76 + 84 + 80}{8} = 82.875
$$
$$
s_1^2 = \frac{1}{7} \sum (x_i - \bar{x}_1)^2 \approx 23.27
$$
クラスB
$$
\bar{x}_2 = \frac{72 + 75 + 70 + 78 + 74 + 69 + 73 + 71}{8} = 72.75
$$
$$
s_2^2 \approx 8.50
$$
② プールされた分散(共通分散)
$$
s_p^2 = \frac{(n_1 - 1)s_1^2 + (n_2 - 1)s_2^2}{n_1 + n_2 - 2}
$$
$$
= \frac{(7)(23.27) + (7)(8.50)}{14} = \frac{162.89 + 59.50}{14} \approx 15.93
$$
③ t統計量の計算
$$
t = \frac{\bar{x}_1 - \bar{x}_2}{\sqrt{s_p^2 \left( \frac{1}{n_1} + \frac{1}{n_2} \right)}}
$$
$$
= \frac{82.875 - 72.75}{\sqrt{15.93 \cdot \left( \frac{1}{8} + \frac{1}{8} \right)}}
= \frac{10.125}{\sqrt{15.93 \cdot 0.25}}
= \frac{10.125}{\sqrt{3.9825}}
\approx \frac{10.125}{1.995}
\approx 5.08
$$
④ 自由度と判断
-
自由度:
$$
df = n_1 + n_2 - 2 = 14
$$ -
検定統計量:
$$
t = 5.08
$$ -
p値 ≈ 0.0002(t分布表またはPythonで確認)
✅ 結論
有意水準5%より p値が小さい ため、帰無仮説を棄却。
つまり、クラスAとクラスBの平均点には有意な差がある。
教材の効果は統計的に有意といえる。
# 📌 日本語フォントのインストール(Google Colab用:最初に1回だけ)
!apt-get -y install fonts-ipafont-gothic > /dev/null
# ライブラリのインポート
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
# 📌 日本語フォントを指定
jp_font = FontProperties(fname="/usr/share/fonts/opentype/ipafont-gothic/ipag.ttf")
plt.rcParams['font.family'] = jp_font.get_name()
# ---------------------------
# データ設定
# ---------------------------
class_a = np.array([78, 85, 82, 88, 90, 76, 84, 80])
class_b = np.array([72, 75, 70, 78, 74, 69, 73, 71])
# t検定(等分散と仮定)
t_stat, p_value = stats.ttest_ind(class_a, class_b, equal_var=True)
# 平均・標準偏差
mean_a = np.mean(class_a)
mean_b = np.mean(class_b)
std_a = np.std(class_a, ddof=1)
std_b = np.std(class_b, ddof=1)
# ---------------------------
# グラフ描画
# ---------------------------
labels = ['クラスA', 'クラスB']
means = [mean_a, mean_b]
stds = [std_a, std_b]
fig, ax = plt.subplots()
bars = ax.bar(labels, means, yerr=stds, capsize=10, color=['skyblue', 'salmon'])
# タイトル・ラベルにフォントを明示的に設定
ax.set_title("クラスごとの平均点と標準偏差", fontproperties=jp_font)
ax.set_ylabel("テストの得点", fontproperties=jp_font)
ax.set_xticklabels(labels, fontproperties=jp_font)
# 平均の点線
ax.axhline(mean_a, color='blue', linestyle='--', linewidth=0.5, label='クラスA 平均')
ax.axhline(mean_b, color='red', linestyle='--', linewidth=0.5, label='クラスB 平均')
# 凡例に日本語フォント
ax.legend(prop=jp_font)
plt.tight_layout()
plt.show()
# ---------------------------
# 検定結果の出力
# ---------------------------
print(f"t値 = {t_stat:.3f}")
print(f"p値 = {p_value:.3f}")
if p_value < 0.05:
print("⇒ 有意差あり:教材によって平均点に差がある")
else:
print("⇒ 有意差なし:教材による平均点の差は有意とは言えない")