信頼区間(confidence interval)は推測統計の最重要概念です。 関連キーワードを難易度別に整理しました。
🍰 まずはやさしく
予測の「幅」のことです。
答えがどれくらい不確かなかを知るために使います。
テストの点数の予想を幅で答えるようなものです。
この章では信頼区間の結論を短くまとめます。
「相関係数 r = 0.97」と1つの数字だけ示されても、 それが「絶対」なのか「不確かな推定」なのかが分かりません。 信頼区間(CI)は、 「同じ調査を繰り返したら、 どれくらいの幅で推定値がブレるか」を示します。
95% CI の解釈:「同じ手続きで100回データを取って100個のCIを作ったら、 そのうち約95個が真の値を含む」。 「真の値が95%の確率でこの区間にある」と読まれがちですが、 厳密には頻度論的にはやや違う表現になります(後述)。
幅の意味:CIが狭い → 推定が精密、 広い → 推定が不確実(n が少ない or データのばらつきが大きい)。 95%CIが 0 を含むか否か は決定的:含めば「効果なし」を否定できない(≒ p>0.05)。
p値より情報量が多い:効果の「大きさ」と「精度」を同時に示せます。 現代の論文では p値だけでなく必ず CI を併記すべき(AMA, APAなどのガイドライン)。
🍰 まずはやさしく
数字に添えられた「範囲」のことです。
データがどれくらいブレるかを見せるために使います。
スマホの充電時間がだいたい何分か示すようなものです。
この章では実際の表でどう書かれるかを読み解きます。
論文表で「[+0.840, +1.019]」「95% CI: 0.81–1.13」のように、推定値とセットで表記される区間。 点推定の不確実性を可視化する。
信頼区間 とは:「同じ実験を100回繰り返したら、95回は作られた区間が真の値を含む」という幅。点推定の不確実性を表現する。
🍰 まずはやさしく
予想の「自信」を形にしたものです。
データの量で答えの確かさが変わることを知るために使います。
部活の練習回数で成果の予想が変わるようなものです。
この章では図を使って直感的に仕組みを学びます。

