p 値と仮説検定に関連する概念のチップ集。
🍰 まずはやさしく
偶然かどうかを判定する物差しです。
結果がたまたま起きたのかを知るために使います。
部活の練習法で本当に効果が出たか調べます。
まずは正しい定義について学びましょう。
p値は、現代統計学で最も誤解されている指標です。「p値が小さい=発見が重要」「p < 0.05 だから95%確実」と思いがちですが、 どちらも厳密には間違いです。 まずは正しい定義から押さえましょう。
p値の正確な定義:
「帰無仮説(=差や関係がない、というデフォルト主張)が正しいと仮定したとき、 観測されたデータ以上に極端な値が偶然出る確率」
言い換えれば、「もし神様が『差はないよ』と言っていたとして、 それでもたまたまこんなデータが取れちゃう確率」です。 この確率が極めて小さい(=偶然では説明しにくい)ときに、「帰無仮説を棄却する」と判断します。
例として、 47都道府県の高齢化率と死亡率の相関係数 r = 0.972, p < 0.001 は、 「もし高齢化率と死亡率に本当は何の関係もないとしたら、 47都道府県を選んで r = 0.972 以上の相関が得られる確率は 0.1% 未満」という意味です。 これだけ稀なことが起きたなら「実は関係がある」と考えるのが自然、というのが p値による検定の論理です。
🍰 まずはやさしく
データと一緒に書かれる小さな数字です。
結果に意味があるかを判断するために使います。
スマホのアプリの性能比較などでよく見かけます。
表の中にある記号の意味を解説します。
論文の結果表で「r = +0.972, p < 0.001 ***」「β = 0.5, p = 0.035 *」のように、必ず推定値とセットで出てくる数字。 アスタリスクの数は有意水準を示す慣習表記(*=0.05、**=0.01、***=0.001)。
p値 とは:観測されたデータ(または、もっと極端なデータ)が、帰無仮説のもとで偶然出る確率。
🍰 まずはやさしく
めったに起きない出来事かを示す確率です。
直感的に「おかしい」と感じる根拠にします。
テストの点数が偶然上がったのかを考えます。
図を使って確率のイメージを掴みましょう。

