論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説(ジャストインタイム型データサイエンス教育)
t検定 — 平均値の比較
t-Tests for Means
標本サイズが小さいときの平均値検定 — 統計実務の入口
仮説検定パラメトリック正規性前提小標本可

📍 あなたが今見ているもの

本ページでは、 t検定を統合的に解説します。 1標本2標本(独立)対応のあるt検定Welchのt検定を、 前提条件・効果量・信頼区間まで一気通貫で理解できます。

t検定は、 標本サイズが小さい(n < 30 程度)ときに「平均値」に関する仮説を検証する最も基本的な方法です。 SSDSE-B のような 47 都道府県データでも頻繁に使われます。

🔖 🔖 キーワード索引(チップから該当箇所へジャンプ)

論文記事から各用語のリンクをクリックすると、 該当箇所が開きます:

なぜt分布 t分布 自由度 1標本t検定 2標本t検定 対応のあるt検定 Welchのt検定 前提条件 正規性 等分散性 効果量 (Cohen's d) 平均の信頼区間 検出力 多重検定補正 scipy.stats.ttest statsmodels pingouin ブートストラップ SSDSE 実値計算 TOST 等価性 Bayes Factor

🛡️ t 検定のロバスト代替と意思決定フロー

「とりあえず ttest_ind」ではなく、 データ特性に応じて適切な手法を選ぶための比較表です。

状況 推奨手法 理由 / 注意
n が大きく分布も正規Student の t / Welch の t古典的最強。 Welch を既定にしておけば等分散を気にせず安心。
n が小さく非正規・歪み大Mann-Whitney U順位ベースで分布形に依存しない。 効果量は r = Z/√N。
対応データかつ差分が非正規Wilcoxon 符号順位差分の中央値の検定。 効果量は r_w。
外れ値が支配的Yuen の t(トリム平均)両端 20% をトリムした平均で検定。 scipy.stats.ttest_ind の代替に pingouin.ttest(... yuen=True)
同等性 (差がないこと) を主張TOST(two one-sided tests)「差が ±δ 以内」を能動的に示す。 statsmodels.stats.weightstats.ttost_ind
事前確率を反映したいベイズ的 t 検定 (BF₁₀)BF₁₀ > 3 で「中程度の証拠あり」。 pingouin.ttest が自動計算。
分布仮定を一切置きたくないブートストラップ平均差10,000 回の再抽出で 95% CI。 サンプル数 5,000 件超でも実用速度。

論文・コンペでは「Welch の t と Mann-Whitney U の両方を行い、 結論が一致するか確認」する two-track 報告 が信頼性を高めます。

💡 30秒で分かる結論

🎨 直感で掴む — t検定の正体

t検定の核心は「平均の差は本物か、 たまたまのバラつきか?」を 偏差で割った標準化スコア で測ること。 SSDSE-B-2026 を例にすると、 「人口 100 万人以上の県」と「未満の県」に出生率を分けて比較するとき、 ふたつの群の平均差を 群内のバラつきの大きさ で割ると t値が得られます。 t値が大きければ「差は本物っぽい」、 小さければ「誤差でも起こりうる」と判断します。

比喩で言うと、 5cm の差が大きいかどうかは 普段のブレ と比較するべきです。 普段の身長測定誤差が 0.5cm なら 5cm は大きいですが、 普段のブレが 10cm(厚着の重量など)なら誤差範囲内。 t検定はこの「相対的な大きさ」を 1 つの数値で表してくれるツールです。

🔬 数式を言葉で読み解く — t統計量の構成

$$ t = \frac{\bar{x}_1 - \bar{x}_2}{\sqrt{\dfrac{s_1^2}{n_1} + \dfrac{s_2^2}{n_2}}} $$
記号意味SSDSE-B-2026 例
$\bar{x}_1, \bar{x}_2$2 群の標本平均大都市と地方の出生率平均
$s_1^2, s_2^2$2 群の不偏分散各群内のバラつき
$n_1, n_2$サンプルサイズ大都市 7 県 vs 地方 40 県など
分子「シグナル」差大きいほど差が明確
分母「ノイズ」標準誤差小さいほど結論が安定

t値の絶対値が自由度の臨界値(2 群比較で約 2 程度)を超えれば、 通常 $p < 0.05$ で「平均差が偶然とは考えにくい」と判断します。

📚 章構成

内容
1. なぜt検定z検定との違い
2. t分布形状・自由度
3. 1標本t検定基準値との比較
4. 2標本t検定独立2群の比較
5. 対応のあるt検定前後比較
6. Welchのt検定等分散仮定なし
7. 前提条件正規性・等分散・独立
8. 効果量と検出力Cohen's d

🤔 1. なぜ t検定なのか

「母平均は μ₀ か?」を検定する場合、 母分散 σ² が分かっていれば z検定(標準正規分布を使う)で済む。 しかし実務では σ² も標本から推定するため、 推定の不確実性が加わる。 これを反映したのが t分布

📈 2. t分布

確率変数 $T$ が自由度 $\nu$ のt分布に従うとき:

$$T = \frac{Z}{\sqrt{V/\nu}}, \quad Z \sim N(0,1),\ V \sim \chi^2_\nu$$

記号読み:$T$ は「ティー」、 $\nu$ は「ニュー」自由度。 t分布は標準正規より裾が厚い(外れ値・極端値が出やすい)形状。

2.1 自由度 (Degrees of Freedom)

🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

x = np.linspace(-4, 4, 500)
for df in [2, 5, 30]:
    plt.plot(x, stats.t.pdf(x, df), label=f't, df={df}')
plt.plot(x, stats.norm.pdf(x), 'k--', label='N(0,1)')
plt.title('t分布と標準正規分布')
plt.legend()
plt.show()
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。

🎯 3. 1標本t検定

母平均が基準値 $\mu_0$ と等しいかを検定する。

仮説

検定統計量

$$t = \frac{\bar{x} - \mu_0}{s/\sqrt{n}}, \quad \nu = n-1$$

記号読み:$\bar{x}$ は「エックス・バー」標本平均、 $s$ は「エス」標本標準偏差、 $n$ は標本サイズ。 $s/\sqrt{n}$ を標準誤差と呼ぶ。

🧮 実値で計算してみる

n=10、 $\bar{x}=12.5$、 $s=2.0$、 $\mu_0=10$ のとき:

🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
1
2
3
4
5
6
7
8
9
import pandas as pd
from scipy import stats

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
# 持ち家比率の母平均が60%と等しいかを検定
t_stat, p_value = stats.ttest_1samp(df['持ち家比率'], popmean=60)
print(f't = {t_stat:.3f}, p = {p_value:.4f}')
print(f'標本平均 = {df["持ち家比率"].mean():.2f}')
print(f'判定: {"有意 (棄却)" if p_value  0.05 else "有意でない (保留)"}')
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。

👥 4. 2標本t検定(独立サンプル)

2 つの独立な群の平均が等しいかを検定する。

仮説

4.1 等分散を仮定する場合(Student のt検定)

$$t = \frac{\bar{x}_1 - \bar{x}_2}{s_p \sqrt{1/n_1 + 1/n_2}}, \quad s_p^2 = \frac{(n_1-1)s_1^2 + (n_2-1)s_2^2}{n_1 + n_2 - 2}$$

記号読み:$s_p$ は「エス・ピー」プール分散の平方根。 共通分散を仮定して、 2 群の分散を加重平均する。

🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import pandas as pd
from scipy import stats

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
# 「人口密度の中央値で高低分類」した2群の所得を比較
median_pop = df['人口密度'].median()
high = df[df['人口密度'] >= median_pop]['一人当たり県民所得']
low  = df[df['人口密度']   median_pop]['一人当たり県民所得']

t_stat, p_value = stats.ttest_ind(high, low, equal_var=True)
print(f't = {t_stat:.3f}, p = {p_value:.4f}')
print(f'高密度群平均 = {high.mean():.0f}, 低密度群平均 = {low.mean():.0f}')
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。

🔁 5. 対応のあるt検定

同じ個体に対して 2 回測定した結果を比較する。 例:薬投与の前後、 訓練の前後。

検定統計量

個体ごとの差 $d_i = x_{1i} - x_{2i}$ について:

$$t = \frac{\bar{d}}{s_d / \sqrt{n}}, \quad \nu = n - 1$$

各個体内で「個人差」がキャンセルされるため、 独立2標本より検出力が高い。

🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import pandas as pd
from scipy import stats

# 例:各都道府県で2020年と2025年の値を比較
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
# 仮想的に2列を比較したいときの構造
before = df['世帯人員']  # 2020年想定
after  = df['世帯人員'] - 0.1  # 2025年想定(仮想)

t_stat, p_value = stats.ttest_rel(before, after)
print(f't = {t_stat:.3f}, p = {p_value:.4f}')
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。

⚖️ 6. Welchのt検定(実務既定)

等分散を仮定しない 2 標本t検定。 自由度を Welch–Satterthwaite 近似で計算。

$$t = \frac{\bar{x}_1 - \bar{x}_2}{\sqrt{s_1^2/n_1 + s_2^2/n_2}}$$

$$\nu \approx \frac{(s_1^2/n_1 + s_2^2/n_2)^2}{(s_1^2/n_1)^2/(n_1-1) + (s_2^2/n_2)^2/(n_2-1)}$$

SciPy の ttest_indequal_var=False を指定すると Welch(実務では既定的にこちらを使う)。

🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
1
2
3
from scipy import stats
t_stat, p_value = stats.ttest_ind(high, low, equal_var=False)
print(f'Welch t = {t_stat:.3f}, p = {p_value:.4f}')
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。

R との対応

R の t.test() の既定は Welch である。 SciPy も実務的に Welch を既定にすべきとされる。

📋 7. 前提条件

前提 確認方法 違反したら
正規性QQ プロット・Shapiro–Wilkn≥30 なら CLT で頑健 / Mann–Whitney U / 並べ替え検定
等分散性Levene 検定・F検定Welchを使う
独立性サンプリング設計を確認混合効果モデル等
外れ値の影響箱ひげ図中央値検定や頑健統計
🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
1
2
3
4
5
6
from scipy import stats
# 正規性
print('Shapiro:', stats.shapiro(high))
print('Shapiro:', stats.shapiro(low))
# 等分散性
print('Levene:', stats.levene(high, low))
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。

📐 8. 効果量(Cohen's d)と検出力

p値はサンプル数依存。 サンプルが多いほど小さな差でも有意になる。 効果の大きさ自体は効果量で評価する。

Cohen's d

$$d = \frac{\bar{x}_1 - \bar{x}_2}{s_p}$$

慣例:|d| ≈ 0.2 小、 0.5 中、 0.8 大。

🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
1
2
3
4
5
6
import numpy as np
def cohens_d(a, b):
    pooled = np.sqrt(((len(a)-1)*np.var(a, ddof=1) + (len(b)-1)*np.var(b, ddof=1)) / (len(a)+len(b)-2))
    return (np.mean(a) - np.mean(b)) / pooled

print('Cohen d =', cohens_d(high, low))
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。

検出力 (Power)

「真に効果があるとき、 検定が正しく有意となる確率」。 慣例 0.8 以上が望ましい。 必要サンプルサイズの事前計算に使う。

🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
1
2
3
4
from statsmodels.stats.power import TTestIndPower
analysis = TTestIndPower()
n_needed = analysis.solve_power(effect_size=0.5, alpha=0.05, power=0.8)
print(f'必要サンプルサイズ (各群): {n_needed:.0f}')
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。

🎯 9. 平均の信頼区間

p値より、 平均の95%信頼区間を報告する方が情報量が多い。

$$\bar{x} \pm t_{\alpha/2, n-1} \cdot \frac{s}{\sqrt{n}}$$

🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import numpy as np
from scipy import stats

x = df['持ち家比率']
n = len(x)
mean = x.mean()
se = x.std(ddof=1) / np.sqrt(n)
t_crit = stats.t.ppf(0.975, df=n-1)
ci = (mean - t_crit*se, mean + t_crit*se)
print(f'平均 = {mean:.2f}, 95%CI = [{ci[0]:.2f}, {ci[1]:.2f}]')
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。

🔀 10. 多重比較補正

複数の t検定を行うと、 family-wise 第一種過誤率が膨らむ。 K 個の検定をすると、 全体で α が約 $1-(1-\alpha)^K \approx K\alpha$ になる。

🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
1
2
3
4
5
from statsmodels.stats.multitest import multipletests
p_values = [0.001, 0.012, 0.034, 0.045, 0.060]
reject, p_adj, _, _ = multipletests(p_values, alpha=0.05, method='holm')
print('Adjusted p:', p_adj)
print('Reject:', reject)
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。

📊 11. t検定の使い分け

状況 使う検定 SciPy 関数
基準値との比較1標本t検定ttest_1samp
独立2群(等分散仮定)Studentのt検定ttest_ind(equal_var=True)
独立2群(等分散仮定なし)Welchのt検定ttest_ind(equal_var=False)
同一個体の前後対応のあるt検定ttest_rel
正規性が成り立たないMann–Whitney U / Wilcoxonmannwhitneyu / wilcoxon
3 群以上ANOVAf_oneway

⚠️ 12. よくある落とし穴

落とし穴 対処
p値だけ報告効果量 (Cohen's d) と平均の信頼区間を必ず併記。
多重検定を補正しないHolm / BH で補正。 補正の有無を明記。
対応データを独立2標本で検定必ず ttest_rel。 検出力が大幅に下がる。
等分散と決めつけるWelch を既定にする。 検出力もあまり落ちない。
正規性検定で p > 0.05 だから正規と決定「棄却できない」は「成り立つ」ではない。 QQ プロットを目視。
事後にサンプルサイズを増やす第一種過誤率が膨らむ。 事前にサイズ計算を。
p > 0.05 を「差なし」と報告「有意ではない=差がない」ではない。 検出力不足の可能性。

⚠️ 詳説:t 検定の落とし穴 7 連発

1. p 値だけを「結論」にしてしまう。p 値はサンプルサイズに敏感で、 N が大きいほど些細な差でも有意になります。 実務的に重要かどうかは Cohen's d(小: 0.2 / 中: 0.5 / 大: 0.8)や平均差の 95% CI で判断しないと「統計的有意だが実用的に無意味」な誤読が生まれます。 報告書には d と CI を必ず併記しましょう。

2. 多重比較を補正せずに「最初に有意になったペア」を強調する。k 個のペア比較を α=0.05 で独立に行うと、 実効的な α は 1 − 0.95k に膨れます。 47 都道府県の総当たり t 検定(1081 ペア)では、 偶然のみで 50 件以上が有意になります。 Bonferroni / Holm / BH(FDR)のいずれかを必ず適用してください。

3. 対応データを独立 2 標本で検定してしまう。同じ個体の前後測定は正の相関を持つため、 独立 2 標本 t 検定(ttest_ind)を使うと標準誤差が過大になり、 検出力が大きく低下します。 必ず ttest_rel(対応のある t 検定)を使い、 d も d_z = Mdiff/SDdiff で計算しましょう。

4. 等分散を当然視して Student 版 t 検定を使う。分散が大きく異なる 2 群(例:東京 vs 鳥取の県民所得)では、 Welch の t 検定(equal_var=False)の方が頑健です。 検出力ロスは僅かなので、 実務既定として Welch を採用する流派が主流になっています。

5. 正規性検定(Shapiro 等)で p > 0.05 だから「正規」と判定。「正規性を棄却できなかった」と「正規である」は別物です。 とくに n が小さいと検出力不足で常に p > 0.05 になります。 QQ プロット・ヒストグラム・歪度/尖度の目視確認を優先し、 怪しい場合は Wilcoxon やブートストラップに切り替えましょう。

6. 結果を見ながらサンプルサイズを追加する(optional stopping)。「もうちょっとデータを取れば有意になりそう」と追加観測すると、 第一種過誤率は名目 5% でも実効 10〜20% に膨れます。 事前に検出力解析(statsmodels.stats.power)で必要 N を決め、 計画通りに観測する規律が必要です。

7. p > 0.05 を「差がない」と結論する。「有意でない」は「差が存在しない証拠」ではなく、 「差を検出する証拠が不足」です。 等価性(同等性)を主張したいなら、 TOST(two one-sided tests)や Bayes Factor を使うのが正攻法です。 「N が小さくて検出力不足だった可能性」も忘れず併記しましょう。

🐍 Python 実装バリエーション(scipy / statsmodels / pingouin)

SSDSE-B-2026 から「東日本 vs 西日本」の一人当たり県民所得を比較する Welch の t 検定を、 3 つのライブラリで実装します。

A. scipy.stats(最も簡潔)

🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import pandas as pd
import numpy as np
from scipy import stats

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
med = df['人口密度'].median()
high = df[df['人口密度'] >= med]['一人当たり県民所得']
low  = df[df['人口密度']   med]['一人当たり県民所得']
t, p = stats.ttest_ind(high, low, equal_var=False)
mean_diff = high.mean() - low.mean()
se_diff = np.sqrt(high.var(ddof=1)/len(high) + low.var(ddof=1)/len(low))
print(f't={t:.3f}, p={p:.4f}, 平均差={mean_diff:.0f} ± {1.96*se_diff:.0f}')
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。
Q2. 5 つの変数 (所得、 世帯人員、 高齢化率、 人口密度、 就業率) について、 高密度群 vs 低密度群を比較する 5 つの t検定を行い、 Holm 補正後の有意な変数を特定しなさい。
🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from statsmodels.stats.multitest import multipletests
variables = ['一人当たり県民所得', '世帯人員', '高齢化率', '人口密度', '就業率']
p_list = []
for v in variables:
    h, l = df[df['人口密度']>=med][v], df[df['人口密度']med][v]
    _, p = stats.ttest_ind(h, l, equal_var=False)
    p_list.append(p)
reject, p_adj, _, _ = multipletests(p_list, method='holm')
for v, pa, r in zip(variables, p_adj, reject):
    print(f'{v}: p_adj={pa:.4f}, reject={r}')
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。
Q3. 効果量 d=0.5 を α=0.05、 検出力 0.8 で検出するのに必要なサンプル数を計算しなさい。
🎯 解説: SSDSE-B-2026 を題材に、 2 群間の平均差を検定する t 検定(独立 2 標本/対応あり/1 標本)を scipy.stats で実行する。 帰無仮説「平均が等しい」の検証であり、 p < 0.05 で有意差ありと判定するのが慣例。
1
2
from statsmodels.stats.power import TTestIndPower
print(TTestIndPower().solve_power(effect_size=0.5, alpha=0.05, power=0.8))
📥 入力例: data/raw/SSDSE-B-2026.csv(47行) 都道府県 A1101(総人口) 高齢化率 地域区分 北海道 5183687 32.5 北日本 東京都 14047594 22.7 関東 沖縄県 1467480 22.0 九州沖縄
📤 実行例: t統計量 = 2.345, p値 = 0.024, 自由度 = 45 95%信頼区間 = [0.32, 4.18] → p < 0.05 のため帰無仮説を棄却(平均差は統計的に有意)
💬 読み方: t 値の絶対値が大きい(>2 程度)かつ p < 0.05 で「差は偶然では説明しにくい」。 ただし「有意=実用的に大きい」とは限らない(効果量 Cohen's d も併用)。 等分散仮定が怪しい場合は Welch t 検定(equal_var=False)を使う。

📝 14. 報告フォーマット

❌ NG例

「2 群に有意差が認められた (p < 0.05)。」

✅ OK例

「人口密度高群 (n=24, M=305万円, SD=42) と低群 (n=23, M=278万円, SD=38) の一人当たり県民所得を Welchのt検定で比較した結果、 高群が有意に高かった (t(45.0) = 2.31, p = .025, 95% CI [3, 50]万円, Cohen's d = 0.68 中程度)。 Shapiro–Wilk による正規性、 Levene による等分散性も併せて確認した(前者 p=.18/.21、 後者 p=.14)。」

🐍 15. ライブラリ早見表

用途 関数・クラス
1標本t検定scipy.stats.ttest_1samp(a, popmean)
2標本t検定(独立)scipy.stats.ttest_ind(a, b, equal_var=True/False)
対応のあるt検定scipy.stats.ttest_rel(before, after)
Mann–Whitney Uscipy.stats.mannwhitneyu
Wilcoxon符号付き順位scipy.stats.wilcoxon
正規性 (Shapiro)scipy.stats.shapiro
等分散 (Levene)scipy.stats.levene
多重検定補正statsmodels.stats.multitest.multipletests
検出力解析statsmodels.stats.power.TTestIndPower
並べ替え検定scipy.stats.permutation_test

📜 16. t検定の歴史

💼 17. 実務応用

📚 Round 18 — t 検定 完全攻略補足

t 検定StudentWelch対応のあるt平均の差p 値効果量SSDSE-B-2026正規性等分散

🔬 数式を言葉で読み解く(拡張 narration)

🔬 記号 → 意味(narration):

📐 補足の数式と読み解き

基本量の関係を、 記号 → 意味で整理します。 任意の比率は

$$\text{比率} = \frac{\text{分子}}{\text{分母}} \times 100\quad\text{単位: }\%$$

記号 → 意味:

平均と分散は

$$\bar{x} = \frac{1}{n}\sum_{i=1}^{n} x_i,\quad s^2 = \frac{1}{n-1}\sum_{i=1}^{n}(x_i - \bar{x})^2$$

t 統計量・効果量は

$$t = \frac{\bar{x}_1 - \bar{x}_2}{\sqrt{s_1^2/n_1 + s_2^2/n_2}},\quad d = \frac{\bar{x}_1 - \bar{x}_2}{s_{\text{pooled}}}$$

🧮 実値で計算してみる — SSDSE-B-2026 47 都道府県

SSDSE-B-2026 の都道府県データから t 検定 の文脈で代表値を読み取ります。 各列の記号 → 意味を確認し、 平均・中央値・四分位を併記する習慣を身につけましょう。

都道府県総人口(千)65歳以上人口(千)高齢化率(%)記号 → 意味
秋田県94537039.1A1101 → 総人口 / A1301 → 高齢者 / 比率 → 高齢化率
東京都14,0473,19322.7巨大分母 → 平均を引き上げる外れ値の典型
沖縄県1,46732322.0若い人口構造 → 全国最低の高齢化率
大阪府8,8382,42027.4大都市圏の中位 → 比較基準として有用
島根県65823135.1人口減少地域 → 分母縮小型の高齢化

🐍 Python 実装 — Round 18 拡張

Welch の t 検定 — 高齢化率(東日本 vs 西日本)の比較

🎯 SSDSE-B-2026(都道府県データ)を t 検定 の文脈で読み解く実値計算例。 各セルの記号 → 意味(A1101 → 総人口, A1301 → 65 歳以上人口)を確認しながら手元の Jupyter で実行できます。
import pandas as pd
from scipy import stats
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
df['aging'] = df['A1301']/df['A1101']*100
west = ['滋賀県','京都府','大阪府','兵庫県','奈良県','和歌山県','鳥取県','島根県','岡山県','広島県','山口県','徳島県','香川県','愛媛県','高知県','福岡県','佐賀県','長崎県','熊本県','大分県','宮崎県','鹿児島県','沖縄県']
g_w = df[df['Prefecture'].isin(west)]['aging']
g_e = df[~df['Prefecture'].isin(west)]['aging']
t, p = stats.ttest_ind(g_e, g_w, equal_var=False)
print(f't={t:.3f}, p={p:.4f}')
📥 入力: data/raw/SSDSE-B-2026.csv(47 都道府県 × 主要統計列)。 出力例は数値・p 値・統計量で、 解釈には「実値で計算してみる → 仮説検定 → 効果量 → 結論」の流れを推奨します。

対応のある t 検定 — 各県の昼夜人口の差

🎯 SSDSE-B-2026(都道府県データ)を t 検定 の文脈で読み解く実値計算例。 各セルの記号 → 意味(A1101 → 総人口, A1301 → 65 歳以上人口)を確認しながら手元の Jupyter で実行できます。
import pandas as pd
from scipy import stats
# A1101: 総人口(常住), A1102: 昼間人口(あれば)
day = df['A1101']  # 常住人口
night = df['A1101'] * 0.95  # 仮の昼夜比でデモ
t, p = stats.ttest_rel(day, night)
print(f'対応のあるt: t={t:.3f}, p={p:.4f}')
📥 入力: data/raw/SSDSE-B-2026.csv(47 都道府県 × 主要統計列)。 出力例は数値・p 値・統計量で、 解釈には「実値で計算してみる → 仮説検定 → 効果量 → 結論」の流れを推奨します。

Cohen's d で効果量を算出

🎯 SSDSE-B-2026(都道府県データ)を t 検定 の文脈で読み解く実値計算例。 各セルの記号 → 意味(A1101 → 総人口, A1301 → 65 歳以上人口)を確認しながら手元の Jupyter で実行できます。
import numpy as np
m1, m2 = g_e.mean(), g_w.mean()
s1, s2 = g_e.std(ddof=1), g_w.std(ddof=1)
n1, n2 = len(g_e), len(g_w)
sp = np.sqrt(((n1-1)*s1**2 + (n2-1)*s2**2)/(n1+n2-2))
d = (m1 - m2) / sp
print(f"Cohen's d = {d:.3f}")  # 0.2 小, 0.5 中, 0.8 大
📥 入力: data/raw/SSDSE-B-2026.csv(47 都道府県 × 主要統計列)。 出力例は数値・p 値・統計量で、 解釈には「実値で計算してみる → 仮説検定 → 効果量 → 結論」の流れを推奨します。

検定の前提を全部チェック(実値で計算してみる)

🎯 SSDSE-B-2026(都道府県データ)を t 検定 の文脈で読み解く実値計算例。 各セルの記号 → 意味(A1101 → 総人口, A1301 → 65 歳以上人口)を確認しながら手元の Jupyter で実行できます。
from scipy import stats
print('Shapiro 正規性 east:', stats.shapiro(g_e))
print('Shapiro 正規性 west:', stats.shapiro(g_w))
print('Levene 等分散:', stats.levene(g_e, g_w))
📥 入力: data/raw/SSDSE-B-2026.csv(47 都道府県 × 主要統計列)。 出力例は数値・p 値・統計量で、 解釈には「実値で計算してみる → 仮説検定 → 効果量 → 結論」の流れを推奨します。

❓ よくある質問 (FAQ)

どの t 検定を使えばよい?
2 群独立かつ等分散仮定が成り立つなら Student、 そうでなければ Welch を既定で。 同じ対象の前後比較なら paired t(対応のある t)。
正規性が崩れていたら?
サンプル数が大きい(n≥30 程度)と中心極限定理で頑健ですが、 小標本かつ歪みが強いなら Wilcoxon/Mann-Whitney を検討。
片側と両側の使い分けは?
事前に方向の仮説を理論的に固定できるときのみ片側。 通常は両側を既定にします。
p<0.05 で勝利と言える?
p 値だけでなく効果量(Cohen's d)と信頼区間、 サンプルサイズの計画を併記してください。
等分散仮定はどう確認?
F 検定や Levene 検定。 等分散がはっきりしない場合は最初から Welch を使うのが実務的に安全。

⚠️ 拡張版 落とし穴チェックリスト

  1. 分母を確認しない罠: 比率や率の意味は分母で決まります。 SSDSE で「per 1000」と「per 100」を取り違えると桁違いになります。
  2. 外れ値の影響: 東京都が平均値を引き上げる効果は実際に大きく、 中央値との乖離を必ず併記しましょう。
  3. 因果と相関の混同: 高齢化率と平均所得が相関しても、 因果は別問題。 第三変数(産業構造・気候)の介在を疑います。
  4. 選択バイアス: 「都市部のサンプルだけ」では地方の構造が見えません。 47 都道府県すべてを観察しましょう。
  5. 多重比較: 47 都道府県を一斉比較すると α=0.05 でも約 2.35 件は偶然有意。 Bonferroni 等の補正が必須です。
  6. 時点ずれ: SSDSE-B-2026 と 国勢調査 2020 では基準時点が異なります。 同期した比較が必要。
  7. t 検定 特有の文脈ずれ: 教育用に正規化したサンプルと現場データの落差。 単位・桁・カテゴリを揃える前処理が肝心。

🔗 関連用語(前提・並列・発展)— Round 18 補強

t 検定 を中心に、 前提概念・並列分野・発展手法へリンクします。

🔗 t 検定🔗 仮説検定🔗 帰無仮説🔗 対立仮説🔗 p 値🔗 効果量🔗 サンプルサイズ🔗 正規性🔗 分散分析🔗 F 検定🔗 カイ二乗🔗 第一種の誤り🔗 正規分布🔗 平均🔗 相関

📚 関連グループ教材

グループ教材から t 検定 の文脈に直結する論文・ハンズオンを辿れます。

🕰 歴史的背景と現代

t 検定 は古典統計と社会データの交差点で発達してきました。 19 世紀末から 20 世紀初頭にかけて Pearson, Fisher, Neyman などが基礎を整え、 戦後の公的統計整備により実務応用が広がりました。

2010 年代以降は、 「再現性危機」「ビッグデータ」「AI 倫理」の三つの波が t 検定 に新しい意味を与えました。 単に p<0.05 を出すのではなく、 効果量・信頼区間・事前登録・データシートが必須となっています。

日本では総務省統計局・国立社会保障人口問題研究所・経済産業省 RESAS などが公的統計を整備し、 教育用に SSDSE が無償公開されました。 本ページもこの枠組みで t 検定 を扱います。

📚 参考リンク

🌐 関連手法・派生(広域マップ)

同じカテゴリの手法、 上位概念、 派生分野へのリンクを補強します。

🔗 t 検定🔗 仮説検定🔗 帰無仮説🔗 対立仮説🔗 p 値🔗 効果量🔗 サンプルサイズ🔗 正規性🔗 分散分析🔗 F 検定🔗 カイ二乗🔗 第一種の誤り🔗 正規分布🔗 平均🔗 相関

📚 Round 18 — t 検定 追加演習と詳細解説

🧮 実値で計算してみる — SSDSE-B-2026 拡張ケーススタディ

t 検定 を SSDSE-B-2026 の 47 都道府県データで多角的に検証します。 ここでは(1)地域グルーピング、 (2)時系列推移の近似、 (3)リスク評価指標の三つを順に扱います。

ケース 1: 9 地域ブロック × t 検定

SSDSE-B-2026 の都道府県を北海道・東北・関東・中部・近畿・中国・四国・九州・沖縄の 9 ブロックに集約して比較します。 ブロック内分散とブロック間分散の比から t 検定 の構造を観察できます。

import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
df['aging'] = df['A1301'] / df['A1101'] * 100
block_map = {
    '北海道': '北海道', '青森県':'東北','岩手県':'東北','宮城県':'東北','秋田県':'東北','山形県':'東北','福島県':'東北',
    '茨城県':'関東','栃木県':'関東','群馬県':'関東','埼玉県':'関東','千葉県':'関東','東京都':'関東','神奈川県':'関東',
    '新潟県':'中部','富山県':'中部','石川県':'中部','福井県':'中部','山梨県':'中部','長野県':'中部','岐阜県':'中部','静岡県':'中部','愛知県':'中部',
    '三重県':'近畿','滋賀県':'近畿','京都府':'近畿','大阪府':'近畿','兵庫県':'近畿','奈良県':'近畿','和歌山県':'近畿',
    '鳥取県':'中国','島根県':'中国','岡山県':'中国','広島県':'中国','山口県':'中国',
    '徳島県':'四国','香川県':'四国','愛媛県':'四国','高知県':'四国',
    '福岡県':'九州','佐賀県':'九州','長崎県':'九州','熊本県':'九州','大分県':'九州','宮崎県':'九州','鹿児島県':'九州',
    '沖縄県':'沖縄'
}
df['block'] = df['Prefecture'].map(block_map)
print(df.groupby('block')['aging'].agg(['mean','std','min','max']))

ケース 2: 時系列の単純外挿で 2040 年を予測

過去 50 年の高齢化率推移は近似的に直線(やや上に凸)です。 線形外挿で 2030 / 2040 / 2050 年の値を推定し、 t 検定 の将来像を可視化します。

import numpy as np
years = [1970, 1980, 1990, 2000, 2010, 2020]
rate  = [7.1, 9.1, 12.1, 17.4, 23.0, 28.6]  # 厚労省・統計局公表値
coef = np.polyfit(years, rate, 2)
for y in [2030, 2040, 2050]:
    print(f'{y} 年予測: {np.polyval(coef, y):.1f}%')

ケース 3: リスクスコア — 都道府県の t 検定 観点での順位

複数指標を z 標準化し、 単純合成スコアで都道府県をランキングします。 重み付けの工夫により t 検定 の優先度を可変にできます。

import pandas as pd
cols = ['A1101','A1301']
z = (df[cols] - df[cols].mean()) / df[cols].std()
df['risk_score'] = z['A1301'] - 0.5 * z['A1101']
print(df[['Prefecture','aging','risk_score']].sort_values('risk_score', ascending=False).head(10))

🔬 数式を言葉で読み解く — 演習問題

  1. SSDSE-B-2026 の A1101 と A1301 の意味を言葉で答えなさい。(記号 → 意味)
  2. 「比率=分子 / 分母」を秋田県のデータで具体的に計算しなさい。 答え: 約 39%。
  3. 東京都・沖縄県・全国平均の三つを比較したとき、 どちらが t 検定 の「外れ値」と呼べるか説明しなさい。
  4. p<0.05 を採用したとき、 47 都道府県の同時検定で偶然有意になる期待件数を求めなさい。 答え: 47 × 0.05 ≈ 2.35。
  5. Bonferroni 補正後の有意水準を答えなさい。 答え: 0.05 / 47 ≈ 0.001。
  6. t 検定 を実務で使うときに最も避けるべき落とし穴を一つ挙げ、 対策を述べなさい。

🌐 関連手法・派生(広域マップ追補)

同じカテゴリの隣接概念、 派生分野、 上位概念へのリンクを補強します。

🔗 t 検定🔗 仮説検定🔗 帰無仮説🔗 対立仮説🔗 p 値🔗 効果量🔗 サンプルサイズ🔗 正規性🔗 ANOVA🔗 第一種の誤り

📚 関連グループ教材(追補)

⚠️ 落とし穴(追加 3 件)

  1. サンプルサイズが小さい状況での過大解釈。 47 都道府県だけでは全国推定に向かないことがある。
  2. カテゴリ分け(cut)の閾値で結論が変わる。 WHO 区分の 7/14/21% は便宜的で、 学術的根拠は限定。
  3. 時間軸の解像度不足。 単年データだけでは構造変化を見逃す。 SSDSE 過去版も併用しよう。

📐 数式または定義 — 補足公式

95% 信頼区間と検出力の式を併記します。

$$\text{CI}_{95\%} = \bar{x} \pm 1.96 \frac{s}{\sqrt{n}}$$

記号 → 意味:

🎨 直感で掴む — もう一つの比喩

t 検定 を「カメラの絞り」に例えると、 絞りを開けすぎると(α を大きくすると)光(偽陽性)が入りすぎ、 絞りすぎると(α を小さくすると)暗くなって何も写らない(偽陰性増加)。 適度な絞り=適度な α を、 撮影条件=研究設計に応じて決める作業が統計的判断です。

🐍 Python 実装 — 標本生成と検定の一気通貫

import pandas as pd
from scipy import stats
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
df['aging'] = df['A1301'] / df['A1101'] * 100
# 全国平均との一群比較
t, p = stats.ttest_1samp(df['aging'], 29.0)
print(f't={t:.3f} / p={p:.4f}')
# 効果量
d = (df['aging'].mean() - 29.0) / df['aging'].std()
print(f"Cohen's d = {d:.3f}")
# 95% 信頼区間
import numpy as np
m, s, n = df['aging'].mean(), df['aging'].std(), len(df)
ci = (m - 1.96*s/np.sqrt(n), m + 1.96*s/np.sqrt(n))
print(f'95% CI = {ci}')