95%信頼区間とは同じ調査やサンプリングを100回繰り返して信頼区間を計算した場合、
そのうち約95回の区間が真の値を含むという意味。
「真の値がこの区間に入る確率が95%である」という意味ではない。真の値は不動。
2標本t検定など平均値の差の検定において、95%信頼区間に基準値「0」を跨いでいなければ、
統計的に有意な差がある(p < 0.05)と判断。
カイ2乗検定などのオッズ比であれば「1」を跨いでいなければ、統計的に有意な差がある(p < 0.05)と判断。
信頼区間の幅が広いということは
推測した数値の「不確実性(ばらつきや誤差)が大きく、真の値がどこにあるのかハッキリと絞り込めていない状態。
・不確実性が高い: 推定した値の精度が低く、幅を持たせた大まかな予測にすぎない。
・「真の値」の絞り込み不足: 平均や割合などの本当の値(母数)がこの範囲にあるとはいえるものの、範囲が広すぎて具体的な値が特定できていない。
原因
・サンプルサイズ(標本数)が少ない
・データのばらつき(分散)が大きい
・信頼水準(信頼係数)を高めに設定している
平均値の差
ある「新しい薬」の効果を調べるために、【新薬を飲んだグループ】と【偽薬(プラセボ)を飲んだグループ】で血圧のの下がり方を比較したとします。
もし、2つのグループに全く差がない(効果がない)なら、「新薬の平均 – 偽薬の平均 = 0」になるはずです。これが基準値(0)の意味です。
❌ 0を跨いでいるケース計算した信頼区間: [ -2 から +5 ]
イメージ: この結果は、「新薬の方が血圧が2上がってしまう可能性もあるし、逆に5下がる可能性もある」という非常にあやふやな状態です。
結論: 区間の中に「0(差がない)」が含まれてしまっているため、「統計的に有意な差があるとは言えない(p ≧ 0.05)」と判断します。
⭕ 0を跨いでいない(効果があると言い切れる)ケース計算した信頼区間: [ +3 から +8 ]
イメージ: 一番低く見積もっても「3」は下がるし、高ければ「8」下がるという意味です。
どこをどう取ってもプラス(効果あり)の側に振れています。
結論: 区間が「0」を完全に超えて(跨いで)いないため、「統計的に有意な差がある(p < 0.05)」、つまり新薬には効果があると言えます。
オッズ比
割り算(倍率)で「リスクが何倍になるか。
リスクが全く同じなら、「Aのリスク ÷ Bのリスク = 1」になる。
❌ 1を跨いでいる(影響があるとは言えない)ケース
計算した信頼区間: [ 0.7倍 から 1.5倍 ]
イメージ: リスクが0.7倍(下がる)かもしれないし、1.5倍(上がる)かもしれないという状態です。
結論: 区間の中に「1(同じ)」が含まれているため、その要因がリスクを高めている(あるいは下げている)とは言えません。
⭕ 1を跨いでいない(影響があると言い切れる)ケース
計算した信頼区間: [ 1.2倍 から 2.5倍 ]
イメージ: 最低でも1.2倍、高ければ2.5倍はリスクが上がるという意味です。
結論: 区間が「1」を跨いでいない(常に1より大きい)ため、「統計的に有意にリスクを高めている」と言い切れます。
2群の平均値の差に対するt検定(独立な2群)と、その平均値の差の95%信頼区間
SciPyライブラリの scipy.stats や statsmodels を使う。
import numpy as np
from scipy import stats
# データ準備(例:A群とB群)
group_a = np.array([18, 21, 23, 19, 22, 25, 20])
group_b = np.array([14, 16, 15, 12, 17, 13, 15])
# 1. 平均値とサンプルサイズ、不偏分散の計算
mean_a, mean_b = np.mean(group_a), np.mean(group_b)
n_a, n_b = len(group_a), len(group_b)
var_a, var_b = np.var(group_a, ddof=1), np.var(group_b, ddof=1)
# 平均値の差
mean_diff = mean_a - mean_b
# 2. ウェルチのt検定(等分散を仮定しない場合)
# scipy.stats.ttest_ind を使用
res = stats.ttest_ind(group_a, group_b, equal_var=False)
# 3. 95%信頼区間の計算(ウェルチの自由度を使用)
se_diff = np.sqrt(var_a / n_a + var_b / n_b) # 差の標準誤差
df = res.df # 自由度
t_crit = stats.t.ppf(0.975, df) # t分布の上側2.5%点
ci_lower = mean_diff - t_crit * se_diff
ci_upper = mean_diff + t_crit * se_diff
print(f"平均値の差: {mean_diff:.4f}")
print(f"t統計量: {res.statistic:.4f}, p値: {res.pvalue:.4f}")
print(f"95%信頼区間: [{ci_lower:.4f}, {ci_upper:.4f}]")
カイ二乗
SciPyライブラリの stats.chi2.ppf を使ってカイ二乗分布のパーセンタイルを求める。
import numpy as np
import scipy.stats as stats
# サンプルデータ
data = np.array([10.1, 10.2, 9.8, 10.0, 9.9, 10.3, 10.1, 9.7, 10.0, 10.1])
n = len(data)
var_sample = np.var(data, ddof=1) # 不偏分散
alpha = 0.05 # 有意水準5%(95%信頼区間)
# 自由度
df = n - 1
# カイ二乗分布の下側・上側分位点
chi2_lower = stats.chi2.ppf(1 - alpha / 2, df)
chi2_upper = stats.chi2.ppf(alpha / 2, df)
# 母分散の信頼区間
ci_lower = (df * var_sample) / chi2_lower
ci_upper = (df * var_sample) / chi2_upper
print(f"不偏分散: {var_sample:.4f}")
print(f"母分散の95%信頼区間: [{ci_lower:.4f}, {ci_upper:.4f}]")