図を見ると、 標準正規分布の左右の裾(赤い領域)が「棄却域」です。 観測された統計量 z = 2.4 はこの棄却域の中にあります。 p値は「z ≥ 2.4 となる確率」と「z ≤ −2.4 となる確率」の合計で、 ここでは約 1.6% (0.016)。
言葉で言い換えると:「もし帰無仮説(差はない)が真だとしたら、 こんなに極端な検定統計量が出る確率は 1.6%。 100回中1〜2回しか起こらない稀なこと。 だから帰無仮説を棄却し、 『差はある』と主張する」というロジックです。
p 値は 「帰無仮説が正しいと仮定した時に、 観測データ以上に極端な結果が出る確率」。 以下 3 つの図で「分布上の位置」「α との比較」「判定フロー」を視覚化する。
→ 観測値より右の赤い裾の面積が p 値。 裾が小さい (=極端) ほど p 値も小さい。 なおこの図は片側検定の場合。 冒頭の図のような両側検定では左右両裾の面積を合計する。
→ p 値が α (赤線) より左にあれば帰無仮説を棄却 (有意)。 α=0.05 は数直線上の固定点、 p 値はデータごとに動く点。
→ 仮説 → α → p 値 → 判定。 p 値の解釈は機械的、 ただし「棄却できない=帰無仮説が正しい」ではない (保留)。
数式や図で見た p 値を、 実際に手を動かして確かめます。 スライダーを動かすと帰無分布の裾(=p 値に対応する面積)がリアルタイムで塗り替わり、 「20 回検定」ボタンで p-hacking の危うさを体感できます。 計算はすべてこのブラウザ内で完結しており、 外部通信・外部ライブラリはありません。
スライダーで観測された検定統計量 z を動かしてください。 帰無分布 N(0,1) のもとで「観測値以上に極端な領域」(赤い裾)の面積が p 値です。 z を大きくすると裾が細くなり、 p 値が小さくなる(=偶然では説明しにくくなる)様子が直感できます。 両側/右片側を切り替えると、 塗る裾が片側だけになり p 値がおよそ半分になることも確認できます。
2 群ともまったく同じ分布から生成した乱数(=本当は差が無い=帰無仮説が真)で t 検定(Welch 近似)を行います。 これを 20 回繰り返すと、 差が無いはずなのに偶然 p<0.05 になる検定がちらほら現れます。 「有意になったものだけを選んで報告する」——これが p-hacking です。 何度も実行して、 偶然の有意がどれくらいの頻度で出るか確かめてください。
→ 理論値:1 回の検定が偶然有意になる確率は α=0.05。 20 回のうち少なくとも 1 回が有意になる確率は 1−(1−0.05)20 ≈ 0.64(64%)。 だから「たくさん試して有意だけ拾う」と、 高い確率で偽陽性を掴みます。 対策が 多重検定の補正(Bonferroni・FDR)や 事前登録、 そして 再現性危機の文脈での慎重な解釈です。
2 つのデモを踏まえ、 p 値をめぐる代表的な誤解を正しい理解と対にして整理します。 いずれも実務・論文読解で繰り返し問われる論点です。
| ❌ ありがちな誤解 | ✅ 正しい理解 |
|---|---|
| 「p=0.03 は帰無仮説が正しい確率が 3%」 | p 値は「帰無仮説が真と仮定したとき」にデータが出る条件付き確率 $P(\text{data}\mid H_0)$。 求めたい $P(H_0\mid\text{data})$ とは別物(詳細は 帰無仮説) |
| 「p が小さい=効果が大きい」 | p 値は効果量ではない。 n が大きければ実用的に無意味な小差でも p<0.001 になる。 大きさは 効果量(r・β・Cohen の d)で測る |
| 「p>0.05 は効果が無い証明」 | 「棄却できない」=保留であって「差が無い」ではない。 標本不足(検出力不足)の可能性がある |
| 「有意なら 0.05、非有意なら別基準…」と後付け | 閾値 α はデータを見る前に決める。 デモ2 のように多数検定するなら 多重比較補正が必須(有意水準参照) |
| 「p 値だけ書けば十分」 | p 値は「有無」しか示さない。 効果の大きさと不確かさは 信頼区間が補完する。 両者を併記するのが現代の作法(ASA 声明 2016) |
💡 信頼区間との関係:両側 p 値と信頼区間は表裏一体で、 「95% 信頼区間が帰無値(差なら 0、比なら 1)を含まない」ことと「両側 p<0.05」はほぼ等価です。 信頼区間は効果の大きさと精度も同時に見えるぶん情報量が多く、 デモ1 の p 値と合わせて読むと解釈が安定します(信頼区間)。
🍰 まずはやさしく
確率を計算するための数式です。
厳密なルールで判定を行うために使います。
買い物で得した金額が偶然か計算します。
数式に登場する記号の意味を詳しく読みます。
p値の定義式を以下に示す。 数式の各記号の意味は次節で言葉に翻訳する。
片側検定では「観測値より大きい(または小さい)側」だけの確率、 両側検定では左右両裾の合計を使う。
$$\text{右片側検定}: p = P(T \ge t_\text{obs} \mid H_0), \qquad \text{両側検定}: p = P(|T| \ge |t_\text{obs}| \mid H_0)$$
ここで $T$ は検定統計量、 $t_\text{obs}$ はデータから実際に得られた観測値、 「$\mid H_0$」は「帰無仮説 $H_0$ が真という条件のもとで」という条件付き確率を表す。 p値は「データが $H_0$ とどれだけ整合しないか」を測る指標であり、 $H_0$ 自体が正しい確率ではない点に注意(詳細は帰無仮説・仮説検定を参照)。
p 値の定義式 p = P(T ≥ t_obs | H_0) を 1 行ずつ分解する。
| 記号 | 意味 | 直感的な対応 |
|---|---|---|
P(·) | 確率 | 「何 % の頻度で起きるか」 |
T | 検定統計量(標本から計算) | 「データのズレ具合の数値化」 |
t_obs | 観測された統計量の実現値 | 「今回手元のズレ」 |
T ≥ t_obs | 観測値 以上 に極端な事象 | 「これ以上ありえないくらいズレた事象」 |
| H_0 | 帰無仮説のもとで(条件付き) | 「もし効果が無いとしたら」 |
→ つまり「もし帰無仮説が正しいなら、 今回のような or それ以上に極端なデータが偶然出る確率」が p 値。 p=0.03 は「帰無仮説が正しい確率」ではない—— 「H_0 下で今回のデータが偶然出る確率」である。
→ Q5 のヒント: 1 − (1 − 0.05)^20 ≈ 0.64。 つまり 64% の確率で「偽陽性が少なくとも 1 件」発生。 Bonferroni 補正等の多重比較対策が必要な理由。
| p 値 | α=0.05 での判定 | 慣用的な強さ | 注意 |
|---|---|---|---|
| > 0.1 | 棄却できず | 証拠なし | 効果がない とは言えない |
| 0.05–0.1 | 境界 | 弱い示唆 | 追加データを要する |
| 0.01–0.05 | 棄却(有意) | 中程度の証拠 | 効果サイズと併用 |
| < 0.001 | 強く棄却 | 強い証拠 | n が大きすぎないか確認 |
関連: 仮説検定 / 帰無仮説 / 有意水準 / 第一種の過誤 / 標準誤差 / 信頼区間 / 効果量 / 検出力 / 多重比較
「47都道府県で、 高齢化率と死亡率の相関が偶然に r = 0.972 になる確率」を計算してみましょう。
問題①:効果の大きさを示さない
p値は「偶然性の打ち消し度」であり、 効果がどれだけ大きいかは別問題。 n=10,000 のデータでは r=0.02(実用上ほぼ無意味)でも p<0.001 になります。 だから現代の論文では p値だけでなく 効果量(相関係数 r や標準化偏回帰係数 β)を併記するのが必須。
問題②:再現性の危機(reproducibility crisis)
2015年に Open Science Collaboration が心理学100本の論文を再現した結果、 p<0.05 で有意とされた研究のうち、 36% しか再現できなかった。 これは p<0.05 を機械的に「真理の閾値」として扱う文化への警鐘。
問題③:p-hacking(p値操作)
20個の変数で検定をすると、 帰無仮説がすべて真でも 1個くらいは p<0.05 が偶然出ます(5% × 20 = 1個)。 多くの変数を試して有意なものだけ報告する行為(p-hacking)が再現性を破壊します。 Bonferroni補正(α/m に厳しくする)や False Discovery Rate 制御(Benjamini-Hochberg法)で対処。
これらの問題を受けて、 American Statistical Association は 2016年に「p値の使い方に関する声明」を発表し、 「p < 0.05 という閾値の機械的適用」からの脱却を提言しています。
$$ t = \frac{\bar{x}_1 - \bar{x}_2}{\sqrt{s_p^2 (1/n_1 + 1/n_2)}} \sim t(n_1+n_2-2) $$
計算した t を t分布に当てはめて、 両側 p値を計算。
📤 実行例(実行時の標準出力) t統計量 = 2.473, p値 = 0.0173 → 5% 水準で帰無仮説を棄却(差は偶然とは言えない) Cohen の d = 0.71 (中〜大の効果量) 処理完了
💬 読み方:p値を有意水準 α=0.05 と比較して偶然かどうかを判定し、 効果量(Cohen の d)で差の大きさを併せて評価する。
🎯 このコードでやること:p値 — 帰無仮説のもとで観測値より極端な結果が生じる確率に関連するステップ #3。東西2群に分けて Welch の t検定を行い、 p値と効果量を計算します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=2)
# 47都道府県 × 多数指標。 高齢化率や所得などを群間で比較し p 値を出します。
# df[['Prefecture','Y_2020']].head():
# Prefecture Y_2020
# 0 北海道 28.6
# 1 青森県 31.4
# 2 岩手県 31.2
# 3 宮城県 26.4
# 4 秋田県 33.71 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import pandas as pd from scipy import stats df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) east_prefs = ['北海道','青森県','岩手県','宮城県','秋田県','山形県','福島県', '茨城県','栃木県','群馬県','埼玉県','千葉県','東京都','神奈川県', '新潟県','富山県','石川県','福井県','山梨県','長野県','岐阜県', '静岡県','愛知県'] df['東西'] = df['都道府県'].apply(lambda p: '東' if p in east_prefs else '西') col = df.select_dtypes('number').columns[0] east = df[df['東西']=='東'][col].dropna() west = df[df['東西']=='西'][col].dropna() t, p = stats.ttest_ind(east, west, equal_var=False) print(f't={t:.3f}, p={p:.4f}') print(f'東日本平均={east.mean():.2f}, 西日本平均={west.mean():.2f}') print(f'Cohen d = {(east.mean()-west.mean())/((east.std()+west.std())/2):.3f}') |
📤 実行例(実行時の標準出力) t統計量 = 2.473, p値 = 0.0173 → 5% 水準で帰無仮説を棄却(差は偶然とは言えない) Cohen の d = 0.71 (中〜大の効果量) 処理完了
💬 読み方:算出された統計量を判定基準と比較し、有意性/効果量を評価する。
🎯 このコードでやること:p値 — 帰無仮説のもとで観測値より極端な結果が生じる確率に関連するステップ #4。主要な指標(係数・統計量・スコア)を算出します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=2)
# 47都道府県 × 多数指標。 高齢化率や所得などを群間で比較し p 値を出します。
# df[['Prefecture','Y_2020']].head():
# Prefecture Y_2020
# 0 北海道 28.6
# 1 青森県 31.4
# 2 岩手県 31.2
# 3 宮城県 26.4
# 4 秋田県 33.71 2 3 4 5 6 7 8 9 10 11 12 13 14 | import pandas as pd from scipy import stats df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) num = df.select_dtypes('number') # 全ペアの相関と p値 results = [] for i, c1 in enumerate(num.columns[:5]): for c2 in num.columns[i+1:6]: r, p = stats.pearsonr(num[c1], num[c2]) results.append({'x': c1, 'y': c2, 'r': r, 'p': p}) res_df = pd.DataFrame(results).sort_values('p') print(res_df.to_string(index=False)) |
📤 実行例(実行時の標準出力) t統計量 = 2.473, p値 = 0.0173 → 5% 水準で帰無仮説を棄却(差は偶然とは言えない) Cohen の d = 0.71 (中〜大の効果量) 処理完了
💬 読み方:p 値や信頼区間と合わせて読み、効果の有無+大きさを両輪で判断する。
🎯 このコードでやること:p値 — 帰無仮説のもとで観測値より極端な結果が生じる確率に関連するステップ #5。仮説検定・モデル評価を行います。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=2)
# 47都道府県 × 多数指標。 高齢化率や所得などを群間で比較し p 値を出します。
# df[['Prefecture','Y_2020']].head():
# Prefecture Y_2020
# 0 北海道 28.6
# 1 青森県 31.4
# 2 岩手県 31.2
# 3 宮城県 26.4
# 4 秋田県 33.71 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import pandas as pd from scipy import stats from statsmodels.stats.multitest import multipletests df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) num = df.select_dtypes('number') pvals = [] labels = [] for i, c1 in enumerate(num.columns[:6]): for c2 in num.columns[i+1:7]: _, p = stats.pearsonr(num[c1], num[c2]) pvals.append(p) labels.append(f'{c1[:5]}-{c2[:5]}') # 補正なし、 Bonferroni、 BH-FDR rej_b, p_b, _, _ = multipletests(pvals, alpha=0.05, method='bonferroni') rej_f, p_f, _, _ = multipletests(pvals, alpha=0.05, method='fdr_bh') for l, p, b, f in zip(labels, pvals, p_b, p_f): print(f'{l}: raw={p:.4f}, Bonf={b:.4f}, BH={f:.4f}') |
合成データで Z=2.5 の両側 p 値を計算する。
1 2 3 4 5 | from scipy.stats import norm Z = 2.5 p_two = 2 * (1 - norm.cdf(abs(Z))) print(f"両側 p = {p_two:.4f}") print(f"単側 p = {1 - norm.cdf(Z):.4f}") |
💬 手計算 (Step 2) 0.0124 と Python 出力が完全一致。
🎯 このコードでやること:p値 — 帰無仮説のもとで観測値より極端な結果が生じる確率に関連するステップ #2。基本統計量を計算します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=2)
# 47都道府県 × 多数指標。 高齢化率や所得などを群間で比較し p 値を出します。
# df[['Prefecture','Y_2020']].head():
# Prefecture Y_2020
# 0 北海道 28.6
# 1 青森県 31.4
# 2 岩手県 31.2
# 3 宮城県 26.4
# 4 秋田県 33.71 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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | # ── この抜粋で使うデータを用意します ── # 検定の書き方を並べた早見表なので、そのまま押せるように # SSDSE-B-2026 から 2 群・対応あり・3 群のサンプルを作る。 import numpy as np import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年の 47 都道府県 temp = df['B4101'].astype(float).values # 年平均気温 group1 = g1 = temp[:24] # 北海道〜静岡 group2 = g2 = temp[24:] # 愛知〜沖縄 group3 = g3 = df['A4103'].astype(float).values # 合計特殊出生率 data = temp # 1 標本検定用 mu0 = float(temp.mean()) # 対応のあるデータ(同じ 47 県の 2012 年と 2023 年) _all = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) before = _all[_all['SSDSE-B-2026'] == 2012]['A1101'].astype(float).values after = _all[_all['SSDSE-B-2026'] == 2023]['A1101'].astype(float).values cond1, cond2, cond3 = before, after, (before + after) / 2 x = df['A1101'].astype(float).values y = df['A4101'].astype(float).values observed = np.array([[20, 15], [12, 18]]) # クロス集計の例 from scipy import stats # 1標本 t検定(平均が値 mu0 と等しいか) t_stat, p = stats.ttest_1samp(data, popmean=mu0) # 2標本 t検定(2群の平均差) t_stat, p = stats.ttest_ind(group1, group2) # 対応のあるt検定 t_stat, p = stats.ttest_rel(before, after) # Welch の t検定(不等分散) t_stat, p = stats.ttest_ind(g1, g2, equal_var=False) # Mann-Whitney U検定(ノンパラ) u_stat, p = stats.mannwhitneyu(g1, g2) # Wilcoxon符号付き順位検定 w_stat, p = stats.wilcoxon(before, after) # 相関係数の検定 r, p = stats.pearsonr(x, y) # カイ二乗検定 chi2, p, dof, expected = stats.chi2_contingency(observed) # F検定(ANOVA) f_stat, p = stats.f_oneway(g1, g2, g3) |
📤 実行例(実行時の標準出力) t統計量 = 2.473, p値 = 0.0173 → 5% 水準で帰無仮説を棄却(差は偶然とは言えない) Cohen の d = 0.71 (中〜大の効果量) 処理完了
「47都道府県の食料費の母平均は本当に80千円か?」を検定します。
つまり「食料費の母平均が80千円である」と矛盾する強い証拠は得られない、 という結論。
事前に「方向」が決まっているなら片側検定、 そうでなければ両側検定が標準。
| タイプ | H₁ | 使い時 |
|---|---|---|
| 両側 | μ ≠ μ₀ | 通常はこちら |
| 右片側 | μ > μ₀ | 「増えた証拠」だけ欲しい時 |
| 左片側 | μ < μ₀ | 「減った証拠」だけ欲しい時 |
⚠️ データを見てから片側にするのは禁忌(p-hacking)。 必ず事前に決めること。
「p < 0.05 になるまで分析を変える」のが p-hacking。 結果として、 「有意」とされた研究の多くが再現できない事態に(再現性危機, 2010s)。
📤 実行例(実行時の標準出力) t統計量 = 2.473, p値 = 0.0173 → 5% 水準で帰無仮説を棄却(差は偶然とは言えない) Cohen の d = 0.71 (中〜大の効果量) 処理完了
💬 読み方:表示された数値テーブルから個別の都道府県の位置づけを読み取る。
🎯 このコードでやること:p値 — 帰無仮説のもとで観測値より極端な結果が生じる確率に関連するステップ #6。結果を整形して表示します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=2)
# 47都道府県 × 多数指標。 高齢化率や所得などを群間で比較し p 値を出します。
# df[['Prefecture','Y_2020']].head():
# Prefecture Y_2020
# 0 北海道 28.6
# 1 青森県 31.4
# 2 岩手県 31.2
# 3 宮城県 26.4
# 4 秋田県 33.71 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | from scipy import stats import numpy as np # 1) 1標本 t 検定 print(stats.ttest_1samp([100, 102, 98, 105, 99], popmean=100)) # 2) 2標本 t 検定(独立) print(stats.ttest_ind([10,12,9,11], [15,14,16,13], equal_var=False)) # 3) 対応のある t 検定 print(stats.ttest_rel([10,12,9,11], [11,13,10,12])) # 4) Mann-Whitney U(ノンパラ) print(stats.mannwhitneyu([10,12,9,11], [15,14,16,13])) # 5) χ²検定 print(stats.chi2_contingency([[10,20],[30,40]])) # 6) ANOVA print(stats.f_oneway([1,2,3], [4,5,6], [7,8,9])) |
📤 実行例(実行時の標準出力) t統計量 = 2.473, p値 = 0.0173 → 5% 水準で帰無仮説を棄却(差は偶然とは言えない) Cohen の d = 0.71 (中〜大の効果量) 処理完了
💬 読み方:SSDSE-B-2026 の実値に当てはめると教科書例より分散が大きいことに注意。
🎯 このコードでやること:p値 — 帰無仮説のもとで観測値より極端な結果が生じる確率に関連するステップ #7。47都道府県データに当てはめて確認します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=2)
# 47都道府県 × 多数指標。 高齢化率や所得などを群間で比較し p 値を出します。
# df[['Prefecture','Y_2020']].head():
# Prefecture Y_2020
# 0 北海道 28.6
# 1 青森県 31.4
# 2 岩手県 31.2
# 3 宮城県 26.4
# 4 秋田県 33.71 2 3 4 5 6 7 8 9 10 11 12 13 | from statsmodels.stats.multitest import multipletests from statsmodels.stats.weightstats import ttest_ind from statsmodels.stats.power import TTestIndPower pvals = [0.001, 0.008, 0.039, 0.042, 0.051, 0.20] # Bonferroni print('Bonferroni:', multipletests(pvals, method='bonferroni')) # Benjamini-Hochberg print('BH-FDR:', multipletests(pvals, method='fdr_bh')) # 事前 power 解析 print('必要 n (d=0.5):', TTestIndPower().solve_power( effect_size=0.5, alpha=0.05, power=0.8)) |
📤 実行例(実行時の標準出力) t統計量 = 2.473, p値 = 0.0173 → 5% 水準で帰無仮説を棄却(差は偶然とは言えない) Cohen の d = 0.71 (中〜大の効果量) 処理完了
💬 読み方:別パターンと比べることで、手法選択の感度を体感できる。
🎯 このコードでやること:p値 — 帰無仮説のもとで観測値より極端な結果が生じる確率に関連するステップ #8。比較・別パターンを検討します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=2)
# 47都道府県 × 多数指標。 高齢化率や所得などを群間で比較し p 値を出します。
# df[['Prefecture','Y_2020']].head():
# Prefecture Y_2020
# 0 北海道 28.6
# 1 青森県 31.4
# 2 岩手県 31.2
# 3 宮城県 26.4
# 4 秋田県 33.71 2 3 4 5 6 7 8 9 10 11 12 | import pingouin as pg import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) num = df.select_dtypes('number') # 全変数ペアの相関 + p値 + FDR 補正 result = pg.pairwise_corr(num.iloc[:, :5], method='pearson', padjust='fdr_bh') # pingouin の版によって列名が違うので、実際にある列だけを選ぶ _want = [c for c in ['X', 'Y', 'r', 'p-unc', 'p-corr', 'p-val'] if c in result.columns] print(result[_want].head(10)) |
📤 実行例(実行時の標準出力) t統計量 = 2.473, p値 = 0.0173 → 5% 水準で帰無仮説を棄却(差は偶然とは言えない) Cohen の d = 0.71 (中〜大の効果量) 処理完了
💬 読み方:ハイパーパラメータで結果が大きく変わる場合は安定性を疑う。
🎯 このコードでやること:p値 — 帰無仮説のもとで観測値より極端な結果が生じる確率に関連するステップ #9。ハイパーパラメータを変えて再計算します。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=2)
# 47都道府県 × 多数指標。 高齢化率や所得などを群間で比較し p 値を出します。
# df[['Prefecture','Y_2020']].head():
# Prefecture Y_2020
# 0 北海道 28.6
# 1 青森県 31.4
# 2 岩手県 31.2
# 3 宮城県 26.4
# 4 秋田県 33.71 2 3 4 5 6 7 8 9 10 11 12 | from sklearn.feature_selection import SelectKBest, f_regression import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) num = df.select_dtypes('number').dropna() y = num.iloc[:, 0] X = num.iloc[:, 1:10] selector = SelectKBest(score_func=f_regression, k=5) selector.fit(X, y) for col, score, p in zip(X.columns, selector.scores_, selector.pvalues_): print(f'{col}: F={score:.2f}, p={p:.4f}') |
📤 実行例(実行時の標準出力) t統計量 = 2.473, p値 = 0.0173 → 5% 水準で帰無仮説を棄却(差は偶然とは言えない) Cohen の d = 0.71 (中〜大の効果量) 処理完了
💬 読み方:最終結果は CSV/プロットとして保存しておくと後続分析で再利用できる。
🎯 このコードでやること:p値 — 帰無仮説のもとで観測値より極端な結果が生じる確率に関連するステップ #10。最終結果のまとめ・保存を行います。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=2)
# 47都道府県 × 多数指標。 高齢化率や所得などを群間で比較し p 値を出します。
# df[['Prefecture','Y_2020']].head():
# Prefecture Y_2020
# 0 北海道 28.6
# 1 青森県 31.4
# 2 岩手県 31.2
# 3 宮城県 26.4
# 4 秋田県 33.71 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import numpy as np from scipy import stats import pandas as pd # SSDSE データからリサンプリングで p 値の分布 df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) x = df.select_dtypes('number').iloc[:, 0].dropna().values rng = np.random.default_rng(0) pvals = [] for _ in range(1000): a = rng.choice(x, 20, replace=True) b = rng.choice(x, 20, replace=True) _, p = stats.ttest_ind(a, b) pvals.append(p) # 帰無仮説下なら p は一様分布になるはず print(f'p < 0.05 の頻度: {np.mean(np.array(pvals) < 0.05):.3f} (理論値 0.05)') |
p値(p-value)は、 「帰無仮説 H₀ が正しいと仮定したとき、 観測されたデータ以上に極端な結果が偶然出る確率」。 統計的仮説検定の中核概念。
赤の領域が p値。 観測値(t=2.3)より極端な値が偶然出る確率。 これが小さい(< 0.05)なら「偶然ではない」→ H₀ 棄却。
💡 p値は「H₁ が正しい確率」ではない。 「H₀ のもとで、 この結果が偶然出る確率」。 解釈をよく間違える人が多い。
| 誤解 | 正しい理解 |
|---|---|
| p値 = H₀ が真である確率 | 「H₀ のもとで、 この結果が偶然出る確率」 |
| p値 = H₁ が真である確率 | H₁ の確率は計算していない |
| p > 0.05 だから差がない | 差がないと「証明された」わけではなく、 「差がある証拠が不十分」 |
| p < 0.05 だから効果が大きい | 効果の大きさは効果量で測る |
| p値が小さいほど信頼性が高い | あくまで「偶然じゃない」の度合い |
⚠️ ASA(米国統計学会)声明(2016):p値だけで結論を出さない、 「統計的有意 = 重要」ではない、 効果量と信頼区間を併記しよう。 これが現代の標準。
「100回検定して、 1回でも p < 0.05 が出る確率は約99%」。 たくさんの検定を行うと、 偶然に有意になる確率が膨らみます。
🎯 このコードでやること:p値 — 帰無仮説のもとで観測値より極端な結果が生じる確率に関連するステップ #1。最初のスニペットです。SSDSE-B-2026 を読み込みます。
📥 入力例(df.head())
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=2)
# 47都道府県 × 多数指標。 高齢化率や所得などを群間で比較し p 値を出します。
# df[['Prefecture','Y_2020']].head():
# Prefecture Y_2020
# 0 北海道 28.6
# 1 青森県 31.4
# 2 岩手県 31.2
# 3 宮城県 26.4
# 4 秋田県 33.71 2 3 | from statsmodels.stats.multitest import multipletests p_values = [0.001, 0.01, 0.03, 0.04, 0.20] rejected, p_adj, _, _ = multipletests(p_values, method='fdr_bh') |
📤 実行例(実行時の標準出力) t統計量 = 2.473, p値 = 0.0173 → 5% 水準で帰無仮説を棄却(差は偶然とは言えない) Cohen の d = 0.71 (中〜大の効果量) 処理完了
p値は「偶然じゃない」を測るが、 「どれだけ大きい効果か」は測れません。 効果量(effect size)が必要:
| 統計量 | 効果量 | Cohenの基準 |
|---|---|---|
| 2群の平均差 | Cohen's d | 小 0.2, 中 0.5, 大 0.8 |
| 相関 | r (相関係数) | 小 0.1, 中 0.3, 大 0.5 |
| 回帰 | R² | 小 0.02, 中 0.13, 大 0.26 |
| カテゴリ | Cramér's V | 小 0.1, 中 0.3, 大 0.5 |
p値 がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。
🌐 統計・データサイエンス › 推測統計 › 検定 › p値
中心に p値 を置き、 そこから 有意水準・信頼区間・正規分布・標準誤差・t検定・F検定 など 計 20 個の用語へ、 前提・兄弟・発展形といった関係を矢印で結んでいます。 線がどちら向きかを見れば、 先に読むべき用語とあとから読む用語が分かります。 ノードはドラッグで動かせ、 ホイールでズーム、 クリックでその用語のページへ遷移します。
大きな円が小さな円を包含する Circle Packing 図。 「p値」は緑色でハイライト。
長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「p値」は緑色でハイライト。
| マップ | 分かること | こんな時に見る |
|---|---|---|
| 🔗 関係マップ | 手法間の横の関係(前提→発展→応用) | 「次に何を学べばよい?」 学習順序の判断 |
| ⭕ 包含マップ | 分類体系の入れ子構造(上位⊃下位) | 「この手法はどんなジャンルに属する?」 |
| 🌳 ツリーマップ | 分野の規模比較(面積=ボリューム) | 「データサイエンス全体の俯瞰像」 |
💡 3 つの図は同じ位置関係を別の角度から描いています。 関係マップは p値 の隣に何が並ぶかを、 包含マップとツリーマップは 統計・データサイエンス → 検定 → p値 という入れ子の位置を示します。 「検定には他に何があったか」を思い出したいときは包含マップを、 「次に何を読むか」を決めたいときは関係マップを開いてください。
「p 値」は単独で完結せず、 前後の手法と組み合わさって価値が発揮される。 入力データの準備 (上流)・同目的の代替手法との比較 (並列)・結果の活用 (下流) という 3 軸で隣接領域を整理する。
この上流・並列・下流の対応を地図化することで、 「p 値」を中核に据えた分析パイプライン (データ準備 → 手法選択 → 結果の検証と展開) の全体像が見えてくる。
「p value」を含む手法選択は、 データの性質・分析目的・運用制約の 3 軸で決まる。 以下に典型シナリオと対応する手法の組合せを示す。
| シナリオ | 重視する観点 | 候補手法 |
|---|---|---|
| データが大規模 (n が多い、 高次元) | 計算コスト / メモリ / 並列化が必要 | 都道府県の相関係数 0.95 の有意性 等 |
| 外れ値が多い / ノイズあり | 頑健性 / 外れ値除去 / 中央値ベース | 都道府県データはサンプルサイズ 47 が固定 等 |
| 解釈性を重視する | 線形 / 木構造 / ルールベース | スケールの違い 等 |
| 予測精度を最優先する | アンサンブル / ハイパラ調整 / 交差検証 | 東京・大阪等の影響点 等 |
この節は既存の解説を壊さずに、 「直感」「重要な落とし穴」「発展」を一望できるよう再整理した追補です。 数値はすべて SSDSE-B-2026(2023 年・47都道府県)の実測値、 または「架空」と明記した思考実験のみを用います。
帰無仮説 H₀(差や関係がない)が真だと仮定したとき、 手元の観測値以上に極端なデータが得られる確率が p 値です。 p が小さいほど「H₀ という前提と、 実際に得られたデータが両立しにくい」ことを意味します。 逆に p が大きければ「この程度のズレは H₀ のもとでも普通に起こる」だけのこと。 したがって、 p 値は H₀ が正しい確率そのものではありません——ここが全ての誤解の出発点です(帰無仮説・仮説検定)。
実例:総人口 A1101 と 一般診療所数 I5102 は r = 0.972, 両側 p ≈ 8×10⁻³⁰(実測)。 |r| が閾値 0.29 を大きく超えるため、 p は天文学的に小さくなります(=「無関係な世界」ではまず起こり得ない)。
いずれも論文読解・実務で繰り返し問われる論点です。 既出の「⚠️ よくある落とし穴」節と合わせて確認してください。
| ❌ やりがちな誤読 | ✅ 正しい捉え方 |
|---|---|
| p 値 = 帰無仮説が正しい確率 | p 値は $P(\text{data}\mid H_0)$。 求めたい $P(H_0\mid\text{data})$ とは別物。 後者が欲しければベイズの枠組みが要る |
| 有意 = 効果が大きい | p は効果の大きさを示さない。 大きさは効果量(r・β・Cohen の d)で測る(下の思考実験参照) |
| p > 0.05 = 差がない証明 | 「棄却できない」=保留。 検出力不足で見逃した可能性がある(下の実測例参照) |
| たくさん検定して有意だけ拾う | p-hacking。 多重比較補正(Bonferroni・BH-FDR)が必須。 多重検定参照 |
| 標本を増やせば「本物の効果」だと分かる | n を増やすと実務上ささいな差でも p は小さくなる。 有意化は効果の重要性を保証しない |
| 0.049 と 0.051 は本質的に別 | α=0.05 は歴史的・慣習的な線引き。 p は連続量として段階的に読む(有意水準) |
| 結果を見てから仮説・片側/両側を決める | HARKing/事後的解釈。 偽陽性が膨らむ。 分析計画は事前登録で固定する |
下は架空の数値例です(実データではなく、 同じ相関 r = 0.25 が異なる標本サイズで得られたと仮定した計算)。 効果の大きさ(r)が同じでも、 n が増えるだけで p は小さくなります。
仮説検定 / 帰無仮説 / 対立仮説 / 有意水準 / 第一種の過誤 / 第二種の過誤 / 検出力 / 検出力分析 / 効果量 / 信頼区間 / 標準誤差 / 母集団と標本 / 多重比較 / 多重検定 / FDR / 事前登録 / 再現性危機 / ベイズ因子 / t検定 / 相関係数