本ページでは、 t検定を統合的に解説します。 1標本・2標本(独立)・対応のあるt検定・Welchのt検定を、 前提条件・効果量・信頼区間まで一気通貫で理解できます。
t検定は、 標本サイズが小さい(n < 30 程度)ときに「平均値」に関する仮説を検証する最も基本的な方法です。 SSDSE-B のような 47 都道府県データでも頻繁に使われます。
論文記事から各用語のリンクをクリックすると、 該当箇所が開きます:
「とりあえず 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 報告 が信頼性を高めます。
t検定の核心は「平均の差は本物か、 たまたまのバラつきか?」を 偏差で割った標準化スコア で測ること。 SSDSE-B-2026 を例にすると、 「人口 100 万人以上の県」と「未満の県」に出生率を分けて比較するとき、 ふたつの群の平均差を 群内のバラつきの大きさ で割ると t値が得られます。 t値が大きければ「差は本物っぽい」、 小さければ「誤差でも起こりうる」と判断します。
比喩で言うと、 5cm の差が大きいかどうかは 普段のブレ と比較するべきです。 普段の身長測定誤差が 0.5cm なら 5cm は大きいですが、 普段のブレが 10cm(厚着の重量など)なら誤差範囲内。 t検定はこの「相対的な大きさ」を 1 つの数値で表してくれるツールです。
| 記号 | 意味 | 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 |
「母平均は μ₀ か?」を検定する場合、 母分散 σ² が分かっていれば z検定(標準正規分布を使う)で済む。 しかし実務では σ² も標本から推定するため、 推定の不確実性が加わる。 これを反映したのが t分布。
確率変数 $T$ が自由度 $\nu$ のt分布に従うとき:
$$T = \frac{Z}{\sqrt{V/\nu}}, \quad Z \sim N(0,1),\ V \sim \chi^2_\nu$$
記号読み:$T$ は「ティー」、 $\nu$ は「ニュー」自由度。 t分布は標準正規より裾が厚い(外れ値・極端値が出やすい)形状。
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() |
母平均が基準値 $\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$ のとき:
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 "有意でない (保留)"}') |
2 つの独立な群の平均が等しいかを検定する。
$$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 群の分散を加重平均する。
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}') |
同じ個体に対して 2 回測定した結果を比較する。 例:薬投与の前後、 訓練の前後。
個体ごとの差 $d_i = x_{1i} - x_{2i}$ について:
$$t = \frac{\bar{d}}{s_d / \sqrt{n}}, \quad \nu = n - 1$$
各個体内で「個人差」がキャンセルされるため、 独立2標本より検出力が高い。
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}') |
等分散を仮定しない 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_ind は equal_var=False を指定すると Welch(実務では既定的にこちらを使う)。
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}') |
R の t.test() の既定は Welch である。 SciPy も実務的に Welch を既定にすべきとされる。
| 前提 | 確認方法 | 違反したら |
|---|---|---|
| 正規性 | QQ プロット・Shapiro–Wilk | n≥30 なら CLT で頑健 / Mann–Whitney U / 並べ替え検定 |
| 等分散性 | Levene 検定・F検定 | Welchを使う |
| 独立性 | サンプリング設計を確認 | 混合効果モデル等 |
| 外れ値の影響 | 箱ひげ図 | 中央値検定や頑健統計 |
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)) |
p値はサンプル数依存。 サンプルが多いほど小さな差でも有意になる。 効果の大きさ自体は効果量で評価する。
$$d = \frac{\bar{x}_1 - \bar{x}_2}{s_p}$$
慣例:|d| ≈ 0.2 小、 0.5 中、 0.8 大。
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)) |
「真に効果があるとき、 検定が正しく有意となる確率」。 慣例 0.8 以上が望ましい。 必要サンプルサイズの事前計算に使う。
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}') |
p値より、 平均の95%信頼区間を報告する方が情報量が多い。
$$\bar{x} \pm t_{\alpha/2, n-1} \cdot \frac{s}{\sqrt{n}}$$
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}]') |
複数の t検定を行うと、 family-wise 第一種過誤率が膨らむ。 K 個の検定をすると、 全体で α が約 $1-(1-\alpha)^K \approx K\alpha$ になる。
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) |
| 状況 | 使う検定 | 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 / Wilcoxon | mannwhitneyu / wilcoxon |
| 3 群以上 | ANOVA | f_oneway |
| 落とし穴 | 対処 |
|---|---|
| p値だけ報告 | 効果量 (Cohen's d) と平均の信頼区間を必ず併記。 |
| 多重検定を補正しない | Holm / BH で補正。 補正の有無を明記。 |
| 対応データを独立2標本で検定 | 必ず ttest_rel。 検出力が大幅に下がる。 |
| 等分散と決めつける | Welch を既定にする。 検出力もあまり落ちない。 |
| 正規性検定で p > 0.05 だから正規と決定 | 「棄却できない」は「成り立つ」ではない。 QQ プロットを目視。 |
| 事後にサンプルサイズを増やす | 第一種過誤率が膨らむ。 事前にサイズ計算を。 |
| p > 0.05 を「差なし」と報告 | 「有意ではない=差がない」ではない。 検出力不足の可能性。 |
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 が小さくて検出力不足だった可能性」も忘れず併記しましょう。
SSDSE-B-2026 から「東日本 vs 西日本」の一人当たり県民所得を比較する Welch の t 検定を、 3 つのライブラリで実装します。
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}') |
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}') |
1 2 | from statsmodels.stats.power import TTestIndPower print(TTestIndPower().solve_power(effect_size=0.5, alpha=0.05, power=0.8)) |
「2 群に有意差が認められた (p < 0.05)。」
「人口密度高群 (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)。」
| 用途 | 関数・クラス |
|---|---|
| 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 U | scipy.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 |
A1101 → 総人口(千人)。 分析の分母になる基本量です。A1301 → 65 歳以上人口。 高齢化率を産む分子。A1201 → 15 〜 64 歳人口(生産年齢人口)。 経済活動の主体。μ → 全国平均。 比較基準として用います。α → 有意水準。 第一種の誤り許容率(t 検定 に関する判断で重要)。p → p 値。 H₀ の下でデータがどれだけ稀かを示す。基本量の関係を、 記号 → 意味で整理します。 任意の比率は
$$\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 の都道府県データから t 検定 の文脈で代表値を読み取ります。 各列の記号 → 意味を確認し、 平均・中央値・四分位を併記する習慣を身につけましょう。
| 都道府県 | 総人口(千) | 65歳以上人口(千) | 高齢化率(%) | 記号 → 意味 |
|---|---|---|---|---|
| 秋田県 | 945 | 370 | 39.1 | A1101 → 総人口 / A1301 → 高齢者 / 比率 → 高齢化率 |
| 東京都 | 14,047 | 3,193 | 22.7 | 巨大分母 → 平均を引き上げる外れ値の典型 |
| 沖縄県 | 1,467 | 323 | 22.0 | 若い人口構造 → 全国最低の高齢化率 |
| 大阪府 | 8,838 | 2,420 | 27.4 | 大都市圏の中位 → 比較基準として有用 |
| 島根県 | 658 | 231 | 35.1 | 人口減少地域 → 分母縮小型の高齢化 |
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 値・統計量で、 解釈には「実値で計算してみる → 仮説検定 → 効果量 → 結論」の流れを推奨します。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 値・統計量で、 解釈には「実値で計算してみる → 仮説検定 → 効果量 → 結論」の流れを推奨します。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 値・統計量で、 解釈には「実値で計算してみる → 仮説検定 → 効果量 → 結論」の流れを推奨します。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 値・統計量で、 解釈には「実値で計算してみる → 仮説検定 → 効果量 → 結論」の流れを推奨します。t 検定 を中心に、 前提概念・並列分野・発展手法へリンクします。
グループ教材から t 検定 の文脈に直結する論文・ハンズオンを辿れます。
t 検定 は古典統計と社会データの交差点で発達してきました。 19 世紀末から 20 世紀初頭にかけて Pearson, Fisher, Neyman などが基礎を整え、 戦後の公的統計整備により実務応用が広がりました。
2010 年代以降は、 「再現性危機」「ビッグデータ」「AI 倫理」の三つの波が t 検定 に新しい意味を与えました。 単に p<0.05 を出すのではなく、 効果量・信頼区間・事前登録・データシートが必須となっています。
日本では総務省統計局・国立社会保障人口問題研究所・経済産業省 RESAS などが公的統計を整備し、 教育用に SSDSE が無償公開されました。 本ページもこの枠組みで t 検定 を扱います。
https://www.e-stat.go.jp/https://www.nstac.go.jp/use/literacy/ssdse/https://docs.scipy.org/doc/scipy/reference/stats.htmlhttps://www.statsmodels.org/同じカテゴリの手法、 上位概念、 派生分野へのリンクを補強します。
t 検定 を SSDSE-B-2026 の 47 都道府県データで多角的に検証します。 ここでは(1)地域グルーピング、 (2)時系列推移の近似、 (3)リスク評価指標の三つを順に扱います。
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']))
過去 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}%')
複数指標を 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))
同じカテゴリの隣接概念、 派生分野、 上位概念へのリンクを補強します。
95% 信頼区間と検出力の式を併記します。
$$\text{CI}_{95\%} = \bar{x} \pm 1.96 \frac{s}{\sqrt{n}}$$
記号 → 意味:
t 検定 を「カメラの絞り」に例えると、 絞りを開けすぎると(α を大きくすると)光(偽陽性)が入りすぎ、 絞りすぎると(α を小さくすると)暗くなって何も写らない(偽陰性増加)。 適度な絞り=適度な α を、 撮影条件=研究設計に応じて決める作業が統計的判断です。
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}')