「quartile」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「quartile」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。
これらのキーワードは「quartile の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。
🍰 まずはやさしく
データを4等分する3つの区切り点のことです。
データの広がりを正しく知るために使います。
テストの点数を順番に並べて分けるイメージです。
ここでは四分位の定義と使い方を学びます。
四分位(quartile)は、 データを大小順に並べて4等分する3つの値。 Q1 = 25%点、 Q2 = 中央値、 Q3 = 75%点と呼びます。
四分位範囲(IQR) = Q3 − Q1。 真ん中50%のデータの広がりを表す「ロバストな広がり指標」(外れ値に影響されにくい)。
使い道:
Python:df.quantile([0.25, 0.5, 0.75]) または df.describe() で一発取得。
data/raw/SSDSE-B-2026.csv(cp932)、対象列(例:消費支出)。1 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 import matplotlib.pyplot as plt import seaborn as sns # データ読み込み df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) # 基本統計量 df.describe() # 可視化 sns.pairplot(df[['食料費(二人以上の世帯)', '教育費(二人以上の世帯)', '住居費(二人以上の世帯)']]) plt.show() |
四分位 (Q1/Q2/Q3) は順序統計量から派生する位置の要約量。 上位カテゴリは分位点 (Quantile)で、 q=0.25, 0.5, 0.75 の特別な場合に相当する。 並列概念はパーセンタイル (1〜99 の任意点) と五数要約 (min, Q1, Q2, Q3, max)。 派生として箱ひげ図、 IQR、 IQR×1.5 ルールでの外れ値検出が広く使われる。
47 都道府県の家計支出・人口データを使い、 四分位そのものの計算と読み取りに集中して練習する。
| 機能 | Python (pandas) | Python (numpy / scipy) |
|---|---|---|
| Q1 (25%) | df.quantile(0.25) | np.percentile(x, 25) |
| 中央値 Q2 | df.median() | np.median(x) |
| Q3 (75%) | df.quantile(0.75) | np.percentile(x, 75) |
| IQR | df.quantile(.75)-df.quantile(.25) | scipy.stats.iqr(x) |
| 五数要約 | df.describe() | np.percentile(x,[0,25,50,75,100]) |
| 箱ひげ図 | df.boxplot() | matplotlib.pyplot.boxplot(x) |
| 補間方式の指定 | df.quantile(.25, interpolation='linear') | np.percentile(x,25,method='linear') |
四分位は「分位点」「順序統計量」「ロバスト統計」「可視化」の交差点に位置する。 以下の概念を併せて学ぶと理解が安定する。
| グループ | 四分位と関連の深い概念 |
|---|---|
| 前提 | 順序統計量、 累積分布関数 CDF、 補間 (linear/midpoint/lower) |
| 並列 (位置の要約) | 中央値 Q2、 パーセンタイル、 トリム平均、 ヒンジ (Tukey 由来) |
| 派生 (ばらつき) | IQR、 五数要約、 MAD (中央絶対偏差)、 SIQR |
| 可視化 | 箱ひげ図、 ヴァイオリンプロット、 Q-Q プロット |
| 外れ値判定 | Tukey の 1.5×IQR、 3×IQR、 ロバスト z スコア |
| 対比される指標 | 平均、 標準偏差、 分散 (外れ値に弱い) |
| 発展 (回帰) | 分位点回帰、 ピンボール損失 |
| 応用 (リスク) | VaR、 CVaR、 信頼区間の代替としてのブートストラップ分位点 |
| 分布論 | 歪度、 尖度、 経験分布 |
| 機械学習 | 分位点ロス、 LightGBM の quantile objective |
df.quantile([.25,.5,.75]) で算出interpolation='linear' と 'midpoint' で Q1 が変わるか比較🍰 まずはやさしく
データを4つのグループに分ける値のことです。
極端な値に惑わされずに分析するために使います。
都道府県ごとの人口などのデータで考えます。
計算方法と外れ値の判定について読みましょう。
論文中に 「四分位」として登場する用語。
四分位 とは:データを大小順に並べて4等分する3つの値。Q1=25%点、Q2=中央値、Q3=75%点。箱ひげ図の基礎。
本ページの主目的は「SSDSE-B-2026 の 47 都道府県データ (総人口・出生数・消費支出) を題材に、 Q1=25%点・Q2=中央値・Q3=75%点を手計算と NumPy/Pandas で一致させる」ことである。 平均と異なり外れ値 (東京・鳥取) に影響されにくい点が中央値・四分位の強みとなる。
後段では (1) ソート後に位置 (n+1)/4, (n+1)/2, 3(n+1)/4 を求め線形補間、 (2) numpy.quantile の 9 種の補間方式 (linear / lower / nearest など) の違い、 (3) IQR = Q3 − Q1 と外れ値判定 1.5×IQR の実例を扱う。
🍰 まずはやさしく
データを4等分する境界線のことです。
真ん中あたりのデータの範囲を見るために使います。
お小遣いの金額を並べて分けるときのようなものです。
まずは道具としての使い道を直感的に掴みましょう。
四分位はデータを小さい順に並べて4 等分した区切り点。 Q1(25%)、 Q2(中央値)、 Q3(75%)。 SSDSE-B-2026 の消費支出(L3221、二人以上の世帯・月額)47 県を昇順に並べると、 Q1 ≈ 26.5 万、 中央値 ≈ 28 万、 Q3 ≈ 30.5 万。 平均値だけでなく Q1-Q3 で「真ん中の半分の範囲」が見えるのが四分位の強み。
四分位の定義と使い方を、 3 点のインライン SVG で押さえる。
Q1=下位 25%、 Q2=中央値=50%、 Q3=上位 25%(=下位 75%)。 データを 4 等分する境界点。
IQR=Q3-Q1 はばらつき指標。 ひげの外側に出た点が外れ値候補。
中央値が箱の中央にある=対称、 偏っていれば歪んだ分布。 平均と中央値の差で歪度を直感把握。
下の数直線上の点をドラッグ(スマホは指でスワイプ)すると、 Q1・Q2(中央値)・Q3・IQR がリアルタイムに再計算され、 縦線と色分け領域・箱ひげ図・外れ値フェンス(Q1−1.5×IQR / Q3+1.5×IQR)が連動して更新されます。 中央付近の点を動かしても四分位はあまり動かず、 端の点を大きく動かしても中央値・IQR がびくともしない——この頑健性(ロバスト性)を、 同時に表示される平均値・標準偏差の激しい動きと見比べて体感してください。
操作: 点をドラッグで移動 / 数直線上の空き部分をクリック/タップで点を追加 / 点をダブルクリックで削除(最少3点)。
linear(NumPy 既定・R type 7)は両隣の順序統計量を線形補間、 nearest は近い方、 lower/higher は片側に丸め、 midpoint は 2 点平均。 中央値 Q2 は多くの場合どの方式でも一致しやすい。 → 詳しくは 分位点 (quantile)。🍰 まずはやさしく
データを4等分する値を数式で表したものです。
正確な値を計算するために使います。
部活の記録を正確に分析するときに役立ちます。
記号の意味と計算の手順について詳しく読みましょう。
直感で全体像を掴んだら、 次は厳密な定義を見ます。 数式は短いものでも、 「何を入力にして、 何を出力するのか」を意識して読むと早く慣れます。
四分位数の計算は「順序統計量 (sorted data) のどの位置を取り出すか」という問題に帰着する。 ところが、 整数番目に該当しない位置 (例: 12.25 番目) をどう補間するかで複数の流儀がある。 NumPy 1.22 以降は numpy.quantile に 9 種類の method 引数があり、 統計教科書ごとに採用流儀が異なるため、 結果が微妙に異なる。
サンプル数 n、 求めたい分位点 q ∈ [0,1] に対し、 「仮想的な順位」 h = (n - α - β + 1) q + α を計算する (α, β は方法ごとに決まる定数)。 h の整数部 j、 小数部 g として、 結果は (1-g) × x_{(j)} + g × x_{(j+1)} となる。 つまり「ソート済みデータの第 j 番目と第 j+1 番目を g : (1-g) で按分する」だけ。 9 種類の方法の違いは α, β の値の違いだけだ。
| method | α | β | 典型用途 | 特徴 |
|---|---|---|---|---|
linear (既定) | 1 | 1 | R type 7、 NumPy 標準 | 連続分布の標本に最適 |
lower | − | − | 離散値のみ | 小さい側に丸める |
higher | − | − | 離散値のみ | 大きい側に丸める |
nearest | − | − | 最近傍法 | 隣接 2 点の近い方 |
midpoint | − | − | 中央 2 点平均 | 単純で頑健 |
weibull | 0 | 0 | SAS type 4 | 経験分布関数の逆 |
median_unbiased | 1/3 | 1/3 | 中央値の不偏推定 | 分布によらず中央バイアス除去 |
normal_unbiased | 3/8 | 3/8 | 正規分布で不偏 | 正規仮定下で最適 |
averaged_inverted_cdf | − | − | SAS type 2 | 不連続点で平均 |
→ 報告書では「補間方法: linear (NumPy 既定 / R type 7)」のように明示することが推奨される。 行政統計や論文では Excel の QUARTILE.INC が linear、 QUARTILE.EXC が weibull に対応する点も覚えておくと、 「Excel と Python で値が違う」という典型ミスを避けられる。
上の四分位の定義式・線形補間式に出てくる各記号が何を表すかを、 言葉・読み方・SSDSE-B-2026 (47 都道府県データ) での具体例の 3 段で翻訳します。 1 つずつ自分の言葉で言い換えられるようになると、 論文や教科書のスピードが一気に上がります。
| 記号 | 読み方 | 意味 | SSDSE-B-2026 47 都道府県での例 |
|---|---|---|---|
| $n$ | エヌ (sample size) | データの個数。 並べる対象の総数。 | $n = 47$ (47 都道府県) |
| $x_{(i)}$ | エックス カッコ アイ (order statistic) | 昇順ソート後の $i$ 番目の値。 順序統計量。 $x_{(1)}$ が最小、 $x_{(n)}$ が最大。 | 食料費(月額)なら $x_{(1)}=$ 愛媛県 71,088 円、 $x_{(47)}=$ 東京都 97,776 円 |
| $q$ | キュー (quantile fraction) | 分位の比率。 $0 \le q \le 1$。 四分位なら $q = 0.25, 0.5, 0.75$。 | $q=0.25$ は「下から 25%」の位置 |
| $Q_1$ | キューワン (first quartile) | 第 1 四分位。 下から 25% の位置の値。 $q=0.25$ の分位点。 | 食料費 $Q_1 \approx 76{,}000$ 円 |
| $Q_2$ | キューツー (median) | 第 2 四分位 = 中央値。 下から 50% の位置。 | 食料費 $Q_2 \approx 80{,}000$ 円 (24 番目の県) |
| $Q_3$ | キュースリー (third quartile) | 第 3 四分位。 下から 75% の位置の値。 $q=0.75$ の分位点。 | 食料費 $Q_3 \approx 85{,}000$ 円 |
| IQR | アイキューアール (Interquartile Range) | 四分位範囲 = $Q_3 - Q_1$。 中央 50% の幅。 外れ値に強い「ばらつき」指標。 | IQR $\approx 85{,}000 - 76{,}000 = 9{,}000$ 円 |
| $h$ (補間位置) | エイチ | $Q_1$ などが整数番目に来ないときの「小数位置」。 NumPy 既定 (linear / R type 7) では $h = (n-1) \cdot q + 1$。 | $n=47, q=0.25$ → $h = 46 \cdot 0.25 + 1 = 12.5$ (12 番目と 13 番目の中間) |
| $\lfloor h \rfloor, \lceil h \rceil$ | フロアエイチ / シーリングエイチ | $h$ を切り捨てた整数 / 切り上げた整数。 補間に使う両端のインデックス。 | $h=12.5$ → $\lfloor h \rfloor = 12, \lceil h \rceil = 13$ |
| $1.5 \cdot$ IQR | いってんごばい アイキューアール | 外れ値判定の係数。 Tukey の経験則。 $Q_1 - 1.5\cdot$IQR 未満 or $Q_3 + 1.5\cdot$IQR 超を外れ値とする。 | 外れ値境界 $\approx [62{,}500, 98{,}500]$ 円 |
SSDSE-B-2026 2023年データで、 47都道府県の食料費(L322101、二人以上の世帯・月額)の四分位を計算します。
| 統計量 | 食料費(円/世帯・月) | 代表的な県 |
|---|---|---|
| 最小値 | 62,800 | 沖縄 |
| Q1(25%点) | 72,400 | 西日本の郊外県 |
| Q2(中央値) | 79,200 | 中部地方 |
| Q3(75%点) | 85,600 | 東北・関東 |
| 最大値 | 98,400 | 青森 |
IQR = Q3 - Q1 = 85,600 - 72,400 = 13,200円。 真ん中50%が13,200円幅に収まる。 標準偏差(約8,900円)の約1.5倍が IQR の典型的関係。
SSDSE 2023 のデータでは沖縄県の食料費が下側フェンスに近いが外れ値ではない、 青森県が上側フェンス内、 と判定される。
(Q3-Q2) と (Q2-Q1) を比較すると、 分布の歪みが分かる:
np.percentile(..., method='linear') で計算すると、 最小 愛媛県 71,088 円 / Q1 76,014 円 / 中央値 79,939 円 / Q3 85,088 円 / 最大 東京都 97,776 円、 IQR = 9,074 円 となります。 中央値・Q3 は上の表とほぼ一致しますが、 実測では (Q3−Q2)=5,149 > (Q2−Q1)=3,925 とわずかに右へ歪む分布です(完全な左右対称ではない点に注意)。
数式だけでは「分かった気になる」だけで終わりがち。 ここで SSDSE-B-2026(教育用標準データセット — 47 都道府県 × 100+ 指標、 2018-2023 年度)の実値を当てはめて、 四分位 の挙動を電卓的に追体験します。
SSDSE-B-2026 は 統計センターの SSDSE 配布ページ から CSV を直接ダウンロードできます。 本サイトでは data/raw/SSDSE-B-2026.csv に配置している前提でコードを書いています。
このコードでやること: SSDSE-B-2026 の A1101 総人口(万人) 47 県分について、 4 種類の補間方法で Q25/Q50/Q75 を並べ、 同じデータでも値がどう変わるかを比較する。
📥 入力データ (SSDSE-B-2026 抜粋、 47 県):
1 2 3 4 5 6 7 8 9 10 11 | import pandas as pd import numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) pop = df.groupby('Prefecture')['A1101'].first().sort_values() methods = ['linear', 'lower', 'higher', 'midpoint'] print(f'{"method":<12} {"Q25":>10} {"Q50":>10} {"Q75":>10} {"IQR":>10}') for m in methods: q25, q50, q75 = np.quantile(pop, [0.25, 0.50, 0.75], method=m) print(f'{m:<12} {q25:>10.2f} {q50:>10.2f} {q75:>10.2f} {q75-q25:>10.2f}') |
📤 実行すると次の出力が得られる:
💬 結果の読み方: 単位は人(A1101 の生値)。 Q50 (中央値) は 4 方式とも同じ 1,549,000 人 (N=47 で 24 番目にあたる県)。 一方 Q25 は 1,026,000〜1,042,000 人、 Q75 は 2,535,000〜2,738,000 人と補間方法で 最大 20 万人ブレる。 IQR (四分位範囲) も 1,509,000 〜 1,696,000 人と約 19 万人差。 「同じデータでも方式次第で結論が変わる」典型例。 報告では必ず method='linear' 等を明示することが必要。
合成 8 件データで Q1, Q2, Q3 を計算する。
1 2 3 4 | import numpy as np x = np.array([3, 5, 7, 8, 10, 12, 15, 18]) q = np.percentile(x, [25, 50, 75]) print(f"Q1: {q[0]}, Q2: {q[1]}, Q3: {q[2]}") |
💬 手計算 (Step 2) と Python 出力が一致 (補間方法の違いで Q1,Q3 値が若干異なる)。
arr(1 次元数値配列)、パーセンタイル指定(25, 50, 75)。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 | # ── この抜粋で使うデータを用意します(SSDSE-B の 47 都道府県・最新年度)── import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) df = df[df['地域コード'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() df['年度'] = pd.to_numeric(df['年度'], errors='coerce') df = df[df['年度'] == df['年度'].max()] for _c in df.columns[3:]: df[_c] = pd.to_numeric(df[_c], errors='coerce') df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100 # 見本でよく使われる仮の列名を、実データから作っておく df['income'] = df['消費支出(二人以上の世帯)'] df['population'] = df['総人口'] _region = {'北海道': '北海道', '青森県': '東北', '岩手県': '東北', '宮城県': '東北', '秋田県': '東北', '山形県': '東北', '福島県': '東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東'} df['region'] = df['都道府県'].map(_region).fillna('その他') df['地域'] = df['region'] import numpy as np q1, q2, q3 = np.percentile(df['income'], [25, 50, 75]) # method(旧 interpolation)を指定可能 q1 = np.percentile(df['income'], 25, method='linear') |
df['income'](Series)または DataFrame、パーセンタイルのリスト。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # ── この抜粋で使うデータを用意します(SSDSE-B の 47 都道府県・最新年度)── import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) df = df[df['地域コード'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() df['年度'] = pd.to_numeric(df['年度'], errors='coerce') df = df[df['年度'] == df['年度'].max()] for _c in df.columns[3:]: df[_c] = pd.to_numeric(df[_c], errors='coerce') df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100 # 見本でよく使われる仮の列名を、実データから作っておく df['income'] = df['消費支出(二人以上の世帯)'] df['population'] = df['総人口'] _region = {'北海道': '北海道', '青森県': '東北', '岩手県': '東北', '宮城県': '東北', '秋田県': '東北', '山形県': '東北', '福島県': '東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東'} df['region'] = df['都道府県'].map(_region).fillna('その他') df['地域'] = df['region'] print(df['income'].quantile([0.25, 0.5, 0.75])) print(df.describe()) # count, mean, std, min, 25%, 50%, 75%, max |
arr(数値配列)、interpolation や axis オプション。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # ── この抜粋で使うデータを用意します(SSDSE-B の 47 都道府県・最新年度)── import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) df = df[df['地域コード'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() df['年度'] = pd.to_numeric(df['年度'], errors='coerce') df = df[df['年度'] == df['年度'].max()] for _c in df.columns[3:]: df[_c] = pd.to_numeric(df[_c], errors='coerce') df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100 # 見本でよく使われる仮の列名を、実データから作っておく df['income'] = df['消費支出(二人以上の世帯)'] df['population'] = df['総人口'] _region = {'北海道': '北海道', '青森県': '東北', '岩手県': '東北', '宮城県': '東北', '秋田県': '東北', '山形県': '東北', '福島県': '東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東'} df['region'] = df['都道府県'].map(_region).fillna('その他') df['地域'] = df['region'] from scipy.stats import iqr, scoreatpercentile print(iqr(df['income'])) # IQR print(scoreatpercentile(df['income'], 25)) # Q1 |
外れ値に強い標準化として、 平均/SD ではなく中央値/IQR を使う。
X(DataFrame または ndarray、外れ値を含み得る)。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.preprocessing import RobustScaler # (x - Q2) / IQR でスケーリング X_robust = RobustScaler().fit_transform(X) |
df(DataFrame)、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 | # ── この抜粋で使うデータを用意します(SSDSE-B の 47 都道府県・最新年度)── import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) df = df[df['地域コード'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() df['年度'] = pd.to_numeric(df['年度'], errors='coerce') df = df[df['年度'] == df['年度'].max()] for _c in df.columns[3:]: df[_c] = pd.to_numeric(df[_c], errors='coerce') df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100 # 見本でよく使われる仮の列名を、実データから作っておく df['income'] = df['消費支出(二人以上の世帯)'] df['population'] = df['総人口'] _region = {'北海道': '北海道', '青森県': '東北', '岩手県': '東北', '宮城県': '東北', '秋田県': '東北', '山形県': '東北', '福島県': '東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東'} df['region'] = df['都道府県'].map(_region).fillna('その他') df['地域'] = df['region'] import seaborn as sns sns.boxplot(data=df, x='region', y='income', whis=1.5) # whis=1.5 で Tukey fence、 whis='range' で min-max |
🎯 このコードでやること: 47 都道府県の総人口について、 Hyndman & Fan (1996) が整理した 6 通りの分位点定義で四分位数を計算し、 値がどれだけ食い違うかを並べます。 numpy の既定は type 7、 R の既定も type 7 ですが、 SPSS や Excel は別の定義を使います。 「四分位数」という同じ言葉で、 ソフトによって違う数字が出ることを実際の 47 県データで確かめます。 なお pd.read_csv('data/raw/SSDSE-B-2026.csv') をパス変数にせず直書きしているのは、 初学者が「パスをどこに書くべきか」で迷わないようにするためです。 CSV を同じ階層に置けばそのまま動きます。
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 | # 四分位 を SSDSE-B-2026 で確かめる最小コード import pandas as pd import numpy as np # 1) SSDSE-B-2026(教育用標準データセット)を読み込み df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1) print('shape:', df.shape) # (564, 112) — 47 都道府県 × 6 年度 print('cols head:', list(df.columns[:8])) # 2) 直近年度(2023 年度)に絞る df23 = df[df['年度'] == 2023].copy() print('rows in 2023:', len(df23)) # 3) 四分位 を動かすために必要な列だけ取り出す y = df23['合計特殊出生率'].astype(float) x = df23['総人口'].astype(float) print('y stats:', y.describe().round(3).to_dict()) print('x stats:', x.describe().round(0).to_dict()) # 4) 四分位 の本処理(このページの主題) # — 具体実装は同カテゴリの個別ページにも掲載 print('---- 四分位 結果 ----') print('mean y:', y.mean().round(3), '/ std y:', round(y.std(), 3)) print('mean x:', x.mean().round(0), '/ std x:', round(x.std(), 0)) print('corr(x, y):', y.corr(x).round(3)) |
うまく動かないときは ①data/raw/SSDSE-B-2026.csv のパス、 ②encoding='cp932'(SSDSE-B は Shift_JIS 系)、 ③1 行目に英数字ヘッダ、 2 行目に日本語列名が入る構造なので skiprows=1 が必要、 の 3 点を確認してください。
SciPy には scipy.stats.mstats.mquantiles(x, alphap=, betap=) という関数があり、 α / β の値を 2 引数で直接指定できる。 9 流儀すべてを 1 API で実装できる利点があり、 専門書 (Hyndman & Fan, 1996) の公式実装に最も近い。
このコードでやること: SSDSE 47 県人口に対し、 scipy.stats.mstats.mquantiles で 6 種類の流儀 (R type 1 〜 9) の Q25/Q75 を一覧表示する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import pandas as pd from scipy.stats import mstats df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) pop = df.groupby('Prefecture')['A1101'].first().values # Hyndman & Fan (1996) の 6 type に対応する (alphap, betap) types = { 'type 4 (Weibull)' : (0.0, 0.0), 'type 5 (Hazen)' : (0.5, 0.5), 'type 6 (Cunnane)' : (0.4, 0.4), 'type 7 (R/NumPy linear)': (1.0, 1.0), 'type 8 (median unbiased)': (1/3, 1/3), 'type 9 (normal unbiased)': (3/8, 3/8), } print(f'{"flavor":<24} {"Q25":>10} {"Q75":>10}') for name, (a, b) in types.items(): q = mstats.mquantiles(pop, prob=[0.25, 0.75], alphap=a, betap=b) print(f'{name:<24} {q[0]:>10.2f} {q[1]:>10.2f}') |
📤 実行例:
💬 結果の読み方: SSDSE 47 県(人口 A1101、 単位は人)の Q25 は 1,026,000 〜 1,034,000 人、 Q75 は 2,636,500 〜 2,738,000 人で揺れる。 Q75 で約 10 万人 (3〜4%) の差。 サンプルサイズ n=47 と中程度のため流儀差が見えるが、 n=1000 以上では実用上同じ値になる。 「47 都道府県分析」のようなマイクロデータでは流儀を明示すること。
四分位の計算には9種類もの定義があり、 ライブラリによって値が違います。 numpy(デフォルト linear)、 pandas(linear)、 Excel(PERCENTILE.INC)、 R(type=7)、 SAS(type=3)など。 同じデータで値が 数%変わる ことも普通。 報告時は「numpy.percentile (interpolation='linear') で計算」のように明示する。 小サンプル(n < 20)では差が大きいので注意。
正規分布では「IQR ≈ 1.349 × SD」という関係がありますが、 これは正規分布限定です。 裾の重い分布(t分布、 ラプラス分布等)や対数正規分布では関係が崩れる。 「IQR が大きい → SD も大きい」と即断せず、 必ず両方を計算して比較する。 また外れ値があると IQR は安定だが SD は爆発する、 という性質の違いも覚える。
Tukey の規則はあくまで探索的に注目すべき点を示す目安。 正規分布なら全データの 0.7% がフェンスを超えるので、 n = 1000 のデータなら 7 個程度は「外れ値判定」されて当然。 「フェンスを超えた = 異常」と即断して除外すると、 重要な情報を失います。 必ず散布図や原データに戻って、 文脈的に異常か判断する。
双峰分布(ふた山)で IQR を計算すると、 「真ん中の谷」がIQRに含まれ、 「分布の広がり」を誤解しやすい。 例:「都市部 vs 郊外」で混合した家計データでは IQR が両群の差を反映してしまう。 必ずヒストグラム or KDE で分布の形を確認し、 必要なら群別に四分位を計算する。
Q2 は中央値であって、 一般に平均と等しくありません。 対称分布では一致しますが、 右に裾を引く分布(所得・人口など)では「中央値 < 平均」が普通。 政策レポートで「世帯所得の中央値」と「平均世帯所得」を区別せずに使うと、 誤解を生む。 平均は外れ値の影響を強く受けるので、 中央値の方が「典型値」を表します。
n = 5 のデータで「Q1 と Q3」を計算しても、 補間に意味がなく、 サンプルが 1 個変わるだけで値が大きく動く。 n < 10 では四分位より「全データの表示」が誠実。 また Q1/Q3 の標準誤差は中央値より大きいので、 信頼区間も併記する(ブートストラップ法など)。
この用語を実務で使うときにつまずきやすい点を、 失敗パターン別に整理しました。 1 度経験すれば回避できるものばかりですが、 先に知っておくと事故が大幅に減ります。
John Tukey (1977) が提案した古典的な外れ値検出ルールは 下限 = Q25 − 1.5×IQR、 上限 = Q75 + 1.5×IQR。 これを超える値を「mild outlier」、 さらに 3×IQR を超えるものを「extreme outlier」と呼ぶ。 正規分布なら全データの約 99.3 % が 1.5×IQR の範囲に収まる (片側 0.35% × 2)。
正規分布における IQR は 1.349σ。 1.5 × 1.349σ ≒ 2.024σ なので、 下端 Q25 = μ−0.674σ から下に 2.024σ 引くと μ−2.698σ となり、 これは正規分布で約 0.35% に相当する位置。 つまり「真に外れ値である確率 0.7% 程度の閾値」として Tukey が経験的に選んだのが 1.5 という係数だ。 厳しめにするなら 3.0 (extreme)、 緩めるなら 1.0 (loose) を使う流儀もある。
このコードでやること: SSDSE-B-2026 の 47 県人口に Tukey 1.5×IQR ルールを適用し、 外れ値判定された県名と値を出力する。
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]) pop = df.groupby('Prefecture')['A1101'].first() q1, q3 = np.quantile(pop, [0.25, 0.75]) iqr = q3 - q1 lower_mild, upper_mild = q1 - 1.5*iqr, q3 + 1.5*iqr lower_ext, upper_ext = q1 - 3.0*iqr, q3 + 3.0*iqr print(f'Q1={q1:.1f} Q3={q3:.1f} IQR={iqr:.1f}') print(f'Mild fence : [{lower_mild:.1f}, {upper_mild:.1f}]') print(f'Extreme : [{lower_ext:.1f}, {upper_ext:.1f}]') mild = pop[(pop < lower_mild) | (pop > upper_mild)] extreme = pop[(pop < lower_ext) | (pop > upper_ext)] print('\nMild outliers:') print(mild.sort_values(ascending=False)) print('\nExtreme outliers:') print(extreme.sort_values(ascending=False)) |
📤 実行例:
💬 結果の読み方: 47 県のうち上位 9 県が「mild outlier」、 上位 4 県が「extreme outlier」と判定される。 これは「東京・神奈川・大阪等の都市圏は他県と比べて統計的に異質」という直感を IQR で定量化した結果。 ただし「外れ値 = 削除」ではなく「外れ値 = 個別検討」が原則。 都道府県データのように母集団そのものなら「外れ値も含めて分析」が正しい姿勢。 1.5×IQR は探索的データ分析 (EDA) の最初のスクリーニング指標として用いる。
単一データに対する Q25/Q75 だけでなく、 「どんなグループに分けても四分位数の差が顕著か」を検定するのが groupby + quantile パターン。 SSDSE では地方ブロック (北海道・東北・関東・中部・近畿・中国・四国・九州沖縄) ごとの人口分布を見るのに使える。
このコードでやること: SSDSE-B-2026 を地方ブロック別にグループ化し、 各ブロックの人口の Q25/Q50/Q75 と IQR を一覧化する。
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 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) pop = df.groupby('Prefecture')['A1101'].first().reset_index() region_map = { '北海道':'北海道', '青森県':'東北','岩手県':'東北','宮城県':'東北','秋田県':'東北','山形県':'東北','福島県':'東北', '茨城県':'関東','栃木県':'関東','群馬県':'関東','埼玉県':'関東','千葉県':'関東','東京都':'関東','神奈川県':'関東', '新潟県':'中部','富山県':'中部','石川県':'中部','福井県':'中部','山梨県':'中部','長野県':'中部','岐阜県':'中部','静岡県':'中部','愛知県':'中部', '三重県':'近畿','滋賀県':'近畿','京都府':'近畿','大阪府':'近畿','兵庫県':'近畿','奈良県':'近畿','和歌山県':'近畿', '鳥取県':'中国','島根県':'中国','岡山県':'中国','広島県':'中国','山口県':'中国', '徳島県':'四国','香川県':'四国','愛媛県':'四国','高知県':'四国', '福岡県':'九州沖縄','佐賀県':'九州沖縄','長崎県':'九州沖縄','熊本県':'九州沖縄','大分県':'九州沖縄','宮崎県':'九州沖縄','鹿児島県':'九州沖縄','沖縄県':'九州沖縄', } pop['region'] = pop['Prefecture'].map(region_map) stats = pop.groupby('region')['A1101'].agg( n='size', q25=lambda s: s.quantile(0.25), median=lambda s: s.quantile(0.50), q75=lambda s: s.quantile(0.75), iqr=lambda s: s.quantile(0.75) - s.quantile(0.25), ) print(stats.round(1)) |
📤 実行例:
💬 結果の読み方: 関東 (IQR 591.6) と近畿 (IQR 260.1) は内部のバラつきが大きい (東京/大阪と他県の格差)。 四国・九州沖縄は IQR が小さく、 県間の差が比較的均質。 中央値で比べると関東 625.7 → 中部 193.1 → 東北 117.4 と段階的に減る。 「ブロック内の代表値 + ブロック内ばらつき」を 1 枚で把握できるのが groupby+quantile の威力。
linear。 旧版・Excel・R・SAS でそれぞれ違うため、 「言語間移行で値が変わる」事故が起こる。 数式を言葉で読み解くと α, β の違いだけ。 必ず method= を明示。linear は連続分布前提。 5 段階リッカート尺度のような離散データに使うと「2.75」のような実在しない値が出る。 離散なら lower / higher / nearest を選ぶ。numpy.quantile ではなく statsmodels.stats.DescrStatsW か numpy.percentile(weights=...) 系を使う必要がある。 単純な np.quantile では誤った値が出る。四分位数のいちばん素朴なイメージは、 ソートしたデータを面積(個数)で 4 等分する 3 本の縦線です。 左から順に Q1(下側四分位数=下から 25%)、 Q2(中央値=50%)、 Q3(上側四分位数=75%)。 各区間にはデータのちょうど 1/4 ずつが入ります。 値そのものではなく順位で線を引くので、 いちばん大きい 1 個が 10 倍になっても Q1〜Q3 は 1 ミリも動かない——これが「頑健(ロバスト)」の正体です。
広がりは IQR=Q3−Q1 で測る。 これは「真ん中の 50% がどれだけの幅に収まっているか」。 標準偏差が全データの二乗和で決まるのに対し、 IQR は両端の 25% ずつを最初から無視するので、 外れ値に強い。 SSDSE-B-2026(2023 年・47 都道府県)の人口で実測すると、 Q1=103.4 万人 / Q2=154.9 万人 / Q3=263.6 万人、 IQR=160.2 万人。 東京都(1408.6 万人)を仮に 2 倍にしても Q1・Q2・Q3・IQR はすべて不変です。
📝 補足(教材):「4 等分」という言葉から Q1・Q2・Q3 が等間隔だと誤解しがちですが、 それは左右対称な分布のときだけ。 人口のように右へ裾を引く分布では (Q3−Q2)=108.7 万人 ≫ (Q2−Q1)=51.5 万人 と右側が広い。 3 本の線の間隔の不揃いそのものが分布の歪みを語る、 と読むのが上級者の見方です。
「補間法で値が変わる」「小標本で不安定」は言葉だけだと軽く聞こえます。 ここでは SSDSE-B-2026 の実測値で、 どれくらいブレるのかを数字で示します(すべて 2023 年・A1101 人口・単位 万人)。
Hyndman & Fan (1996) が整理した 9 つの分位数推定法を、 numpy.percentile(..., method=) の対応する名前でそのまま計算した実測結果です。 R の quantile(type=)、 Excel、 SAS はこのどれかに対応します。
| type | numpy method 名 | Q1 | Q3 | IQR | 代表的な採用 |
|---|---|---|---|---|---|
| 1 | inverted_cdf | 102.6 | 273.8 | 171.2 | 経験分布そのまま |
| 3 | closest_observation | 102.6 | 253.5 | 150.9 | SAS 既定 (type=3) |
| 4 | interpolated_inverted_cdf | 102.1 | 258.6 | 156.5 | — |
| 5 | hazen | 103.0 | 268.7 | 165.7 | 水文学で伝統的 |
| 6 | weibull | 102.6 | 273.8 | 171.2 | Excel PERCENTILE.EXC / Minitab |
| 7 | linear | 103.4 | 263.6 | 160.2 | numpy / pandas / R / Excel.INC 既定 |
| 8 | median_unbiased | 102.9 | 270.4 | 167.6 | Hyndman-Fan 推奨 |
| 9 | normal_unbiased | 102.9 | 270.0 | 167.1 | 正規分布で不偏 |
💬 読み方:IQR は最小 150.9(type3)から最大 171.2(type1/6)まで動き、 既定の linear(160.2)を基準にすると約 12.7% の幅があります。 「どの言語で計算したか」だけで報告値が 1 割ずれる、 という現実。 必ず method / type を明記し、 チーム内で 1 つに固定するのが唯一の防御策です(既定の linear=type7 が最も無難)。
東北 6 県の人口(2023 年)は、 昇順で 91.4 / 102.6 / 116.3 / 118.4 / 176.7 / 226.4 万人(秋田・青森・岩手・山形・宮城・福島)。 この n=6 で Q1・Q3 を計算すると、 補間法だけで IQR が激変します。
| method | Q1 | Q3 | IQR |
|---|---|---|---|
lower | 102.6 | 118.4 | 15.8 |
linear(既定) | 106.0 | 162.1 | 56.1 |
higher | 116.3 | 176.7 | 60.4 |
IQR が 15.8 〜 60.4 万人(約 4 倍)まで動きます。 47 県(n=47)では 1 割強の差だったものが、 n=6 では手が付けられないほど不安定に。 n が小さいほど四分位数は生データ 1 点の位置に強く引きずられるため、 n が二桁前半以下なら「四分位数を報告するより全データを見せる」方が誠実です。 どうしても幅を示したいときは ブートストラップで Q1・Q3 の信頼区間を添えます。
架空の 5 段階満足度アンケート回答 [1, 1, 2, 2, 2, 3, 3, 4, 5](架空データ)を linear で計算すると Q1=2、 Q3=3、 IQR=1。 一方 lower でも Q1=2, Q3=3 と一致しますが、 回答が [3,3,3,3,3,3,4] のように同値が多いと Q1=Q2=Q3=3、 IQR=0 になります。 IQR=0 は「ばらつきゼロ」ではなく「中央 50% が同じ値」という意味。 リッカート尺度など離散データでは、 実在しない小数(例 2.75)を避けるため lower/higher/nearest を選ぶか、 度数分布そのものを併記するのが安全です。
四分位数は単独で使うより、 最小値・Q1・中央値・Q3・最大値の 5 つをセットにした五数要約 (five-number summary)として扱うのが定石です。 SSDSE 人口なら 46.6(鳥取)/ 103.4 / 154.9 / 263.6 / 1408.6(東京)万人。 これをそのまま図にしたのが箱ひげ図で、 箱の両端が Q1・Q3、 箱の中の線が中央値、 ヒゲの先が Tukey フェンス、 その外の点が外れ値候補。 df.describe() が出す 8 行のうち 5 行はこの五数要約です。 → 箱ひげ図
Tukey (1977) が箱ひげ図を作ったとき使ったのは、 厳密な「四分位数」ではなくヒンジ (lower/upper hinge)という近縁量でした。 中央値でデータを半分に割り、 各半分の中央値をヒンジとする——手計算しやすい定義です。 現代の numpy/pandas の四分位数(linear=type7)とは値が微妙に違い、 これも「実装で値が変わる」一因。 R の fivenum() はこのヒンジ流儀(type に近い挙動)を返すため、 quantile() の結果と食い違うことがあります。
四分位偏差 QD=(Q3−Q1)/2=IQR/2。 人口データでは 80.1 万人。 標準偏差の頑健版として、 中央値と組で「中央値 ± QD」のように使えます。 さらに 3 点の間隔比から歪みも読めます:四分位歪度 (Bowley skewness) = ((Q3−Q2)−(Q2−Q1)) / (Q3−Q1)。 人口では (108.7−51.5)/160.2 ≒ +0.36 と正で、 右へ裾を引く分布を順位ベースだけで定量化できます(平均や標準偏差を一切使わない歪度指標)。
四分位数の考え方を回帰に持ち込んだのが分位点回帰。 通常の最小二乗回帰が「説明変数を固定したときの平均」を推定するのに対し、 分位点回帰は「Q1 の線」「中央値の線」「Q3 の線」を別々に引きます。 所得のように分布の裾で挙動が違うデータで威力を発揮し、 外れ値にも頑健。 → 分位点回帰
上の type1–9 を一括で試すには numpy.percentile(x, [25,75], method=名) を回すか、 scipy.stats.mstats.mquantiles(x, alphap, betap) で α, β を直接指定します(このページの Python セクションに実行例あり)。 ロバスト統計の観点では、 四分位ベースの散らばりに加えて MAD(中央絶対偏差) も併用すると分布の性質を多面的に掴めます。
四分位数を軸に、 本サイト内の実在ページを前提 → 並列 → 発展の順に並べました(いずれも相対リンク)。
📝 補足(教材):「パーセンタイル」「五数要約」「IQR(略号 iqr)」の単独ページは本サイトには未作成のため、 それぞれ 分位点・箱ひげ図・IQR のページで代替してください。
p値だけでなく効果量も併記するのが現代統計の標準。 主要な指標と 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 |
| ANOVA | η² (eta²) | 0.01 | 0.06 | 0.14 |
| χ² | Cramér's V | 0.1 | 0.3 | 0.5 |
| ロジスティック | Odds Ratio | 1.5 | 2.5 | 4.0 |
四分位 がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。
🌐 統計・データサイエンス › 記述統計 › ばらつき › 四分位
中心に 四分位 を置き、 そこから 中央値・箱ひげ図・平均・ヒストグラム・散布図・外れ値検出 計 6 個の用語へ、 前提・兄弟・発展形といった関係を矢印で結んでいます。 線がどちら向きかを見れば、 先に読むべき用語とあとから読む用語が分かります。 ノードはドラッグで動かせ、 ホイールでズーム、 クリックでその用語のページへ遷移します。
大きな円が小さな円を包含する Circle Packing 図。 「四分位」は緑色でハイライト。
長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「四分位」は緑色でハイライト。
| マップ | 分かること | こんな時に見る |
|---|---|---|
| 🔗 関係マップ | 手法間の横の関係(前提→発展→応用) | 「次に何を学べばよい?」 学習順序の判断 |
| ⭕ 包含マップ | 分類体系の入れ子構造(上位⊃下位) | 「この手法はどんなジャンルに属する?」 |
| 🌳 ツリーマップ | 分野の規模比較(面積=ボリューム) | 「データサイエンス全体の俯瞰像」 |
💡 3 つの図は同じ位置関係を別の角度から描いています。 関係マップは 四分位 の隣に何が並ぶかを、 包含マップとツリーマップは 統計・データサイエンス → ばらつき → 四分位 という入れ子の位置を示します。 「ばらつきには他に何があったか」を思い出したいときは包含マップを、 「次に何を読むか」を決めたいときは関係マップを開いてください。
「四分位数」は単独で完結する手法ではなく、 隣接領域と連携することで真価を発揮する。
SSDSE-B-2026 の都道府県人口を四分位点で要約すると、 Q1 ≈ 103 万・Q2 (中央値) ≈ 155 万・Q3 ≈ 264 万、 上位 25% は急に伸びる右裾分布だと一目で分かる。
「quartile」を含む手法選択は、 データの性質・分析目的・運用制約の 3 軸で決まる。 以下に典型シナリオと対応する手法の組合せを示す。
| シナリオ | 重視する観点 | 候補手法 |
|---|---|---|
| 分布が左右対称・正規に近い | 平均±標準偏差で十分 | 四分位は概観として併用 |
| 外れ値が多い / 歪んだ分布 (人口・所得) | 頑健な中心と散らばりが必要 | 四分位 Q1/Q2/Q3 と IQR を主指標に |
| 複数群を比較したい | 群間の散らばりを一目で見たい | 箱ひげ図 (四分位を可視化) |
| 外れ値を機械的に検出したい | Tukey ルールが標準 | Q1-1.5×IQR / Q3+1.5×IQR の外を外れ値 |
| 学生の成績順位を扱う | 上位 25% / 中位 50% / 下位 25% | 四分位順位を直接使用 |
| 47 都道府県の散らばりを見る | SSDSE-B-2026 で歪み大 | Q1/Q2/Q3 + IQR で要約 |
論文・記事に登場する用語のリンクで該当箇所へジャンプ: