中央値 はデータを大小順に並べたときの真ん中の値。 平均と異なり 外れ値の影響を受けにくい ため、 所得・住宅価格・人口のように右に歪んだ分布の「代表値」として推奨される。 SSDSE-B-2026 の都道府県人口で平均は東京の影響で大きく引っ張られるが、 中央値は影響を受けにくい。
df.median()
np.median()
SSDSE-B-2026 都道府県
「平均 vs 中央値 → 外れ値の効き方 → 歪んだ分布での選択」が要点。
🍰 まずはやさしく
中央値はデータの真ん中の値です。
全体の中心を正しく知るために使います。
クラスのテスト点数を並べて真ん中を探すようなものです。
ここでは中央値の基本ルールを学びます。
df.median() / np.median(arr) / statistics.median(arr)。 SSDSE-B-2026 の都道府県人口で平均 ≈ 265 万人、 中央値 ≈ 155 万人と東京の影響で大きく乖離する。中央値(median)は、 データを大小順に並べたときちょうど真ん中の値。 47都道府県データなら、 24番目(または 23-24番目の平均)の値です。
強み:外れ値に強い。 1つの極端な値が混ざっても、 中央値はびくともしません。 「ロバストな中心」と呼ばれます。
使い場面:(i) 所得・支出・地価など歪んだ分布、 (ii) 外れ値が多いデータ、 (iii) 順位データ(順序尺度)。 「日本の平均年収」より「日本の中央値年収」の方が現実を反映することが多い。
箱ひげ図の中央線が中央値。 第2四分位(Q2)、 50%パーセンタイルとも同じ概念。 df.median() で計算。
🍰 まずはやさしく
中央値は代表的な数値のひとつです。
データの中心をあらわすために使います。
スマホの利用時間をみんなで比べる時に役立ちます。
このページでは中央値の意味を詳しく解説します。
論文中に 「中央値」として登場する用語。
中央値 とは:データを大小に並べたときの真ん中の値。外れ値に強い「ロバストな中心」。
このページの位置: 中央値は大分類「統計の基礎」配下の代表値 (中心傾向) カテゴリに属し、 直近上位は「中心傾向 (代表値)」「記述統計」。 並列概念として「平均」「最頻値」、 ロバスト統計の系統では「MAD (中央絶対偏差)」「四分位数」と接続する。 機械学習評価指標では「MAE」が中央値最適と関連する。
次の章への橋渡し: 章 4 では SSDSE-B-2026 の住居費データで「順位の中心」としての中央値を視覚化し、 章 5 で偶数個・奇数個の場合分け定義、 章 7 で 47 都道府県の住居費・人口の中央値を実計算、 章 8 で numpy.median / pandas.Series.median による実装を扱います。
本ページでは「median」を扱う。 統計データ分析コンペティション (2026) の教材で、 SSDSE-B-2026 (47 都道府県 × 複数年 × 100 超列) の実データを使った再現可能な学習を目指す。
「median」は統計・データサイエンスの体系における重要概念のひとつ。 本ページは「定義・直感・数式・実装・落とし穴・関連手法」の 6 視点で構成され、 各視点は独立して読めるが順序通り読むと体系的な理解が得られる。
🍰 まずはやさしく
中央値は順位のちょうど真ん中です。
極端に大きい数字に惑わされないために使います。
部活の練習時間を小さい順に並べて真ん中を見る例です。
図を使って直感的に仕組みを理解しましょう。
中央値(median)は、 データを小さい順に並べた時の真ん中の値。 平均が「重心」だったのに対し、 中央値は「順位の中心」を表します。 47都道府県の住居費(2023年・ SSDSE-B-2026)を例に見ましょう。
各バーが1つの都道府県の住居費。 オレンジ色の24番目がちょうど中央 → これが中央値 18.47千円です。 赤い点線が平均(18.36千円)。 平均は住居費が高い少数の県(東京、 神奈川など)に引っ張られて高めに出ています。
データ (奇数個: 5 個): 3, 5, 7, 11, 15
昇順並び: 3 < 5 <[7]<11 <15
↑ 中央 = median = 7
データ (偶数個: 6 個): 3, 5, 7, 11, 15, 22
昇順並び: 3 < 5 <[7, 11]<15 <22
↑↑ 中央 2 値の平均 = (7+11)/2 = 9
SSDSE-B-2026 から代表 7 都道府県の住居費 (千円/月) を昇順に並べた例:
順位 都道府県 住居費(千円) 1 神奈川県 11.64 2 愛知県 13.44 3 岡山県 13.91 4 宮崎県 16.71 ← 中央値 (4 番目 = 真ん中) 5 福岡県 21.15 6 鹿児島県 22.96 7 東京都 26.46 ← 最大
→ 平均 = (11.64+13.44+13.91+16.71+21.15+22.96+26.46)/7 = 18.04 千円。 中央値 = 16.71 千円。 東京都の高い値で平均は中央値より 1.3 千円高いが、 中央値はその影響を受けにくい。
| 場面 | 推奨 | 理由 |
|---|---|---|
| 所得・住居費・地価 | 中央値 | 高所得層の外れ値で平均が歪む |
| 身長・体重 (正規分布) | 平均 | 対称分布なら両者ほぼ一致、 数理扱いが楽 |
| 回帰の損失関数 | 用途次第 | MAE 最適 = 中央値、 MSE 最適 = 平均 |
| 外れ値検出後 | どちらも可 | クリーニング済なら平均で十分 |
中央値は選挙の中道議員。 極端な左右の議員 (外れ値) が増えても、 議員席を順番に並べた時の真ん中の人は変わりにくい。 平均は議員 1 人 1 人の主張の合計を頭数で割った値で、 極端な議員が 1 人いるだけで大きく動く。
💡 中央値は順序統計量と呼ばれる量の代表。 「データの値そのもの」ではなく「並び順での位置」を見るため、 外れ値や極端な値の影響を受けにくい性質があります。
🍰 まずはやさしく
中央値は計算で決まる真ん中の値です。
正確な値を導き出すために使います。
買い物の金額を並べて計算するイメージです。
数式を使った求め方を順番に説明します。
データを並べたものを x_{(1)} ≤ x_{(2)} ≤ ... ≤ x_{(n)} とすると:
$$ \text{median}(x) = \begin{cases} x_{((n+1)/2)} & (n \text{ 奇数}) \\ \frac{x_{(n/2)} + x_{(n/2 + 1)}}{2} & (n \text{ 偶数}) \end{cases} $$
| 記号 | 読み方 | 意味 |
|---|---|---|
| x_{(i)} | エックス カッコ アイ | 並べた時の i 番目の値(順序統計量) |
| n | エヌ | データ数 |
| (n+1)/2 | エヌ プラス いち わる に | 真ん中の位置(n奇数の場合) |
連続的な確率分布の場合、 累積分布関数 F の0.5 になる点:
$$ F(\text{median}) = 0.5 \quad \Leftrightarrow \quad P(X \le \text{median}) = 0.5 $$
「中央値以下の確率は50%、 以上の確率も50%」という最も基本的な性質。
中央値はL1 損失を最小化する点として定義できます:
$$ \text{median}(x) = \arg\min_m \sum_i |x_i - m| $$
絶対値の和を最小化する m が中央値です。 これは平均が「二乗和」を最小化するのと対をなします。
| 性質 | 平均 | 中央値 |
|---|---|---|
| 最小化する損失 | L2(二乗和) | L1(絶対値和) |
| 線形性 | ✅ ある | ❌ ない |
| 外れ値耐性 | 弱い | 強い(崩壊点50%) |
| 計算量 | O(n) | O(n log n)(ソート)または O(n)(quickselect) |
| 微分可能性 | ✅ 可能 | ❌ 不可能(不連続) |
中央値が最も活躍するのは外れ値や歪んだ分布のとき。 平均との違いを実感する例を見ましょう。
左は正規分布のデータ。 平均と中央値はほぼ一致。
右は同じデータに外れ値(3000, 4500, 5000)を3つ追加。 平均は劇的に上昇するのに、 中央値はほとんど動かない。
「データの何%まで汚染しても推定値が壊れないか」を表す指標:
中央値の50%崩壊点は、 ロバスト統計量として理論的最高。 半分以上のデータが「正常」なら推定値は壊れない。
所得分布、 株価変動、 都市人口、 地震被害額など、 多くの実データは右に裾の長い分布(対数正規、 Pareto等)。 平均は裾に引っ張られて「典型的でない」値になり、 中央値の方が「典型的な人」を表します。 「平均年収」より「中央値年収」を見るべき理由。
平均にはペアとして「標準偏差」がありましたが、 中央値のロバスト版が MAD (Median Absolute Deviation)。
$$ \text{MAD} = \text{median}(|x_i - \text{median}(x)|) $$
標準偏差は外れ値に弱い(2乗するから極端値が支配的)ですが、 MAD は50%崩壊点を持つロバスト指標。 正規分布の場合、 σ ≈ 1.4826 × MAD という換算式があります。
1 2 3 4 5 6 7 8 9 10 11 12 | import numpy as np from scipy import stats data = np.array([1, 2, 3, 4, 5, 6, 7, 100]) # 外れ値あり median = np.median(data) mad = np.median(np.abs(data - median)) print(f'中央値: {median}') print(f'MAD: {mad}') # scipy には組み込み関数がある mad_scipy = stats.median_abs_deviation(data) mad_scaled = stats.median_abs_deviation(data, scale='normal') # 正規分布換算 |
中央値はデータの50%点。 これを25%、 75%にも拡張したのが四分位(quartile)。 そして四分位を可視化した最強のグラフが箱ひげ図。
💡 箱ひげ図1枚で 中央値・四分位・データの散らばり・歪み・外れ値 全てが分かります。 探索的データ分析(EDA)の基本ツール。
最も単純:全データをソートして、 真ん中を取り出す。 numpy/pandas のデフォルト実装。
1 2 3 4 5 6 7 | def median_sort(arr): sorted_arr = sorted(arr) # O(n log n) n = len(sorted_arr) if n % 2 == 1: return sorted_arr[n // 2] else: return (sorted_arr[n // 2 - 1] + sorted_arr[n // 2]) / 2 |
クイックソートと同じ分割を、 必要な位置だけ続ける。 全部ソートしないので線形時間で中央値が求まる。
1 2 3 4 5 6 | import numpy as np # numpy の partition は内部で QuickSelect 系のアルゴリズム arr = np.random.randn(10**6) k = len(arr) // 2 np.partition(arr, k)[k] # O(n) で k 番目の値 |
データが1個ずつ来る場合、 ヒープを2つ(max-heap と min-heap)使うと O(log n) で更新可能。 IoT センサーや金融取引の中央値追跡で使われます。
通常の線形回帰は平均(期待値)を予測しますが、 中央値を予測する回帰もあります。 外れ値に強いロバスト回帰の代表。 損失関数は L1(絶対値):
$$ L(\beta) = \sum_i |y_i - x_i^T \beta| $$
機械学習ライブラリ:sklearn.linear_model.QuantileRegressor、 statsmodels.regression.quantile_regression。
決定木の回帰版で、 各葉ノードの「中央値」を予測値とする方法もあります(デフォルトは平均だが、 中央値ベースの方がロバスト)。
欠損値を埋める時、 SimpleImputer(strategy='median') で中央値補完。 外れ値の影響を受けないので、 平均補完より安全。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # ── この抜粋で使うデータを用意します ── import numpy as np import pandas as pd from sklearn.model_selection import train_test_split df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年の 47 都道府県 X = df[['A1101', 'A1303', 'L3221']].astype(float).values y = df['A4101'].astype(float).values # 出生数 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42) from sklearn.impute import SimpleImputer imputer = SimpleImputer(strategy='median') X_imputed = imputer.fit_transform(X) |
標準化(標準偏差で割る)の代わりに、 中央値と IQR を使うスケーリング。 外れ値の影響を受けない前処理:
$$ x_{\text{scaled}} = \frac{x - \text{median}(x)}{\text{IQR}(x)} $$
1 2 3 | from sklearn.preprocessing import RobustScaler scaler = RobustScaler() X_scaled = scaler.fit_transform(X) |
中央値(median)は順序統計量の中央に位置する値で、 並べ替えたデータの「半分が上、 半分が下」を分ける点です。 サンプル数 $n$ の偶奇で定義が異なります。
$$ \text{median}(X) = \begin{cases} x_{((n+1)/2)} & (n \text{ 奇数}) \\ \dfrac{1}{2}\left( x_{(n/2)} + x_{(n/2+1)} \right) & (n \text{ 偶数}) \end{cases} $$
$$ \text{median} = \arg\min_{m} \sum_{i=1}^{n} |x_i - m| $$
| 記号 | 意味 | 具体例 |
|---|---|---|
| $x_{(k)}$ | 第 $k$ 順序統計量(小さい方から $k$ 番目) | 47 県人口で 24 番目に大きい県の値 |
| $n$ | 標本サイズ | 日本の都道府県なら $n=47$(奇数) |
| $(n+1)/2$ | 奇数時の中央位置 | $n=47$ なら 24 番目(小さい方から) |
| $\arg\min_m \sum \|x_i - m\|$ | L1 損失最小化解 | 「絶対値誤差の合計が最小になる m」が中央値 |
| $\arg\min_m \sum (x_i - m)^2$ | L2 損失最小化(平均値) | 対照: 平均は二乗誤差を最小化 |
最後の最小化表現が重要:中央値は L1 損失の最小化解、 平均値は L2 損失の最小化解です。 これにより「中央値は外れ値の影響を受けにくい」という頑健性が数学的に説明できます。
前節の中央値の定義式 $\text{median}(x) = x_{((n+1)/2)}$(n 奇数)または $\frac{x_{(n/2)} + x_{(n/2+1)}}{2}$(n 偶数) を、 記号ごとに意味へ翻訳する。 中央値は「並べ替えて真ん中を取る」だけだが、 数式上は順序統計量という概念で表現される。
| 記号 | 読み方 | 意味 | 具体例(n=7 の場合) |
|---|---|---|---|
| $x$ | エックス | 元のデータ集合(並べる前) | {72, 85, 68, 91, 77, 80, 74} |
| $x_{(i)}$ | エックス カッコ アイ | 昇順に並べたときの i 番目(順序統計量) | $x_{(1)}$=68, $x_{(2)}$=72, …, $x_{(7)}$=91 |
| $n$ | エヌ | サンプル数 | 7 |
| $(n+1)/2$ | エヌ プラス 1 割る 2 | 奇数のときの中央の位置インデックス | (7+1)/2 = 4 → 4 番目 |
| $n/2,\ n/2+1$ | エヌ割る 2、 と その次 | 偶数のときに挟む 2 つの位置 | n=6 なら 3 番目と 4 番目 |
| $\text{median}(x)$ | メディアン | 中央値(求めたい値) | $x_{(4)}$ = 77 |
「データ $x$ を昇順に並べ、 並んだもの $x_{(1)} \le x_{(2)} \le \cdots \le x_{(n)}$ について、 サンプル数 $n$ が奇数なら ちょうど真ん中の $x_{((n+1)/2)}$ を、 偶数なら 真ん中を挟む 2 つ $x_{(n/2)}$ と $x_{(n/2+1)}$ の平均を取る。 これが中央値である」
$x_i$(元の i 番目)と $x_{(i)}$(並べ替え後の i 番目)は別物。 例えば $x_3$ は「3 番目に観測した値」(=68)だが $x_{(3)}$ は「3 番目に小さい値」(=74)。 カッコの有無で意味が変わるため、 中央値の定義では必ず $x_{(i)}$ を使う。 これにより「並べ替えた後の真ん中」を厳密に指定できる。
47都道府県データから等間隔で7県を抜き出して、 中央値を手で計算してみましょう。
都道府県と住居費(千円/月):
| 順位 | 都道府県 | 住居費 |
|---|---|---|
| 1 | 神奈川県 | 11.64 |
| 2 | 福井県 | 13.60 |
| 3 | 島根県 | 15.88 |
| 4 | 佐賀県 | 18.47 |
| 5 | 長崎県 | 19.93 |
| 6 | 鹿児島県 | 22.96 |
| 7 | 沖縄県 | 27.52 |
n = 7(奇数)なので、 真ん中はちょうど (n+1)/2 = 4番目。
中央値 = 18.47 千円
n=6(例:上の表から最後を除く)の場合、 真ん中が「ない」。 そこで 3番目と4番目の平均を取ります:
SSDSE-B-2026(2023年)の「総人口 A1101」で平均と中央値を比較し、 中央値の有用性を確認します。 人口は東京都という強い外れ値をもつ右に歪んだ分布の典型例です。
1 2 3 4 5 6 7 8 9 10 11 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) latest = df[df['SSDSE-B-2026'] == 2023] # 最新年度 pop = latest['A1101'].dropna() # 総人口 print(f'n = {len(pop)}') print(f'平均 = {pop.mean():,.0f}') print(f'中央値 = {pop.median():,.0f}') print(f'最大値 = {pop.max():,.0f}(東京)') print(f'最小値 = {pop.min():,.0f}(鳥取)') print(f'歪度 = {pop.skew():.3f}') |
結果:平均 = 2,645,809(約 265 万人)、 中央値 = 1,549,000(約 155 万人)、 歪度 = 2.29。 平均 > 中央値 で右に大きく歪んだ分布(東京都の人口が突出)。 「典型的な県の人口」を語るなら中央値の方が実態を反映する。
1 2 3 4 5 6 7 | import numpy as np # 仮に「東京都の人口が突然3倍になった」と仮定 pop_extreme = pop.copy() pop_extreme[pop_extreme.idxmax()] *= 3 print(f'平均 (元) = {pop.mean():.1f} → (変動後) {pop_extreme.mean():.1f}({(pop_extreme.mean()-pop.mean()):.1f} 変動)') print(f'中央値(元) = {pop.median():.1f} → (変動後) {pop_extreme.median():.1f}({(pop_extreme.median()-pop.median()):.1f} 変動)') # 平均は約60万人変動、 中央値は1人も動かない → ロバスト性の真髄 |
1 2 3 4 5 6 7 | q1, q3 = pop.quantile([0.25, 0.75]) iqr = q3 - q1 mad = (pop - pop.median()).abs().median() # 中央絶対偏差 print(f'Q1 = {q1:.1f}, Q3 = {q3:.1f}, IQR = {iqr:.1f}') print(f'MAD = {mad:.1f}') print(f'SD (比較) = {pop.std():.1f}') # 散布度の頑健指標:MAD・IQR < SD < 分散 の順にロバスト性が低下 |
🎯 このコードでやること:SSDSE-B-2026 から最新年度の 47 都道府県人口を取り出し、 平均値と中央値を計算。 東京を除外した場合の影響を比較し、 「外れ値に対するロバスト性」を実証する。
📥 入力データ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) latest = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()].copy() latest = latest[~latest['Prefecture'].str.contains('全国')] pop = latest['A1101'] print(f'47 県全体 平均 = {pop.mean():>12,.0f}') print(f'47 県全体 中央値 = {pop.median():>12,.0f}') without_tokyo = latest[latest['Prefecture'] != '東京都']['A1101'] print() print(f'東京除外46県 平均 = {without_tokyo.mean():>12,.0f}') print(f'東京除外46県 中央値 = {without_tokyo.median():>12,.0f}') print() print(f'平均 変化率: {(without_tokyo.mean() - pop.mean()) / pop.mean() * 100:+.2f}%') print(f'中央値 変化率: {(without_tokyo.median() - pop.median()) / pop.median() * 100:+.2f}%') |
📤 実行結果:
💬 結果の読み方:東京(1,409 万人)を除くと平均は 9.4% も下落するが、 中央値はわずか 2.6% しか動かない。 これが中央値のロバスト性。 47 県のような「1 県だけ突出して大きい」分布では、 代表値として中央値の方が「典型的な県」を表す。 全国レベルの政策議論で平均人口を語る危険性がここに表れる。
合成データで平均と中央値を比較し外れ値の影響を計算する。
1 2 3 4 5 | import numpy as np x1 = np.array([2, 4, 7, 5, 3]) x2 = np.array([2, 4, 7, 5, 3, 100]) print(f"x1 平均: {x1.mean()}, 中央値: {np.median(x1)}") print(f"x2 平均: {x2.mean():.1f}, 中央値: {np.median(x2)}") |
💬 手計算 (Step 2) 中央値の頑健性と Python 出力が完全一致。
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 | import pandas as pd import numpy as np from scipy import stats # pandas(skiprows=[1] で日本語見出し行を除外、 L322102=住居費) df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) median_housing = df['L322102'].median() print(f'住居費の中央値: {median_housing:.2f}') # numpy arr = np.array([1, 3, 5, 7, 9, 11]) print(np.median(arr)) # 6.0(4と8の平均) # 軸指定 mat = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print(np.median(mat, axis=0)) # [4, 5, 6] - 列ごと print(np.median(mat, axis=1)) # [2, 5, 8] - 行ごと # 欠損値を無視 arr_nan = np.array([1, 2, np.nan, 4]) print(np.nanmedian(arr_nan)) # 2.0 # 四分位 q1, q2, q3 = np.percentile(df['L322102'], [25, 50, 75]) print(f'Q1={q1:.2f}, Median={q2:.2f}, Q3={q3:.2f}') # pandas describe(要約) print(df['L322102'].describe()) # count/mean/std/min/25%/50%/75%/max |
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 30 31 32 33 34 | # ── この抜粋で使うデータを用意します(SSDSE-B の 47 都道府県・最新年度)── import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()].copy() # 最新年度の 47 行 df['高齢化率'] = df['A1303'] / df['A1101'] * 100 # 「地方」は SSDSE に無い列なので、都道府県名から 8 地方区分を作る _BLOCKS = { '北海道': ['北海道'], '東北': ['青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県'], '関東': ['茨城県', '栃木県', '群馬県', '埼玉県', '千葉県', '東京都', '神奈川県'], '中部': ['新潟県', '富山県', '石川県', '福井県', '山梨県', '長野県', '岐阜県', '静岡県', '愛知県'], '近畿': ['三重県', '滋賀県', '京都府', '大阪府', '兵庫県', '奈良県', '和歌山県'], '中国': ['鳥取県', '島根県', '岡山県', '広島県', '山口県'], '四国': ['徳島県', '香川県', '愛媛県', '高知県'], '九州・沖縄': ['福岡県', '佐賀県', '長崎県', '熊本県', '大分県', '宮崎県', '鹿児島県', '沖縄県'], } _R = {p: g for g, ps in _BLOCKS.items() for p in ps} df['地方'] = df['Prefecture'].map(_R) import seaborn as sns import matplotlib.pyplot as plt df['地域'] = df['地方'] # 1変数の箱ひげ図 sns.boxplot(y=df['L322102']) # カテゴリ別の箱ひげ図('地域'列は都道府県から事前に付与しておく) sns.boxplot(x='地域', y='L322102', data=df) # violin plot(分布の形も見える進化版) sns.violinplot(x='地域', y='L322102', data=df, inner='quartile') |
1 2 3 4 5 6 7 | import pandas as pd import numpy as np s = pd.Series([1, 2, 3, 100]) print(s.median()) # 2.5 print(np.median(s)) # 2.5 print(np.percentile(s, 50)) # 2.5(中央値 = 50%パーセンタイル) print(np.quantile(s, 0.5)) # 2.5 |
1 2 3 4 5 6 | from scipy import stats data = [1, 2, 3, 4, 100] print(stats.tmean(data, limits=(2, 50))) # 切断平均(範囲内のみ) print(stats.trim_mean(data, 0.1)) # 上下10%トリム print(stats.gmean(data)) # 幾何平均(対数正規分布向け) print(stats.hmean(data)) # 調和平均(比率の集約向け) |
1 2 3 4 5 6 7 8 9 10 11 12 13 | # ── この抜粋で使うデータを用意します ── import pandas as pd import statsmodels.formula.api as smf df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年の 47 都道府県 df = df.rename(columns={'A4101': 'y', 'A1101': 'x1', 'A1303': 'x2'}) # y=出生数 を x1=総人口・x2=65歳以上人口 で説明する # 「中央値」を目的とした回帰(外れ値に強い) mod = smf.quantreg('y ~ x1 + x2', data=df).fit(q=0.5) print(mod.summary()) # 通常の OLS(平均回帰)の頑健代替。 q=0.25, 0.75 で他分位点も推定可 |
1 2 3 | from sklearn.linear_model import HuberRegressor hr = HuberRegressor(epsilon=1.35).fit(X, y) # 中央値ベースではないが、 外れ値に強い線形回帰 |
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 | # ── この抜粋で使うデータを用意します ── # 検定の書き方を並べた早見表なので、そのまま押せるように # 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.stats import median_test stat, p, m, table = median_test(group1, group2) print(f'統計量 = {stat:.3f}, p = {p:.4f}') # 2群の中央値が等しいかを検定(χ²ベース) |
中央値の標本分布は理論的には複雑(順序統計量に基づく)です。 実務的にはブートストラップで信頼区間を推定するのが最も簡単で頑健です。
🎯 このコードでやること:47 都道府県人口の中央値の 95% 信頼区間を 10,000 回のブートストラップで推定し、 平均の信頼区間と比較する。
📥 入力データ:上記コードと同じ pop シリーズ(47 県人口)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import pandas as pd import numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) latest = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()].copy() latest = latest[~latest['Prefecture'].str.contains('全国')] pop = latest['A1101'].values rng = np.random.default_rng(42) B = 10000 boot_med = np.empty(B) boot_mean = np.empty(B) for b in range(B): sample = rng.choice(pop, size=len(pop), replace=True) boot_med [b] = np.median(sample) boot_mean[b] = sample.mean() ci_med = np.quantile(boot_med , [0.025, 0.975]) ci_mean = np.quantile(boot_mean, [0.025, 0.975]) print(f'中央値 95% CI: [{ci_med [0]:>12,.0f}, {ci_med [1]:>12,.0f}] 幅 {ci_med [1]-ci_med [0]:,.0f}') print(f'平均 95% CI: [{ci_mean[0]:>12,.0f}, {ci_mean[1]:>12,.0f}] 幅 {ci_mean[1]-ci_mean[0]:,.0f}') |
📤 実行結果:
💬 結果の読み方:中央値の CI 幅(74.7 万)は平均の CI 幅(157.9 万)の半分以下。 外れ値(東京・神奈川など)が再サンプリングのたびに含まれる/含まれないで平均は大きく振動するが、 中央値は「真ん中の県」が変わるだけで影響が小さい。 これがブートストラップで見える「中央値の標本分布が引き締まる」現象。
2 群の中央値が等しいかを検定したいとき、 正規性を仮定しないノンパラメトリック検定として Mann-Whitney U 検定(独立 2 群)や Wilcoxon 符号順位検定(対応のある 2 群)が使われます。 中央値の差をターゲットにする実務必須ツールです。
🎯 このコードでやること:SSDSE-B-2026 の 47 県を「関東 7 都県」と「東北 6 県」に分け、 人口の中央値に差があるかを Mann-Whitney U 検定で確認する。
📥 入力データ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import pandas as pd from scipy.stats import mannwhitneyu df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) latest = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()].copy() latest = latest[~latest['Prefecture'].str.contains('全国')] kanto = ['茨城県','栃木県','群馬県','埼玉県','千葉県','東京都','神奈川県'] tohoku = ['青森県','岩手県','宮城県','秋田県','山形県','福島県'] g1 = latest[latest['Prefecture'].isin(kanto )]['A1101'] g2 = latest[latest['Prefecture'].isin(tohoku)]['A1101'] print(f'関東 中央値 = {g1.median():,.0f}') print(f'東北 中央値 = {g2.median():,.0f}') U, p = mannwhitneyu(g1, g2, alternative='two-sided') print(f'U 統計量 = {U}, p = {p:.4f}') |
📤 実行結果:
💬 結果の読み方:p = 0.0047 < 0.05 で帰無仮説(両群の分布は同じ)は棄却される。 中央値の差は 508 万人。 t 検定では東京の外れ値で平均が引っ張られるが、 Mann-Whitney U は順位ベースなのでロバストに「関東は東北より人口が大きい」と検定できる。
🎯 このコードでやること:SSDSE-B-2026 の年次データから、 47 都道府県の「年度ごとの消費支出中央値」を計算し、 中央絶対偏差(MAD)で外れ年度を検出する。
📥 入力データ:L3221(消費支出・二人以上の世帯)の年次系列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import pandas as pd import numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[~df['Prefecture'].str.contains('全国')] # 年度ごとの消費支出中央値 yearly = df.groupby('SSDSE-B-2026')['L3221'].median() # 中央絶対偏差 (MAD) によるロバスト外れ値検出 m = yearly.median() mad = (yearly - m).abs().median() modified_z = 0.6745 * (yearly - m) / mad outliers = yearly[modified_z.abs() > 3.5] print('年度別 中央値 (消費支出):') print(yearly.tail(8).to_string()) print() print(f'中央値 {m:,.0f}, MAD {mad:,.0f}') print(f'外れ年度: {list(outliers.index)}') |
📤 実行結果:
💬 結果の読み方:MAD ベースの修正 Z スコアでは、 2023 年度が「外れ年度」として検出される(消費支出中央値が約 30.1 万円へ急伸し |Z| > 3.5)。 一方コロナ禍の 2020 年度はむしろ低めだが |Z| < 3.5 で異常とはされない。 平均 + 標準偏差より遥かに頑健で、 時系列の異常検知では実務標準。
このページのテーマ「中央値のロバスト性」を、 3 つの実験で手を動かして確かめます。 姉妹ページ(平均=重心の体感、 外れ値=1 点ドラッグでの検出、 四分位数=Q1/Q3 の連動)とは角度を変え、 ここでは (1) breakdown point 50% の実証、 (2) 歪んだ分布での「典型値」選択、 (3) 中央値がどの点に乗るかのステップ体感 に絞ります。 マウスでもタッチ(スマホ)でも操作できます。
数直線上に架空の 9 点(10〜20 に対称配置、 初期状態では平均 = 中央値 = 15.0)が並んでいます。 点をドラッグして 1 点だけ極端な位置へ動かすと、 平均(赤実線)はズルズル引きずられるのに、 中央値(青点線)はほぼ動きません。 さらに「汚染 +1点」ボタンで大きい方の点から順に 120 へ飛ばしていくと、 4 点(44.4%)までは中央値が不動で、 5 点目(55.6%)で初めて崩壊する——これが崩壊点(breakdown point)50% の意味です。
読み込み中…
💬 平均の崩壊点は 0%(1 点の汚染で任意に動く)。 中央値の 50% は理論的な最大値で、 「データの半分が壊れていても中心の推定が生き残る」ことを意味します。 本文の SSDSE-B 実測例(総人口 A1101、 2023 年)でも、 東京都という 1 点の突出に対し平均は 265 万人 vs 中央値 155 万人と大きく乖離しました。
右裾の長い所得型分布(架空データ、 対数正規・n=200)のヒストグラムです。 ボタンで対称分布(架空)と切り替えて、 平均と中央値の位置関係、 そして「平均未満の世帯の割合」がどう変わるかを見比べてください。 この架空所得データでは平均 ≈ 502 万円に対し中央値 ≈ 399 万円で、 約 62% の世帯が「平均未満」——平均は少数の高所得に引き上げられ、 典型値としては中央値が適切です。
読み込み中…
空の数直線をタップ/クリックして点を 1 つずつ置いてください(「自動で 1 点追加」でも可)。 奇数個のときは中央値が実在するデータ点そのもの(青い点)に乗り、 偶数個になるとどの点にも乗らず中央 2 点の中点へ移る——点を追加するたびに中央値が「綱引き」のように隣の点へ乗り移る様子をステップ体感できます。
読み込み中…
実験①で中央値が不動だった理由は、 中央値が値の大きさではなく順位だけを使うからです。 端の点をどれだけ遠くへ飛ばしても「その点が端にある」という順序情報は変わらないため、 真ん中の点は入れ替わりません。 数式で言えば、 中央値は L1 損失 $\sum_i |x_i - m|$ の最小化解であり、 その勾配は各点について $\pm 1$(点が $m$ より上か下かの符号だけ)。 外れ値がどれだけ遠くても寄与は「1 票」のままです。 一方、 平均は L2 損失 $\sum_i (x_i - m)^2$ の最小化解で、 勾配が距離に比例するため、 遠い点ほど強く平均を引っ張ります。 実験①の「引きずられる赤線」と「動かない青線」は、 この損失関数の形の違いの可視化です。
(1) 多峰分布では中央値も「典型値」にならない。 実験②は単峰の歪みでしたが、 例えば 20 代と 60 代に山が分かれる二峰の年収分布では、 中央値は 2 つの山の谷間(誰も「典型的」でない値)に落ちることがあります。 分布形状の確認(ヒストグラム・最頻値との併記)を省略して中央値だけ報告するのは危険です。
(2) グループ併合時の非加法性。 中央値はグループごとの値から全体の値を再構成できません。 架空の例:グループ A = {1, 2, 3}(中央値 2)、 グループ B = {10, 20, 30, 40}(中央値 25)を併合すると、 全体 {1, 2, 3, 10, 20, 30, 40} の中央値は 10。 サイズ加重平均 (2×3 + 25×4)/7 ≈ 15.1 とは一致しません(平均なら厳密に一致します)。 都道府県別の中央値から「全国の中央値」を合成する、 といった集計は原データに戻って計算し直す必要があります。
平均(崩壊点 0%)と中央値(崩壊点 50%)は両極端で、 その中間にトリム平均(上下 α% を捨てて平均、 崩壊点 α)があります。 α=0 で平均、 α→50% で中央値に一致し、 「頑健性と効率のトレードオフ」を連続的に調整できます(体操採点の最高・最低カットが α=1/審査員数 のトリム平均)。 また実験②の発想を回帰に持ち込んだのが分位点回帰で、 条件付き平均ではなく条件付き中央値(や任意の分位点)を予測するため、 歪んだ目的変数や外れ値に強いモデルになります。 これらの体系はロバスト統計、 ばらつき側の頑健指標は MAD、 可視化は箱ひげ図を参照してください。
interpolation='linear' で線形補間、 statsmodels や R では他の補間法もある。 報告時には「中央値(線形補間)」のように方法を明示する。scipy.stats.bootstrap や sklearn.utils.resample。 中央値を点推定でだけ報告するのは不十分。 「中央値 280 万(95% CI [260, 295])」のように区間も併記。中央値 がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。
🌐 統計・データサイエンス › 記述統計 › 中心傾向 › 中央値
中心に 中央値 を置き、 そこから 平均・四分位・箱ひげ図・ノンパラ検定・外れ値検出・分散 など 計 11 個の用語へ、 前提・兄弟・発展形といった関係を矢印で結んでいます。 線がどちら向きかを見れば、 先に読むべき用語とあとから読む用語が分かります。 ノードはドラッグで動かせ、 ホイールでズーム、 クリックでその用語のページへ遷移します。
大きな円が小さな円を包含する Circle Packing 図。 「中央値」は緑色でハイライト。
長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「中央値」は緑色でハイライト。
| マップ | 分かること | こんな時に見る |
|---|---|---|
| 🔗 関係マップ | 手法間の横の関係(前提→発展→応用) | 「次に何を学べばよい?」 学習順序の判断 |
| ⭕ 包含マップ | 分類体系の入れ子構造(上位⊃下位) | 「この手法はどんなジャンルに属する?」 |
| 🌳 ツリーマップ | 分野の規模比較(面積=ボリューム) | 「データサイエンス全体の俯瞰像」 |
💡 3 つの図は同じ位置関係を別の角度から描いています。 関係マップは 中央値 の隣に何が並ぶかを、 包含マップとツリーマップは 統計・データサイエンス → 中心傾向 → 中央値 という入れ子の位置を示します。 「中心傾向には他に何があったか」を思い出したいときは包含マップを、 「次に何を読むか」を決めたいときは関係マップを開いてください。
中央値は順序統計量族の中央メンバーであり、 四分位数・百分位数・最頻値・分位回帰へと自然に拡張されます。
中央値は単独で使うより、 上流のソート操作、 並列の平均・最頻値・四分位、 下流の IQR・MAD・箱ひげ図と組み合わせて使う。 外れ値に頑健な代表値として、 平均と必ずペアで報告するのが安全。 ここでは 接続 / 統合 / 比較 の 3 視点で隣接手法 5 件との関係を整理する。
| 前後関係 | 隣接手法 | 中央値との接続 | 適用シーン |
|---|---|---|---|
| 上流 | データクレンジング | 欠損除去・型変換が前提 | SSDSE 列に NaN がある場合まず除去 |
| 上流 | 分位点 | 中央値は q=0.5 の特殊例 | Q1・Q3 と組で要約統計 |
| 下流 | 箱ひげ図 | 中央値線を中心に IQR を描画 | 県別人口の分布可視化 |
| 下流 | MAD | 中央値からの絶対偏差の中央値 | 外れ値に頑健なばらつき測定 |
| 下流 | 分位点回帰 | 中央値回帰 (τ=0.5) として一般化 | 所得・家賃など歪んだ目的変数 |
| 手法 | 中央値との違い | いつ中央値より優先するか |
|---|---|---|
| 平均 | 全データの加重和÷n、 外れ値に敏感 | 対称分布・合計に意味がある時 |
| 最頻値 | 最も多い値、 カテゴリでも定義可 | 名義尺度・多峰分布 |
| トリム平均 | 上下 k% を捨てて平均、 中央値と平均の中間 | 外れ値が少数で大きさ既知 |
SSDSE-B-2026 の県別人口の中央値は約 140 万人で、 平均 269 万人と大きく異なる。 上流でソート、 中段で median + Q1 + Q3 計算、 下流で箱ひげ図に描いて東京・神奈川を外れ値マーカーで強調、 という流れがレポートの基本。
💡 報告では両方を併記するのが最も誠実。 「平均500万円、 中央値450万円」と書けば、 分布の歪みも示唆できる。
平均よりも歴史は若いですが、 「外れ値に強い代表値」として近代統計の発展に欠かせない概念に。
本ページの既存の解説に対する追記の補足です。 「直感」「落とし穴」「平均との対比」を一段深めつつ、 分位数・MAD・分位点回帰・ロバスト統計へ橋渡しします。 数値はすべて SSDSE-B-2026(2023 年・47 都道府県・総人口 A1101)の実測、 一部の説明用データは「架空」と明記します。
平均はてこの支点(重心):各データを距離に比例した重みで引っ張るので、 遠い 1 点が全体を動かせます。 中央値は順位の中心:値の大小ではなく「上下どちらの側か」という 1 票だけを数えるので、 端の点がどれだけ遠くても真ん中の順位は変わりません。 これが「中央値は外れ値に頑健」「歪んだ分布の代表値に向く」ことの核心です。 対称な分布では両者はほぼ一致し(例:本ページの左右対称ウィジェット②)、 右に歪むほど 平均 > 中央値 の差が開きます(SSDSE 総人口では平均 265 万人 > 中央値 155 万人、 歪度 2.29)。 「平均と中央値の差」そのものが分布の歪みの簡易指標になります。
$n$ が偶数だと真ん中が存在しないため中央 2 値の平均を取るのが標準(例:$n=4$ なら 2・3 番目の平均)。 ただしこれは唯一の定義ではありません。 numpy.median / pandas.median は中央 2 値の平均、 Python 標準 statistics.median_low は下側の値(lower median)、 median_high は上側を返します。 関数によって偶数 $n$ の結果が変わりうるため、 報告時は「中央値(2 値平均)」のように方式を明示します。 なお SSDSE の 47 都道府県は $n=47$(奇数)なので中央値は 24 番目の県の値そのもの=この曖昧さは生じません。
平均は $\text{mean}(A\cup B)$ をサイズ加重平均で厳密に再構成できますが、 中央値にはこの加法性がありません。 SSDSE 実測での確認:47 都道府県全体の総人口中央値は 154.9 万人。 一方これを「三大都市圏(架空の区分でグルーピング)」ごとに中央値を出して加重平均しても、 一般にこの 154.9 万には戻りません。 「都道府県別中央値の平均 = 全国中央値」と考えるのは誤りで、 全国の中央値が欲しければ原データ 47 件に戻して計算し直すのが唯一正しい手順です(本ページウィジェット深掘り②(2)も参照)。
中央値の標準誤差(SE)には正規分布を仮定した近似式 $\mathrm{SE}\approx 1.2533\,\sigma/\sqrt{n}$ があります(落とし穴で既出)。 しかし右に歪んだ SSDSE 総人口では、 $\sigma$ が東京・神奈川の裾で膨らむため、 この式はSE を過大に見積もります。 実測での対比:
| 推定法 | 中央値の SE | コメント |
|---|---|---|
| 正規近似 $1.2533\,\sigma/\sqrt{n}$ | 約 51.1 万人 | σ が外れ値で膨張 → 過大 |
| ブートストラップ(10,000 回) | 約 22.1 万人 | 分布を仮定せず頑健。 実質半分以下 |
| (参考)平均の SE $\sigma/\sqrt{n}$ | 約 40.8 万人 | ブートSEは約 40.4 万でほぼ一致 |
教訓:歪んだデータの中央値には正規近似 SE を使わず、 ブートストラップで区間推定する。 本ページ「Python での計算」のブートストラップ CI(中央値 95%CI 幅 74.7 万 < 平均 157.9 万)も同じ現象を別角度で示しています。
中央値は順序関係さえあれば定義でき、 間隔が等しい保証のない順序尺度(5 段階リッカート等)でも使えます(平均は本来使えない)。 一方、 同値が大量にある離散データでは中央値が特定の階級に「貼り付き」、 1 件の増減では動かない反面、 微小な変化を映せない硬さがあります(落とし穴②・⑥)。 尺度水準の判断は 順序尺度 を参照。
中央値は $\tau=0.5$ の分位点 $Q(0.5)$ という特殊例に過ぎません。 $\tau=0.25,0.75$ が四分位 $Q_1,Q_3$、 一般の $\tau$ が百分位点。 累積分布関数 $F$ の逆関数 $Q(\tau)=F^{-1}(\tau)$ として統一的に定義され、 箱ひげ図はこの $Q_1,Q_2,Q_3$ を可視化したものです。
中央値は $\arg\min_m \sum_i |x_i-m|$(数式③既出)。 SSDSE 総人口で実測すると、 $m$=中央値のとき絶対偏差の総和は 約 7,627 万、 $m$=平均のときは 約 9,215 万。 中央値の方が約 1,589 万小さく、 確かに L1 損失を最小化しています。 対照的に平均は L2 損失 $\sum(x_i-m)^2$ を最小化する点で、 この損失の違いが「中央値=MAE 最適/平均=MSE 最適」という機械学習側の対応にそのまま繋がります。
中央値からの絶対偏差の中央値が MAD $=\text{median}(|x_i-\text{median}(x)|)$。 SSDSE 総人口の実測は MAD = 62.3 万。 正規換算 $1.4826\times$MAD = 約 92.4 万で、 外れ値に膨らんだ標準偏差 SD = 約 279.8 万の約 1/3 に収まります。 「中央値 + MAD」は「平均 ± SD」の頑健版で、 修正 Z スコア $0.6745\,(x-\text{median})/\text{MAD}$ による異常値検出は実務標準(本ページ時系列 MAD 検出で 2023 年度を検出)。
全ペア平均(Walsh 平均 $(x_i+x_j)/2$)の中央値が Hodges-Lehmann (HL) 推定量。 SSDSE 総人口の実測 HL は 約 178.1 万人で、 中央値 154.9 万と平均 264.6 万の間、 中央値寄りに位置します。 HL は中央値より統計的に効率が高い(正規分布下で漸近相対効率 ≈ 0.955、 単純中央値の 0.637 を上回る)一方、 崩壊点は約 29% と依然として頑健です。 Wilcoxon 符号順位検定に対応する位置推定量で、 ロバスト統計の古典。
「条件付き中央値」を予測するのが分位点回帰($\tau=0.5$ で中央値回帰、 損失は L1)。 平均(崩壊点 0%)と中央値(崩壊点 50%)の中間を連続的に埋めるのがトリム平均・M 推定量で、 これらの体系がロバスト統計です。 中央値は「外れ値に頑健な代表値」の入口であり、 ここから MAD・分位点回帰・HL 推定・ノンパラ検定という頑健統計の地図全体へ繋がります。