信頼区間 (CI) は 「同じ手続きを繰り返したとき、 真値を含む区間が 95% できる」幅。 以下 3 図で「点推定 vs 区間推定」「N と CI 幅」「95% の意味」を可視化する。
→ 点推定は1 点だけを答えるが、 区間推定は不確かさ込みで答える。 同じデータでも報告の重みが違う。
→ N が 4 倍 → 幅は √4=2 倍狭くなる (σ/√N の効果)。 N=1000 なら ±0.76 に収まり、 結論に強い根拠を与えられる。
→ 100 回標本抽出して 100 個の CI を作ると、 約 95 個が真値 μ を含む。 「あなたの 1 つの区間が 95% の確率で真値を含む」ではない (頻度主義の解釈)。
母平均 $\mu$ の 95% 信頼区間は次式で求めます (正規分布近似、 既知の母分散 $\sigma$ の場合)。
$$ \text{CI}_{0.95} = \bar{x} \pm 1.96 \cdot \frac{\sigma}{\sqrt{n}} $$
記号の意味: $\bar{x}$ は標本平均 (中心)、 $\sigma$ は母標準偏差、 $n$ はサンプルサイズ、 $1.96$ は標準正規分布の 97.5% 点 (両側 95% に対応)。 分子 $\sigma$ は「データのばらつき」、 分母 $\sqrt{n}$ は「標本数の効果」を表します。 $n$ が 4 倍になると区間幅は $\sqrt{4} = 2$ 倍狭くなり、 精度が上がります。 $\sigma$ が未知の場合は標準偏差 $s$ と $t$ 分布を用い、 $1.96$ を $t_{n-1, 0.975}$ に置き換えます。
このコードでやること: SSDSE-B-2026(2023年度)の47都道府県の消費支出(二人以上の世帯、 月平均、 千円)について、 95% 信頼区間を scipy.stats.t.interval で計算する。
📥 入力データ (SSDSE-B-2026 2023年度抜粋、 消費支出 L3221 (千円)):
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='cp932', skiprows=[1]) x = df.loc[df['SSDSE-B-2026'] == 2023, 'L3221'].values / 1000 # 消費支出(千円) n = len(x) mean = np.mean(x) sem = stats.sem(x) ci = stats.t.interval(0.95, n-1, loc=mean, scale=sem) print(f'n = {n}, 標本平均 = {mean:.2f}') print(f'95% 信頼区間: [{ci[0]:.2f}, {ci[1]:.2f}]') |
📤 実行例:
💬 47 都道府県の消費支出の標本平均は 295.86 千円。 95% 信頼区間は [288.77, 302.94]。 「同じ手続きを反復して区間を作ると、 その 95% が母平均を含む」 と読む。
信頼区間の最大の誤解は 「この 1 本の区間に真の値が 95% の確率で入る」 という読み方です。 正しくは 「同じ手続きで標本抽出と区間作成を何度も繰り返すと、 作られた区間の約 95% が真の母平均を含む」。 下のシミュレータでこの頻度論的な被覆を目で確かめてください。
母集団は SSDSE-B-2026・2023 年度の 47 都道府県の消費支出(L3221、 二人以上の世帯、 千円/月)。 この 47 個を「既知の母集団」とみなし、 母平均 μ = 295.86 千円(紫の縦線)を真の値とします。 ここから標本サイズ n の標本を復元抽出し、 各標本の信頼区間を横棒で下へ積み上げます。 緑 = μ を含む、 赤 = μ を外す。 抽出を繰り返すほど、 μ を含む割合が信頼水準に近づくことを観察できます。
※ 乱数を使うため実行のたびに結果は変わります。 t 分布の臨界値は正則化不完全ベータ関数から算出(scipy.stats.t.ppf と小数第 4 位まで一致)。 標本数を数十〜数百と増やすほど、 被覆率は選んだ信頼水準(90 / 95 / 99%)に収束します。
scipy.stats.bootstrap)では消費支出のブートストラップ 95% CI ≈ [288.69, 302.46] と、 t 区間 [288.77, 302.94] がほぼ一致します。※ ベイズ統計の「信用区間(credible interval)」は「パラメータがこの区間に入る事後確率が 95%」と確率を直接パラメータに与える点で、 ここで扱う頻度論的信頼区間とは意味が異なります(数値は近くても解釈が別物)。
🍰 まずはやさしく
範囲を決めるための「計算式」です。
正確な幅を数字で出すために使います。
買い物の予算を計算して範囲を決めるようなものです。
この章では信頼区間を求める数式について学びます。
$$ \bar{x} \pm z_{\alpha/2} \cdot \frac{\sigma}{\sqrt{n}} $$
$$ \bar{x} \pm t_{\alpha/2, n-1} \cdot \frac{s}{\sqrt{n}} $$
$$ \hat{p} \pm z_{\alpha/2} \sqrt{\frac{\hat{p}(1-\hat{p})}{n}} $$
$$ (\bar{x}_1 - \bar{x}_2) \pm t_{\alpha/2} \cdot SE $$
| 信頼水準 | α | z_{α/2} |
|---|---|---|
| 90% | 0.10 | 1.645 |
| 95% | 0.05 | 1.96 |
| 99% | 0.01 | 2.576 |
47都道府県の家計食料費(2023):n = 47、 平均 = 80.598千円、 標準偏差 s = 5.842千円。
合成データではなく公的統計を念頭に、 信頼区間の具体的計算手順を数値で示します。
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #4。主要な指標(係数・統計量・スコア)を算出します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 47 都道府県の平均寿命(仮想) 標本平均 x̄ = 84.55 年 標本標準偏差 s = 0.62 年 n = 47 # 標準誤差 SE = s / √n = 0.62 / √47 ≈ 0.0904 # t 分布の臨界値(df = 46、 α = 0.05) t(0.025, 46) ≈ 2.013 # 95% 信頼区間 CI_95 = x̄ ± t · SE = 84.55 ± 2.013 · 0.0904 = 84.55 ± 0.182 = [84.37, 84.73] → 「全 47 都道府県の真の平均寿命は 95% 信頼で 84.37〜84.73 年」 → 幅 0.36 年 |
📤 このブロックは標準出力には何も出さない
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #5。仮説検定・モデル評価を行います。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 | # 99% 信頼水準 t(0.005, 46) ≈ 2.687 CI_99 = 84.55 ± 2.687 · 0.0904 = 84.55 ± 0.243 = [84.31, 84.79] → 幅 0.49 年(95% より広い) → 信頼水準を上げると区間は広がる |
📤 このブロックは標準出力には何も出さない
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #6。結果を整形して表示します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # 仮想値 東日本(n=24):平均 84.3、 標準偏差 0.7 西日本(n=23):平均 84.8、 標準偏差 0.6 # 平均差の SE(Welch) SE_diff = √(0.7²/24 + 0.6²/23) = √(0.0204 + 0.0157) ≈ 0.190 # 自由度(Welch–Satterthwaite) df ≈ 44.5 # 95% 信頼区間(平均差) CI = (84.3 - 84.8) ± 2.014 · 0.190 = -0.50 ± 0.383 = [-0.883, -0.117] → 0 を含まないので有意(p < 0.05) → 「西日本は東日本より 0.12〜0.88 年長い(95% 信頼)」 |
📤 このブロックは標準出力には何も出さない
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #7。47都道府県データに当てはめて確認します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 47 都道府県中 38 県が人口減少(仮想) p̂ = 38/47 ≈ 0.809 n = 47 # Wald 法 SE_p = √(p̂(1-p̂)/n) = √(0.809·0.191/47) = √0.00329 ≈ 0.0573 CI_Wald = 0.809 ± 1.96 · 0.0573 = [0.696, 0.921] # Wilson 法(より精度高、 小標本で推奨) z² = 1.96² = 3.8416 center = (p̂ + z²/(2n)) / (1 + z²/n) = (0.809 + 0.0409) / (1 + 0.0817) ≈ 0.785 margin = (z/(1 + z²/n))·√(p̂(1-p̂)/n + z²/(4n²)) ≈ 0.1106 CI_Wilson = 0.785 ± 0.1106 ≈ [0.675, 0.896] # 比較 Wald : [0.696, 0.921](端で不安定) Wilson : [0.675, 0.896](より現実的) |
📤 このブロックは標準出力には何も出さない
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #8。比較・別パターンを検討します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 10 11 | # 粗死亡率(‰) ~ 高齢化率(%) の単回帰(2023年度、 47 都道府県) β̂ = 0.610(推定値) SE(β̂) = 0.022 # 95% 信頼区間 CI = 0.610 ± 2.013 · 0.022 = 0.610 ± 0.044 = [0.566, 0.654] → 0 を含まないので係数は有意 → 「高齢化率が 1% 上がると粗死亡率(人口千対)は 0.57〜0.65 ポイント上昇」 |
📤 このブロックは標準出力には何も出さない
合成データ x = [3, 5, 8, 2, 7](n=5)を代入し、 平均 x̄ ± t_{n-1, α/2} × s/√n を Step 1〜5 で展開する。 標本平均・標本標準偏差・標準誤差・自由度 4 の t 臨界値・上下限の順に手計算し、 同じ計算を Python(scipy.stats)で再現する。
$$ \bar{x} \pm t_{n-1,\,\alpha/2} \cdot \frac{s}{\sqrt{n}}, \qquad s = \sqrt{\frac{1}{n-1}\sum_{i=1}^n (x_i - \bar{x})^2} $$
母分散未知・標本サイズ小(n<30)の場合、 標準正規分布ではなく自由度 n-1 の t 分布の臨界値を使う。 α=0.05 で両側 95% 信頼区間を構成する。
| i | x_i |
|---|---|
| 1 | 3 |
| 2 | 5 |
| 3 | 8 |
| 4 | 2 |
| 5 | 7 |
| 項目 | 計算 | 結果 |
|---|---|---|
| Σx_i | 3 + 5 + 8 + 2 + 7 | 25 |
| x̄ | 25 / 5 | 5.0000 |
| i | x_i - x̄ | (x_i - x̄)² |
|---|---|---|
| 1 | -2 | 4 |
| 2 | 0 | 0 |
| 3 | 3 | 9 |
| 4 | -3 | 9 |
| 5 | 2 | 4 |
| 合計 | 0 | 26 |
| 項目 | 計算 | 結果 |
|---|---|---|
| s² = Σ偏差² / (n-1) | 26 / 4 | 6.5000 |
| s = √s² | √6.5 | 2.5495 |
| 項目 | 計算 | 結果 |
|---|---|---|
| SE = s / √n | 2.5495 / √5 = 2.5495 / 2.2361 | 1.1402 |
| 自由度 df | n - 1 = 5 - 1 | 4 |
| t_{4, 0.025}(両側 95%) | t 分布表より | 2.7764 |
| 誤差幅 = t × SE | 2.7764 × 1.1402 | 3.1656 |
| 項目 | 計算 | 結果 |
|---|---|---|
| 下限 | 5.0000 - 3.1656 | 1.8344 |
| 上限 | 5.0000 + 3.1656 | 8.1656 |
| 95% 信頼区間 | [1.8344, 8.1656] | — |
n=5 の小サンプルなので、 母平均の不確かさが大きく、 区間幅は約 6.33 と広い。 n が増えれば SE = s/√n が縮み、 区間も狭くなる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import numpy as np from scipy import stats # Step 1: データ x = np.array([3, 5, 8, 2, 7]) n = len(x) # Step 2: 標本平均 mean = x.mean() # Step 3: 標本標準偏差(ddof=1 で不偏) s = x.std(ddof=1) # Step 4: SE と t 臨界値 se = s / np.sqrt(n) df = n - 1 t_crit = stats.t.ppf(0.975, df) # 両側 95% → 上側 2.5% margin = t_crit * se # Step 5: 95% 信頼区間 lo = mean - margin hi = mean + margin print(f"x̄ = {mean:.4f}") print(f"s = {s:.4f}") print(f"SE = {se:.4f}") print(f"t_(df={df}, 0.025) = {t_crit:.4f}") print(f"誤差幅 = {margin:.4f}") print(f"95% CI = [{lo:.4f}, {hi:.4f}]") |
💬 手計算(Step 2: x̄=5.0、 Step 3: s=2.5495、 Step 4: SE=1.1402, t=2.7764, 誤差幅=3.1656、 Step 5: CI=[1.8344, 8.1656])と scipy.stats.t.ppf を使った Python 出力が完全一致。 自由度 4 の t 臨界値 2.7764 が、 標準正規の 1.96 より大きいことが、 小サンプルでの保守的な区間構成の根拠となる。
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #1。最初のスニペットです。SSDSE-B-2026 を読み込みます。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import pandas as pd import numpy as np from scipy import stats df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) data = df.loc[df['SSDSE-B-2026'] == 2023, 'L3221'].values / 1000 # 消費支出(千円) # 平均の95%信頼区間 def mean_ci(data, alpha=0.05): mean = np.mean(data) se = stats.sem(data) # 標準誤差 t_crit = stats.t.ppf(1 - alpha/2, df=len(data)-1) return mean - t_crit * se, mean + t_crit * se ci_low, ci_high = mean_ci(data) # scipy で一発 ci = stats.t.interval(0.95, df=len(data)-1, loc=np.mean(data), scale=stats.sem(data)) # ブートストラップ信頼区間 from scipy.stats import bootstrap res = bootstrap((data,), np.mean, confidence_level=0.95, random_state=0) print(f'ブートストラップ 95% CI: [{res.confidence_interval.low:.2f}, {res.confidence_interval.high:.2f}]') |
📤 実行例(実行時の標準出力) ブートストラップ 95% CI: [288.69, 302.46]
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #2。基本統計量を計算します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 | from statsmodels.stats.proportion import proportion_confint # 成功 30 / 試行 100 ci_low, ci_high = proportion_confint(count=30, nobs=100, alpha=0.05, method='wilson') print(f'Wilson 95% CI: [{ci_low:.4f}, {ci_high:.4f}]') |
📤 実行例(実行時の標準出力) Wilson 95% CI: [0.2189, 0.3958]
分布の仮定なしに信頼区間を計算する手法。 元データから復元抽出を繰り返し、 統計量の分布を直接シミュレーション:
正規分布の仮定が崩れる場合、 メディアンや分位数の CI を計算する場合に強力。 現代の標準ツール。
| 誤った解釈 | 正しい解釈 |
|---|---|
| 真値が95%CIに95%の確率で入る | 同じ手順で多くのCIを作れば、 95%が真値を含む |
| 95%CIの中の値は等しく確からしい | 中心付近のほうがより確からしい |
| 95%CIが0を含めば差はない | 差がない強い証拠ではない(検出力不足の可能性) |
CIの幅 = 2 × z × σ / √n。 これを左右する3要素:
「CIが広い」→ 推定の精度が低い、 サンプル不足の可能性。 「CIが狭い」→ 精度が高い推定。
ベイズ統計では「信用区間(credible interval)」が信頼区間に対応。 解釈がより直感的:
💡 ベイズの95%信用区間:「真値がこの範囲に入る確率が95%」。 頻度主義の信頼区間と違って、 直接的な確率表現が可能。
事前分布 + 尤度 → 事後分布 → 事後分布の2.5%〜97.5%が95%信用区間。
95%CIが特定値(例えば0)を含まない ⇔ 両側5%水準でその値が棄却される。 つまりCIと検定は表裏一体。
CIの幅は推定精度の指標。 半分の幅にしたければ、 サンプルサイズを4倍にする(√n則)。
近代的な統計報告では点推定 + 95%CI + 効果量を併記するのが標準(APA 7版マニュアル、 ASA声明)。
| 対象 | 95%CI公式 |
|---|---|
| 平均(σ既知) | x̄ ± 1.96·σ/√n |
| 平均(σ未知) | x̄ ± t(n-1)·s/√n |
| 比率 | p̂ ± 1.96√(p̂(1-p̂)/n) |
| 分散 | [(n-1)s²/χ²_(α/2), (n-1)s²/χ²_(1-α/2)] |
| 2平均差 | (x̄₁-x̄₂) ± t·SE |
| 相関係数 | Fisher's z変換ベース |
| 回帰係数 | β̂ ± t·SE(β̂) |
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #9。ハイパーパラメータを変えて再計算します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import pandas as pd import numpy as np from scipy import stats df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) x = df.loc[df['SSDSE-B-2026'] == 2023, 'L3221'].dropna().values / 1000 # 消費支出(千円) # t 区間 mean = x.mean() sem = stats.sem(x) # 標準誤差 ci_low, ci_high = stats.t.interval(0.95, df=len(x)-1, loc=mean, scale=sem) print(f'平均 = {mean:.2f}, 95% CI = [{ci_low:.2f}, {ci_high:.2f}]') # z 区間(母分散既知の場合) z_low, z_high = stats.norm.interval(0.95, loc=mean, scale=sem) print(f'z CI = [{z_low:.2f}, {z_high:.2f}]') |
📤 実行例(実行時の標準出力) 平均 = 295.86, 95% CI = [288.77, 302.94] z CI = [288.95, 302.76]
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #10。最終結果のまとめ・保存を行います。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 | from statsmodels.stats.proportion import proportion_confint # 2023年度、 47 都道府県中 45 県が前年(2022年度)より総人口減少 count = 45 n = 47 for method in ['normal', 'wilson', 'beta', 'agresti_coull']: ci = proportion_confint(count, n, alpha=0.05, method=method) print(f'{method:15s}: [{ci[0]:.4f}, {ci[1]:.4f}]') |
📤 実行例(実行時の標準出力) normal : [0.8997, 1.0000] wilson : [0.8575, 0.9883] beta : [0.8546, 0.9948] agresti_coull : [0.8496, 0.9962]
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #11。可視化を仕上げ、レポートに統合します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import pandas as pd # df2023 はこのあとのブロックで作っているので、ここでも用意しておく df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df2023 = df[df['SSDSE-B-2026'] == 2023] from statsmodels.stats.weightstats import CompareMeans, DescrStatsW # 便宜上、 地域コード R24000(三重県)以東を東日本とする(東 24 県・西 23 県) east = df2023.loc[df2023['Code'] <= 'R24000', 'L3221'] / 1000 west = df2023.loc[df2023['Code'] > 'R24000', 'L3221'] / 1000 cm = CompareMeans(DescrStatsW(east), DescrStatsW(west)) ci = cm.tconfint_diff(usevar='unequal', alpha=0.05) print(f'平均差の 95% CI = [{ci[0]:.3f}, {ci[1]:.3f}]') |
📤 実行例(実行時の標準出力) 平均差の 95% CI = [9.337, 34.867]
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #12。追加検証・感度分析を実行します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 10 11 | from scipy.stats import bootstrap # 平均値のブートストラップ CI(パーセンタイル法) res = bootstrap((x,), np.mean, confidence_level=0.95, n_resamples=10000, method='percentile', random_state=0) print(f'パーセンタイル: [{res.confidence_interval.low:.3f}, {res.confidence_interval.high:.3f}]') # BCa 法(バイアス補正 + 加速) res_bca = bootstrap((x,), np.mean, confidence_level=0.95, n_resamples=10000, method='BCa', random_state=0) print(f'BCa: [{res_bca.confidence_interval.low:.3f}, {res_bca.confidence_interval.high:.3f}]') |
📤 実行例(実行時の標準出力) パーセンタイル: [288.873, 302.577] BCa: [288.695, 302.457]
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #13。応用パターン(別データ・別手法)に拡張します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 10 | import statsmodels.api as sm d = df2023.assign(高齢化率 = df2023['A1303'] / df2023['A1101'] * 100, 粗死亡率 = df2023['A4200'] / df2023['A1101'] * 1000) X = sm.add_constant(d[['高齢化率']]) y = d['粗死亡率'] model = sm.OLS(y, X).fit() print('係数 CI:') print(model.conf_int(alpha=0.05)) |
📤 実行例(実行時の標準出力)
係数 CI:
0 1
const -6.573784 -3.762576
高齢化率 0.565729 0.654249🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #14。実務での落とし穴対策を実装します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import numpy as np from scipy import stats x_sorted = np.sort(x) n = len(x_sorted) # 中央値の漸近 95% CI(n 大の場合) median = np.median(x_sorted) ci_idx_low = int(np.floor(n/2 - 1.96*np.sqrt(n)/2)) ci_idx_high = int(np.ceil(n/2 + 1.96*np.sqrt(n)/2)) print(f'中央値 = {median:.2f}') print(f'95% CI ≈ [{x_sorted[ci_idx_low]:.2f}, {x_sorted[ci_idx_high]:.2f}]') # ブートストラップでの中央値 CI res = stats.bootstrap((x,), np.median, confidence_level=0.95, n_resamples=10000, method='percentile', random_state=0) print(f'ブートストラップ中央値 CI: [{res.confidence_interval.low:.2f}, {res.confidence_interval.high:.2f}]') |
📤 実行例(実行時の標準出力) 中央値 = 300.65 95% CI ≈ [294.54, 306.54] ブートストラップ中央値 CI: [294.84, 305.54]
🎯 このコードでやること:信頼区間 — 母平均が含まれると推定される区間に関連するステップ #15。出力結果を解釈・考察します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df2023 = df[df['SSDSE-B-2026'] == 2023]
# 2023年度47都道府県の消費支出 L3221(二人以上の世帯、 円/月)を母集団とみなし、 平均の 95% CI を計算
# df2023[['Prefecture','L3221']].head():
# Prefecture L3221
# 0 北海道 296888
# 12 青森県 263371
# 24 岩手県 298536
# 36 宮城県 305541
# 48 秋田県 2720861 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import statsmodels.api as sm # 転出超過(転出者数 A5102 > 転入者数 A5101)か否かを 2 値の目的変数に X = sm.add_constant(pd.DataFrame({ '高齢化率': df2023['A1303'] / df2023['A1101'] * 100, '消費支出': df2023['L3221'] / 1000})) y = (df2023['A5102'] > df2023['A5101']).astype(int) model = sm.Logit(y, X).fit() # 係数と CI params = model.params conf = model.conf_int() # 指数変換してオッズ比とその CI or_table = pd.DataFrame({ 'OR': np.exp(params), 'OR_CI_low': np.exp(conf[0]), 'OR_CI_high': np.exp(conf[1]) }) print(or_table) |
📤 実行例(実行時の標準出力)
Optimization terminated successfully.
Current function value: 0.190567
Iterations 9
OR OR_CI_low OR_CI_high
const 0.002118 5.087428e-11 88138.979013
高齢化率 2.117222 1.191540e+00 3.762045
消費支出 0.955091 8.980132e-01 1.015797信頼区間(confidence interval, CI)は、 「母数(真の平均など)が一定の確率で含まれる範囲」。 推測統計の中心概念。
20回の試行で計算した95%CI。 約95%(19/20)が真の平均(破線)を含むのが正しい解釈。
⚠️ よくある誤解:「95%CI に真値が95%の確率で入る」→ 不正確。 正しくは「同じ方法で多くの標本から CI を計算すれば、 95%の CI が真値を含む」。 1つの CI に対しては入っているか入っていないかどちらかであり、 確率ではない。
信頼区間は推測統計の基礎ツールですが、 解釈を誤ると科学的判断を歪める危険があります。 適用前に下表のチェックリストで前提を確認しましょう。
| 条件 | 満たさない場合の影響 | 代替手法 |
|---|---|---|
| 標本がランダム抽出されている | CI が母集団を代表せず、 系統誤差で偏る | 層別抽出/補正法 |
| 独立同分布 (iid) が成り立つ | SE が過小評価、 CI が狭すぎる | クラスター頑健 SE |
| 標本サイズが十分大きい (n≥30 目安) | 正規近似が成立せず、 CI が誤る | t 分布 / ブートストラップ |
| 外れ値が極端でない | 平均と SE が歪み、 CI が信頼できない | 中央値 + ロバスト CI |
| 事前に仮説と n を決めている | p-hacking で false positive 増加 | 事前登録/Bonferroni 補正 |
| 誤解 | 正しい解釈 |
|---|---|
| 「真の値が 95%CI に入る確率は 95%」 | 真の値は固定。 「同じ手順で 100 回区間を作れば 95 回は真の値を含む」が正 |
| 「95%CI が 0 を含まない = 効果あり」 | 統計的有意 ≠ 実用上意味のある効果。 効果サイズも要検討 |
| 「2 つの CI が重なれば差なし」 | 重なっても有意差があることはある。 差の CI を直接計算すべき |
| 「CI が狭い = 正確」 | 系統誤差 (バイアス) は CI に反映されない。 narrow ≠ accurate |
| 「信頼水準を上げれば判断が確実」 | 99%CI は 95%CI より広い → 検出力低下のトレードオフ |
statsmodels の関数。 ブートストラップなら scipy.stats.bootstrap| 手法 | 目的 | 出力 | 主な用途 |
|---|---|---|---|
| 信頼区間 | 母数の範囲推定 | 区間 [a, b] | 点推定の不確実性表示 |
| p 値 | 帰無仮説検定 | 確率 (0-1) | 有意差判定 |
| ベイズ信用区間 | 事後分布の HDI | 区間 + 確率解釈 | 直感的な確率解釈が必要な場合 |
| 予測区間 | 将来観測値の範囲 | 区間 [a, b] (広い) | 個別予測の不確実性表示 |
| ブートストラップ CI | 分布フリーな区間推定 | 区間 [a, b] | 非正規分布や小標本 |
📤 読み方: 信頼区間は「母数 (定数) を含むかどうか」、 予測区間は「次の観測値が入るかどうか」と区別する。 予測区間は CI より常に広い (個別観測の散らばりが加わるため)。
これは最も頻繁な誤解です。 頻度論的な正しい解釈は「同じ手続きを多数回繰り返したとき、 作られる信頼区間のうち 95% が真値を含む」。 個別の区間 [84.37, 84.73] に対して「真値が 95% の確率で入る」は誤り(真値は確率変数ではなく定数)。 「真値が確率的に区間に入る」と言いたいならベイズの事後信用区間を使うべきです。
母分散が未知で n が小さいときは必ず t 分布を使うべきです。 例:n = 10 の場合、 95% 信頼区間の臨界値は t(0.025, 9) = 2.262 で、 正規(1.96)より 15% 広い。 これを正規で計算すると信頼区間が狭すぎ、 真の母平均を含む確率は 95% 未満になります。 scipy なら `stats.t.interval` で正しく計算可能。
t 分布の信頼区間は「データが正規分布」または「N が十分大」を仮定します。 強い歪み(人口、 所得、 売上)や外れ値があると、 N が中程度でもカバレッジが狂います。 対策は (i) 対数変換、 (ii) Wilcoxon 区間、 (iii) ブートストラップ信頼区間。 ブートストラップは分布仮定なしで頑健に区間を出せます。
Wald 法は p̂ が 0 や 1 に近いと区間が [0, ?] や [?, 1] を超える病的振る舞い。 例:p̂ = 0.95、 n = 20 で Wald なら [0.854, 1.046] と上限が 1 を超える。 対策は Wilson 法、 Clopper-Pearson 法、 Agresti-Coull 補正。 sklearn には直接ないが statsmodels の `proportion_confint` で複数選択可能。
2 群の信頼区間が重なっていても、 差の信頼区間が 0 を含まないことがあります。 これは数学的に証明可能で、 1 群の CI を重ねて判断するのは誤り。 必ず「差の検定」または「差の信頼区間」で判断してください。 概ね、 各群の SE の √2 倍が差の SE のため、 個別 CI が重なっても差は有意になり得ます。
20 個の信頼区間をそれぞれ 95% で作ると、 少なくとも 1 つで真値を外す確率は 1 − 0.95²⁰ ≈ 64%。 多重比較問題は信頼区間にも当てはまります。 family-wise coverage を保ちたいなら、 Bonferroni 補正(α/m)、 同時信頼区間(Tukey HSD、 Scheffé)を使う必要があります。
多くの変数を解析し、 結果を見てから一部だけ報告すると、 選択バイアスで報告された CI のカバレッジ確率が大きく崩れます。 「post-selection inference」の問題で、 通常の方法ではバイアスが残ります。 対策は事前登録、 全変数の報告、 selective inference や conditional CI など先進的手法。
信頼区間 がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。
🌐 統計・データサイエンス › 推測統計 › 推定 › 信頼区間
中心に 信頼区間 を置き、 そこから p値・標準誤差・正規分布・標準偏差・標本サイズ・平均推定 など 計 16 個の用語へ、 前提・兄弟・発展形といった関係を矢印で結んでいます。 線がどちら向きかを見れば、 先に読むべき用語とあとから読む用語が分かります。 ノードはドラッグで動かせ、 ホイールでズーム、 クリックでその用語のページへ遷移します。
大きな円が小さな円を包含する Circle Packing 図。 「信頼区間」は緑色でハイライト。
長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「信頼区間」は緑色でハイライト。
| マップ | 分かること | こんな時に見る |
|---|---|---|
| 🔗 関係マップ | 手法間の横の関係(前提→発展→応用) | 「次に何を学べばよい?」 学習順序の判断 |
| ⭕ 包含マップ | 分類体系の入れ子構造(上位⊃下位) | 「この手法はどんなジャンルに属する?」 |
| 🌳 ツリーマップ | 分野の規模比較(面積=ボリューム) | 「データサイエンス全体の俯瞰像」 |
💡 3 つの図は同じ位置関係を別の角度から描いています。 関係マップは 信頼区間 の隣に何が並ぶかを、 包含マップとツリーマップは 統計・データサイエンス → 推定 → 信頼区間 という入れ子の位置を示します。 「推定には他に何があったか」を思い出したいときは包含マップを、 「次に何を読むか」を決めたいときは関係マップを開いてください。
「信頼区間」は推定値の不確実性を範囲で示す指標で、 上流の標準誤差計算と下流の仮説検定 (p 値) との整合を取らないと、 「95% 信頼区間に 0 を含むのに有意」のような矛盾報告が出る。
上流で標本サイズと標準誤差を整え、 並列のブートストラップ CI と理論 CI を比較し、 下流の仮説検定・効果量と同時に報告すれば、 SSDSE 都道府県の平均値推定や差の検定を統一的に解釈できる。
「confidence interval」を含む手法選択は、 データの性質・分析目的・運用制約の 3 軸で決まる。 以下に典型シナリオと対応する手法の組合せを示す。
| シナリオ | 重視する観点 | 候補手法 |
|---|---|---|
| データが大規模 (n が多い、 高次元) | 計算コスト / メモリ / 並列化が必要 | 標準手法 等 |
| 外れ値が多い / ノイズあり | 頑健性 / 外れ値除去 / 中央値ベース | 高速版 等 |
| 解釈性を重視する | 線形 / 木構造 / ルールベース | 頑健版 等 |
| 予測精度を最優先する | アンサンブル / ハイパラ調整 / 交差検証 | 高次元対応版 等 |
| データが少ない | 正則化 / ベイズ / 転移学習 / 簡素なモデル | 小データ向け 等 |
| リアルタイム/オンライン処理 | ストリーミング / 軽量モデル / 逐次更新 | 解釈重視版 等 |
このページでは 47 都道府県の消費支出(L3221、 2023 年度)から 95% 信頼区間 [288.77, 302.94] を計算しました。 ここで一歩立ち止まって考えたいのが、 「47 都道府県は標本なのか、 それとも母集団そのものなのか」という問いです。 日本の都道府県は 47 しかなく、 SSDSE にはその全部が入っています。 「48 番目の都道府県」を将来抽出することはできません。 全数データに信頼区間を付けるとき、 その区間は何を推定しているのかを意識すると、 信頼区間の理解が一段深まります。
同じ数値 [288.77, 302.94] でも、 分析の枠組みによって意味がまったく違います。
上の 🎮 シミュレータは、 47 県を「既知の母集団」と宣言したうえで復元抽出する枠組み C の練習装置でした。 論文やレポートで CI を報告するときは、 自分がどの枠組みで語っているのかを明示するのが誠実な書き方です。
stats.t.interval を回して「母平均の 95% CI は [288.77, 302.94]」と書くと、 存在しない抽出誤差を捏造したことになります。 CI を付けるなら「超母集団の期待値を推定している」(枠組み B)と目的を書き換える必要があります。枠組み B(超母集団)を採用した場合、 信頼水準を上げる「値段」がどれくらいかを、 同じ実データ(L3221、 2023 年、 n = 47、 平均 295.86 千円、 SE = 3.52 千円)で並べると次のとおりです。
| 信頼水準 | t 臨界値 (df=46) | 区間(千円) | 幅(千円) |
|---|---|---|---|
| 90% | 1.679 | [289.94, 301.77] | 11.82 |
| 95% | 2.013 | [288.77, 302.94] | 14.18 |
| 99% | 2.687 | [286.39, 305.32] | 18.93 |
95% → 99% で外す確率を 1/5(5% → 1%)にする代償は幅 +34%(14.18 → 18.93 千円)。 「確実さの購入コスト」が具体的な金額の幅で見えます(値はすべて SSDSE-B-2026 実測に基づく計算値)。