このページ内のセクションへ素早く飛べます(クリックで該当箇所へジャンプ):
「eda」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「eda」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。
これらのキーワードは「eda の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。
🍰 まずはやさしく
データの中身をのぞく準備運動のようなものです。
分析の前にデータの全体像をつかむために使います。
スマホの利用時間をグラフにして眺めるような作業です。
この章では分析の手順や注意点を学びます。
可視化と集計でデータを探索する分析手法
🍰 まずはやさしく
データの顔をうかがうための道具箱です。
どんな特徴があるかを見つけるために使います。
部活の記録をグラフにして傾向を見るイメージです。
ここでは使うグラフやツールの種類について読みます。
ヒストグラム、 箱ひげ図、 散布図、 ペアプロット、 相関行列 — EDA はこれらを駆使してデータの『顔』を掴む段階。 pandas/seaborn/plotly が主役。
本ページは 探索的データ分析(Exploratory Data Analysis (EDA)) を、 ジャストインタイム型データサイエンス教育の文脈で 12 のセクションに分けて解説します。 上から順に読まなくても、 「🔖 キーワード索引」から必要箇所だけ拾い読みすることもできます。
🍰 まずはやさしく
データから直感的に答えを探す探偵のような作業です。
なぜその分析が必要なのかを体感するために使います。
買い物で商品の口コミをざっと眺める感覚に似ています。
このあと具体的な例や計算方法について読みます。
探索的データ分析(Exploratory Data Analysis (EDA))は、 言葉だけ眺めても「で、 何が嬉しいの?」となりがちです。 ここでは具体例で 『なぜ必要か / どう役立つか』 を一気に体感しましょう。
| 場面 | 探索的データ分析が登場する例 | 何が分かるか |
|---|---|---|
| 論文の Methods 節 | 「探索的データ分析を用いて分析した」 | 手法の前提と限界が文脈に乗る |
| 実務レポート | 「探索的データ分析の観点で評価」 | 意思決定の根拠が明確化 |
| 教育・学習 | SSDSE-B-2026 を題材に演習 | 実データで本物の感覚が得られる |
| 政策・社会 | プロセス 分野で標準的に登場 | EBPM や DX の議論に直結 |
本ページではこのあと、 数式(または定義)・SSDSE 実データ計算・Python実装・落とし穴 を順番に追いかけて、 用語を「使える知識」にしていきます。
データを読み・解釈し・批判する力。 数値の背後にある文脈とバイアスを意識してください。
本ページでは 探索的データ分析 を、 定義・前提条件・使い方・落とし穴の順に整理して解説します。 厳密な定義より、 まず何を、 いつ、 どう使うかを理解することを優先してください。
🍰 まずはやさしく
グラフや集計でデータを調べる手法のことです。
データの正しさを判断する基本の道具として使います。
テストの結果を平均や比率でまとめる作業と同じです。
ここでは計算の仕組みや言葉の意味について読みます。
探索的データ分析 は概念的定義が中心ですが、 ジャストインタイム教育の観点からは「関連量のなかで何を計算しているか」を式で押さえると理解が深まります。 代表的に使われる数式は:
$$ \text{基本量}_{eda} = f(\text{入力データ}, \text{前提}, \text{パラメータ}) $$
定義式の一般形:
$$ Q = \frac{1}{n} \sum_{i=1}^{n} g(x_i) $$
ここで $g(\cdot)$ は用語に応じた評価関数(カウント、 平均、 比、 オッズなど)。 具体形は次セクション「🔬 数式を言葉で読み解く」で確認します。
可視化と集計でデータを探索する分析手法
英語名 Exploratory Data Analysis。 同義・関連語:EDA。
この用語を理解・使用するときは、 次のような前提を意識してください:
EDA で頻出する描述統計を「数式 → 言葉での意味 → SSDSE-B-2026 での値」の 3 段で整理します。
$$\bar{x} = \frac{1}{n}\sum_{i=1}^{n} x_i, \quad \text{median}(x) = x_{(\lceil n/2 \rceil)}, \quad \text{mode}(x) = \arg\max_v |\{i: x_i = v\}|$$
2023 年人口 (n=47): $\bar{x} = 2{,}645{,}809$、 中央値 $= 1{,}549{,}000$。 平均 > 中央値で 右に歪んだ分布と読める。
$$s = \sqrt{\frac{1}{n-1}\sum_{i=1}^{n}(x_i - \bar{x})^2}, \quad \text{IQR} = Q_3 - Q_1, \quad \text{MAD} = \text{median}(|x_i - \text{median}(x)|)$$
2023 年人口: $s = 2{,}797{,}551$、 $Q_1 = 1{,}034{,}000$、 $Q_3 = 2{,}636{,}500$、 $\text{IQR} = 1{,}602{,}500$。 IQR は外れ値の影響を受けにくく、 都心 9 都道府県を含めても安定。
$$\text{skewness} = \frac{1}{n}\sum_{i=1}^{n}\left(\frac{x_i - \bar{x}}{s}\right)^3, \quad \text{kurtosis} = \frac{1}{n}\sum_{i=1}^{n}\left(\frac{x_i - \bar{x}}{s}\right)^4 - 3$$
2023 年人口: 歪度 = 2.219 (強い右歪み)、 尖度 = 4.951 (正規分布 0 より大きい尖り)。 これだけで「正規分布で扱うのは不適切」と判断できる。 数式を言葉で読み解くと、 歪度は「3 乗の符号で左右非対称を測る」、 尖度は「4 乗で外れ値の影響を強調しつつ正規 (=3) からの偏差を測る」となる。
$$\text{Tukey fence (upper)} = Q_3 + 1.5 \times \text{IQR}, \quad \text{Tukey fence (lower)} = Q_1 - 1.5 \times \text{IQR}$$
2023 年人口: 上限フェンス = $2{,}636{,}500 + 1.5 \times 1{,}602{,}500 = 5{,}040{,}250$。 これを超えるのは 北海道、 埼玉、 千葉、 東京、 神奈川、 愛知、 大阪、 兵庫、 福岡の 9 都道府県で、 これは「政令指定都市以上の人口集中圏」と一致。
EDA の発明者 John W. Tukey (1977) は「データから仮説を発見する」プロセスを 5 数要約 + 箱ひげ図 で形式化した。 Tukey 自身の論文に出る IQR ルールは以下:
$$\text{外れ値判定} = \{x : x < Q_1 - 1.5 \times \text{IQR}\} \cup \{x : x > Q_3 + 1.5 \times \text{IQR}\}$$ $$\text{IQR} = Q_3 - Q_1, \quad Q_1 = \text{第 25 パーセンタイル}, \quad Q_3 = \text{第 75 パーセンタイル}$$🎯 このコードでやること:SSDSE-B-2026 の都道府県人口に Tukey の IQR ルールを適用して、 外れ値県を自動抽出。 同時に 5 数要約 + 箱ひげ図を生成して EDA の最初の 1 枚を作る。
📥 入力データ: SSDSE-B-2026 47 県の総人口 A1101 (人、 2023 年)。
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 numpy as np import pandas as pd # SSDSE-B-2026 を読み込み、2023 年・47 都道府県の総人口 A1101 を取り出す df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) sub = df[df['SSDSE-B-2026'] == 2023] pop = sub['A1101'] # 5 数要約 (Tukey 流: min, Q1, median, Q3, max) q1, q2, q3 = pop.quantile([0.25, 0.5, 0.75]) iqr = q3 - q1 lower_fence = q1 - 1.5 * iqr upper_fence = q3 + 1.5 * iqr print(f"min : {pop.min():>11,}") print(f"Q1 (25%) : {q1:>11,.0f}") print(f"median : {q2:>11,.0f}") print(f"Q3 (75%) : {q3:>11,.0f}") print(f"max : {pop.max():>11,}") print(f"IQR : {iqr:>11,.0f}") print(f"下側 fence: {lower_fence:>11,.0f}") print(f"上側 fence: {upper_fence:>11,.0f}") # 外れ値判定 (Tukey の 1.5×IQR / 3×IQR ルール) outliers = sub[(pop < lower_fence) | (pop > upper_fence)] far = sub[(pop < q1 - 3 * iqr) | (pop > q3 + 3 * iqr)] print(f"\n外れ値 (1.5×IQR 超): {len(outliers)} 県, {list(outliers['Prefecture'])}") print(f"far outliers (3×IQR 超): {len(far)} 県, {list(far['Prefecture'])}") |
📤 実行例:
💬 結果の読み方:47 県の人口は median 約 155 万人、 IQR 約 160 万人、 上側 fence 約 504 万人を超える 9 都道府県 (北海道・埼玉・千葉・東京・神奈川・愛知・大阪・兵庫・福岡) が外れ値。 とくに東京 14,086 千人・神奈川・愛知・大阪の 4 都府県は Q3 + 3×IQR = 7,444,000 を超え far outlier。 これは「分析時に東京を別扱いする」という EDA からの仮説検出。 1.5 を 1.5 のまま使うのは Tukey 1977 の慣行で、 分布が正規でない場合は「外れ値が多数」が正常な姿。 慌てて削除せず、 まず なぜそうなるか を考えるのが EDA の哲学。
探索的データ分析は、グラフを数枚描いて印象を述べる作業ではない。最終的には「このデータで、何を信じてよく、何をまだ信じてはいけないか」を切り分ける監査工程である。平均値、中央値、四分位範囲、欠損率、外れ値、カテゴリの偏り、時点のずれ、単位の違い、入力ミス、母集団の取り違えを順に確認し、後続の推定・予測・意思決定に渡してよい状態かを判断する。EDA が弱いと、どれほど高度なモデルを使っても、モデルは単にデータの欠陥を高精度に再現するだけになる。
実務で最初に見るべきなのは、各列の定義と観測単位である。都道府県データなら 1 行が都道府県なのか、市区町村なのか、年度なのか、調査時点なのかを確認する。売上データなら 1 行が明細なのか、注文なのか、顧客月次なのかで解釈が変わる。観測単位を曖昧にしたまま相関係数や回帰係数を読むと、個人レベルの傾向を地域レベルに誤って持ち込む生態学的誤謬や、集計後に符号が反転するシンプソンのパラドックスを見落とす。
次に、欠損の意味を分類する。欠損は単なる空欄ではなく、「本当に値が存在しない」「調査対象外」「測定できなかった」「集計前に秘匿された」「入力処理で落ちた」のどれかである。たとえば自治体統計で小地域の値が秘匿されている場合、0 とみなして合計すれば過小評価になる。アンケートで所得が未回答なら、欠損している人ほど所得が高い、または低い可能性もある。EDA では欠損率を列別・群別に出し、欠損が目的変数や重要属性と関係していないかを必ず見る。
分布確認では、平均と標準偏差だけでは不十分である。歪んだ分布、ゼロ過剰、天井効果、床効果、二峰性、長い裾を見逃すと、後続の分析手法の前提が崩れる。人口、売上、アクセス数、所得、医療費のような量は右裾が長くなりやすいので、対数変換前後のヒストグラムを比較する。割合データは 0 から 1 の範囲に閉じ込められ、境界付近で分散が小さくなる。時系列データは季節性とトレンドを分けて見ないと、単なる月次変動を政策効果と誤読する。
外れ値は削除候補ではなく、まず説明候補である。東京都の人口、年末商戦の売上、災害月の避難者数、キャンペーン日のアクセス数などは、統計的には外れ値でも、分析上は最も重要な観測であることが多い。一方、負の年齢、未来の日付、都道府県コードの桁落ち、単位が円と千円で混在している値は、データ品質上の外れ値である。EDA では「現象としての外れ値」と「誤りとしての外れ値」を分け、削除、補正、別モデル化、ロバスト統計の利用を選択する。
| 確認項目 | 見る指標 | 危険な兆候 | 推奨アクション |
|---|---|---|---|
| 観測単位 | 行数、主キー、重複数 | 同じ ID が複数意味で使われる | 粒度を文書化し、集計単位を固定する |
| 欠損 | 列別・群別欠損率 | 特定群だけ欠損が高い | 欠損理由を分類し、補完前に感度分析する |
| 分布 | 中央値、IQR、歪度、ヒストグラム | 長い裾、ゼロ過剰、二峰性 | 変換、層別、ロバスト指標を併用する |
| 外れ値 | IQR ルール、Z スコア、箱ひげ図 | 単位混在、入力桁違い、特殊イベント | 誤値と重要事象を分けて処理する |
| 関係性 | 散布図、相関、層別平均 | 全体と群内で傾向が違う | 層別図と交互作用を確認する |
EDA の良し悪しは、作った図の数ではなく、仮説が更新された回数で決まる。最初に「人口が多い地域ほど就業者数が多いはず」と考えたなら、散布図で概ね線形か、対数で見た方がよいか、都市圏と地方圏で傾きが違うかを確認する。想定と違う点があれば、測定誤差、制度差、産業構造、年齢構成、地理条件、サンプル選択のどれで説明できるかを考える。EDA は仮説を守る工程ではなく、仮説を壊してより強い説明へ進む工程である。
相関を見るときは、全体相関、層別相関、順位相関を並べると解像度が上がる。外れ値 1 点で Pearson 相関が大きく動くことは珍しくない。順位相関なら単調関係を捉えやすいが、非線形の形までは分からない。散布図に回帰直線だけを引くと、曲線関係や分散の増大を隠すことがあるため、LOWESS のような平滑線や密度表示を併用する。特に教育データ、医療データ、地域統計では、群ごとの構造差が大きいため、色分けや facet による分割表示が有効である。
時系列を含む EDA では、横断面データと同じ手順だけでは足りない。欠測が連続していないか、集計締め日の変更がないか、制度改定や分類変更で系列が切れていないかを確認する。月次データなら前年同月比、移動平均、季節調整前後を比較する。日次データなら曜日効果、祝日、月末月初、システム障害日の影響を見る。時点のずれを放置すると、説明変数が未来情報を含むリークになり、検証時だけ高精度に見える危険がある。
カテゴリ変数では、件数の少ない水準と表記ゆれが重要である。「東京都」「東京」「Tokyo」「13」のように同じ意味が複数表記されると、集計もモデルも分裂する。逆に「その他」に多様な水準を押し込めると、重要な少数群が見えなくなる。EDA ではカテゴリ別件数、上位水準、下位水準、未知カテゴリの扱いを確認する。モデル投入前には、訓練データに存在しないカテゴリが本番で出た場合のエンコード方針も決めておく必要がある。
数値の単位とスケールも監査対象である。円、千円、百万円が混ざる、人口が人と千人で混ざる、割合が 0.32 と 32 の両方で入る、面積が平方キロメートルと平方メートルで混ざる、といった問題は見た目には気づきにくい。EDA では最小値、最大値、分位点、代表的な実在値との照合で異常を検出する。単位のメタデータを列名だけに頼らず、データ辞書や出典表と突き合わせることで、後続の分析事故を大きく減らせる。
モデル開発に渡す前の EDA では、目的変数との関係だけでなく、説明変数同士の重複も見る。人口、世帯数、就業者数、課税所得総額のように、規模を表す変数は互いに強く相関しやすい。これを知らずに線形回帰へ入れると、多重共線性で係数解釈が不安定になる。予測目的なら許容できる場合もあるが、説明目的なら VIF、相関行列、主成分、標準化後の係数比較を検討する。EDA は、どのモデルを選ぶべきかだけでなく、どの解釈を避けるべきかも教えてくれる。
可視化の設計では、見やすさよりも誤読しにくさを優先する。棒グラフのゼロ起点、折れ線グラフの時系列順、地図の階級区分、ヒートマップの色覚多様性、散布図の点の重なり、箱ひげ図のサンプル数表示は、すべて解釈に直結する。EDA の図は途中成果物であっても、意思決定者に共有される可能性がある。軸ラベル、単位、期間、サンプル数、除外条件を図中または直下に残し、後から見ても同じ解釈に戻れるようにする。
再現性も EDA の品質である。ノートブック上で試行錯誤した結果だけが残り、どの前処理でどの図を作ったか分からない状態は危険である。読み込み、型変換、欠損処理、集計、描画、保存をコードとして残し、乱数シード、ライブラリバージョン、入力ファイル名、実行日時を記録する。特に教材や共同研究では、別の人が同じ図を再生成できることが重要である。再現できない EDA は、説得力のある発見ではなく、たまたま残った画面でしかない。
最後に、EDA の結論は「分かったこと」「分からないこと」「次に確認すること」に分けて書く。分かったことは、分布、外れ値、主要な関係、データ品質の状態である。分からないことは、因果、未観測交絡、測定誤差の程度、制度変更の影響などである。次に確認することは、追加データ、層別分析、ロバスト性確認、モデル比較、専門家レビューである。この 3 区分でまとめると、EDA が単なる観察メモではなく、分析プロジェクト全体の意思決定ログになる。
教育場面では、EDA を「正解を探す前の準備」として教えるより、「データに質問する技法」として教える方が定着しやすい。最初に 5 数要約を出し、次にヒストグラムを描き、外れ値を見つけ、散布図で関係を見て、必要なら層別し、最後に言葉で仮説を書き直す。この循環を短いデータセットで何度も回すと、学生はモデル以前にデータを疑う姿勢を身につける。EDA の最終目標は美しい図ではなく、次の分析で失敗しないための判断材料をそろえることである。
先ほどの数式・定義に出てきた記号や概念を、 一つずつ確認します。 とくに 探索的データ分析 の文脈で意味を取り違えやすい部分を強調します。
| 記号 | 意味と注意点 |
|---|---|
| $\bar{x}$ | 標本平均。 $\bar{x} = \frac{1}{n}\sum_{i=1}^n x_i$ |
| $\sigma$(または $s$) | 標準偏差(または標本標準偏差)。 ばらつきの代表指標 |
| $n$ | 標本サイズ(観測数) |
| $p$ | p値、 または比率。 文脈で意味が変わる |
| $\alpha$ | 有意水準(通常 0.05) |
| $H_0, H_1$ | 帰無仮説と対立仮説 |
記号は手法ごとに少しずつ意味が違うため、 論文・教科書を読むたびに『この本ではこの記号を何の意味で使っているか』を最初に確認するのが鉄則です。 とくに 探索的データ分析 関連の文献では、 ${\sigma}^2$(分散)と $s^2$(標本分散)の区別、 $n$ と $N$(標本サイズ vs 母集団サイズ)の混同に注意。
SSDSE-B-2026(47都道府県・2023 年・112 列)を題材に、 探索的データ分析 に関係する変数を実値で確認します。 とくに東京・大阪・沖縄・秋田 など特徴ある県を比較すると、 用語の重みが体感できます。
| 都道府県 | 総人口(千人) | 高齢化率(%) | TFR | 年平均気温(℃) |
|---|---|---|---|---|
| 東京 | 14,086 | 22.8 | 0.99 | 17.6 |
| 大阪 | 8,763 | 27.7 | 1.19 | 18.0 |
| 沖縄 | 1,468 | 23.8 | 1.60 | 23.8 |
| 秋田 | 914 | 39.1 | 1.10 | 13.7 |
| 47都道府県 中央値 | 1,549 | 31.8 | 1.30 | 17.4 |
これらの値を 探索的データ分析 の観点で読み解くと、 都道府県間の格差・特徴・関係性が浮かび上がります。 具体的な計算手順は次の「🐍 Python 実装」セクションで実演します。
EDA の最初の一歩「5 数要約 (min, Q1, median, Q3, max)」を、 SSDSE-B-2026 の A4103 (合計特殊出生率) の 47 都道府県全データで実行する。 EDA で「分布の中心と幅を一目で掴む」典型操作。
| Code | Prefecture | A4103 |
|---|---|---|
| R01000 | 北海道 | 1.06 |
| R13000 | 東京都 | 0.99 |
| R27000 | 大阪府 | 1.19 |
| R47000 | 沖縄県 | 1.60 |
| R05000 | 秋田県 | 1.10 |
| ... | (全 47 件) | ... |
47 県の値をソート (昇順) すると以下のような分布:
東京 (0.99) と沖縄 (1.60) で 0.61 差 — TFR で 1 県の差が 0.6 もあるのは非常に大きい。 EDA は「この差をどう読むか」の起点となる。
このコードでやること: SSDSE-B-2026 を読み込み、 A4103 列の 5 数要約 (min/Q1/median/Q3/max + IQR) を計算する。
📥 入力データ (SSDSE-B-2026.csv 関連列):
1 2 3 4 5 6 7 8 9 | import pandas as pd import numpy as np # SSDSE-B-2026 を読み込み、2023 年の合計特殊出生率 A4103 を抽出 df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) x = df[df['SSDSE-B-2026'] == 2023]['A4103'].values q = np.percentile(x, [0, 25, 50, 75, 100]) print(f"min={q[0]:.2f}, Q1={q[1]:.2f}, median={q[2]:.2f}, Q3={q[3]:.2f}, max={q[4]:.2f}") print(f"IQR={q[3]-q[1]:.2f}, 範囲={q[4]-q[0]:.2f}") |
💬 手計算 (Step 2) min 0.99 / median 1.30 / max 1.60 と Python 出力が一致。 IQR 0.17 に対し range 0.61 — 沖縄 (1.60) が右側の外れ値である可能性を箱ひげ図でさらに検証するのが EDA の次ステップ。
以下は 探索的データ分析 を SSDSE-B-2026 で扱うときの典型コード。 encoding='cp932' は政府統計の Shift-JIS 対応。 skiprows=[1](リスト指定)で 2 行目の日本語見出し行だけをスキップし、 1 行目の列コード(A1101 等)をヘッダに採用するのが定石。 skiprows=1(整数)だと逆に 1 行目のコード行が消えてしまう点に注意。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import pandas as pd # 探索的データ分析 に関連する SSDSE-B-2026 分析の基本パターン df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) # 見出しの下に地域コード以外の行が混ざるので、47 都道府県だけ残して数値に直す df = df[df['地域コード'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() for _c in df.columns[3:]: df[_c] = pd.to_numeric(df[_c], errors='coerce') print(df.shape) # (564, 112) print(df.dtypes.head(10)) print(df.describe().T.head(10)) # 主要列にエイリアス df['総人口'] = df['総人口'] df['65歳以上'] = df['65歳以上人口'] df['高齢化率'] = df['65歳以上'] / df['総人口'] * 100 print(df[['都道府県','総人口','高齢化率']].head()) |
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 | import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 探索的データ分析 の探索的データ分析(EDA) df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) # 見出しの下に地域コード以外の行が混ざるので、47 都道府県だけ残して数値に直す df = df[df['地域コード'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() for _c in df.columns[3:]: df[_c] = pd.to_numeric(df[_c], errors='coerce') # 主要変数を取り出して名前を分かりやすく df['総人口'] = df['総人口'] df['65歳以上'] = df['65歳以上人口'] df['高齢化率'] = df['65歳以上'] / df['総人口'] * 100 df['TFR'] = df.iloc[:, 21] # ヒストグラム fig, axes = plt.subplots(1, 2, figsize=(12, 4)) sns.histplot(df['高齢化率'], kde=True, ax=axes[0]) axes[0].set_title('高齢化率の分布(47都道府県)') sns.histplot(df['TFR'], kde=True, ax=axes[1]) axes[1].set_title('TFRの分布') plt.tight_layout() plt.savefig('eda_distribution.png', dpi=120) |
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 | import pandas as pd import numpy as np # 探索的データ分析 に関わる前処理の典型パターン df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) # 見出しの下に地域コード以外の行が混ざるので、47 都道府県だけ残して数値に直す df = df[df['地域コード'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() for _c in df.columns[3:]: df[_c] = pd.to_numeric(df[_c], errors='coerce') # ① 欠損値の確認 print('欠損数:') print(df.isna().sum().sort_values(ascending=False).head(10)) # ② 数値変換(カンマ・%除去 など) def to_num(s): if isinstance(s, str): return float(s.replace(',', '').replace('%', '')) return s _num_cols = [c for c in df.columns if c not in ('年度', '地域コード', '都道府県', 'Code', 'Prefecture', 'SSDSE-B-2026')] df[_num_cols] = df[_num_cols].apply(lambda col: col.map(to_num)) # ③ 外れ値検出(IQR) # 地域コードや都道府県名は大小比較できないので、数値の列だけで判定する _num = df.select_dtypes(include='number') q1 = _num.quantile(0.25) q3 = _num.quantile(0.75) iqr = q3 - q1 outlier_mask = ((_num < q1 - 1.5*iqr) | (_num > q3 + 1.5*iqr)).any(axis=1) print('外れ値を含む行数:', outlier_mask.sum()) |
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 from scipy import stats # 探索的データ分析 文脈での基本的な仮説検定 df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) # 見出しの下に地域コード以外の行が混ざるので、47 都道府県だけ残して数値に直す df = df[df['地域コード'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() for _c in df.columns[3:]: df[_c] = pd.to_numeric(df[_c], errors='coerce') df['aging'] = df['65歳以上人口'] / df['総人口'] * 100 df['region'] = df['都道府県'].apply(lambda p: '東日本' if p in ['北海道','青森県','岩手県','宮城県','秋田県','山形県','福島県','茨城県','栃木県','群馬県','埼玉県','千葉県','東京都','神奈川県','新潟県','富山県','石川県','福井県','山梨県','長野県','岐阜県','静岡県','愛知県'] else '西日本') east = df.loc[df['region']=='東日本', 'aging'] west = df.loc[df['region']=='西日本', 'aging'] t, p = stats.ttest_ind(east, west, equal_var=False) print(f'東日本 平均高齢化率: {east.mean():.2f}%') print(f'西日本 平均高齢化率: {west.mean():.2f}%') print(f't = {t:.3f}, p = {p:.4f}') print('判定:', '有意差あり' if p < 0.05 else '有意差なし') |
※ より高度な例(クロス集計、 機械学習、 ベイズ推定)は data-process のグループ教材を参照。
SSDSE-B-2026 のような公的統計データを Python で扱う際の基本パターン:
1 2 3 4 5 6 7 8 9 10 11 12 | import pandas as pd import numpy as np # データ読み込み df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) print(df.shape) print(df.dtypes) print(df.describe()) # 「探索的データ分析」の文脈で扱う場合の例: # 分野: リテラシー # 関連手法は同カテゴリの他用語を参照してください。 |
具体的なコードは データリテラシー を参照してください。
分析結果を報告するときに含めるべき情報:
🎯 このコードでやること: SSDSE-B-2026 を読み込み、 形状・データ型・欠損数・基本統計量を 1 画面で把握する。 EDA の第 1 ステップ。
📥 入力データ: data/raw/SSDSE-B-2026.csv(cp932 エンコード、 2 行目はヘッダ和訳)
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]) print('shape:', df.shape) print('dtypes summary:') print(df.dtypes.value_counts()) print('missing:') print(df.isnull().sum().sum(), 'cells') print() print(df[['SSDSE-B-2026', 'Prefecture', 'A1101', 'A1303']].describe()) |
📤 実行結果:
💬 結果の読み方: 564 行 = 47 都道府県 × 12 年 (2012-2023)。 欠損 0 個は SSDSE シリーズの大きな特徴。 人口の最大値 14,086,000 は東京都 2023 年で、 最小 537,000 は鳥取県 2023 年。
🎯 このコードでやること: 2023 年の都道府県人口について、 ヒストグラム + 箱ひげ図 + KDE で分布形を多角的に確認する。
📥 入力データ: df2023 = df[df['SSDSE-B-2026']==2023](47 行 × 112 列)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import matplotlib.pyplot as plt import seaborn as sns df2023 = df[df['SSDSE-B-2026']==2023] pop = df2023['A1101'] / 10000 # 万人単位 fig, axes = plt.subplots(1, 3, figsize=(15, 4)) axes[0].hist(pop, bins=15, color='steelblue', edgecolor='black') axes[0].set_title('Histogram (population, 10k)') axes[0].set_xlabel('Population (10k people)') axes[1].boxplot(pop, vert=True) axes[1].set_title('Box plot') axes[1].set_ylabel('Population (10k)') sns.kdeplot(pop, ax=axes[2], color='darkred', fill=True) axes[2].set_title('KDE (density)') axes[2].set_xlabel('Population (10k)') plt.tight_layout() plt.savefig('eda_population_dist.png', dpi=100) print(f'mean={pop.mean():.1f} median={pop.median():.1f} std={pop.std():.1f}') print(f'skewness={pop.skew():.3f} kurtosis={pop.kurt():.3f}') |
📤 実行結果:
💬 結果の読み方: 歪度 2.29 (> 1) で「強い右歪み」と判定。 平均 264.6 万 ≫ 中央値 154.9 万も右歪みの傍証。 EDA の段階で 「正規分布前提の検定は使えない」「対数変換が必要」と判断できる。
🎯 このコードでやること: 人口、 65歳以上人口、 出生数、 死亡数の 4 変量について、 散布図行列で全ペアの関係を一目で確認する。
📥 入力データ: 2023 年データ 47 行 × 4 列 (A1101, A1303, A4101, A4200)
1 2 3 4 5 6 7 8 9 10 11 | cols = ['A1101', 'A1303', 'A4101', 'A4200'] labels = ['Population', 'Age65+', 'Births', 'Deaths'] sub = df2023[cols].copy() sub.columns = labels g = sns.pairplot(sub, diag_kind='hist', plot_kws={'s': 22, 'alpha': 0.7}) g.fig.suptitle('SSDSE-B 2023: Population-related variables', y=1.02) plt.savefig('eda_pairplot.png', dpi=100, bbox_inches='tight') print('Correlation matrix:') print(sub.corr().round(3)) |
📤 実行結果:
💬 結果の読み方: 全変量間で r > 0.97 — 「人口規模に支配された冗長な変量群」と分かる。 EDA の段階で 「人口で正規化した比率(出生率・死亡率・高齢化率)に変換すべき」と判断できる。 これが EDA の真骨頂 — モデリング前に変数選択の方向を決める。
🎯 このコードでやること: 2023 年人口で IQR 法による外れ値を抽出し、 都道府県名と人口を一覧表示する。
📥 入力データ: df2023 の Prefecture 列と A1101 列
1 2 3 4 5 6 7 8 9 10 11 12 | pop = df2023['A1101'] Q1 = pop.quantile(0.25) Q3 = pop.quantile(0.75) IQR = Q3 - Q1 upper = Q3 + 1.5 * IQR lower = Q1 - 1.5 * IQR outliers = df2023[(pop > upper) | (pop < lower)] print(f'Q1={Q1:,.0f} Q3={Q3:,.0f} IQR={IQR:,.0f}') print(f'Upper fence = {upper:,.0f} (Lower fence = {lower:,.0f})') print(f'Outliers: {len(outliers)} prefectures') print(outliers[['Prefecture', 'A1101']].to_string(index=False)) |
📤 実行結果:
💬 結果の読み方: 外れ値 9 都道府県は「3 大都市圏 + 北海道 + 福岡」とほぼ一致。 EDA の段階で 「これは異常値ではなく説明対象」と判断し、 「人口集中の地理的構造」というモデリング仮説を導ける。
🎯 このコードでやること: 2023 年人口の生データと対数変換後の両方で Shapiro-Wilk 正規性検定を行い、 「対数変換が必要か」を客観的に判定する。
📥 入力データ: pop = df2023['A1101'](47 件、 単位: 人)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import numpy as np from scipy import stats # 生データ w1, p1 = stats.shapiro(pop) # 対数変換後 w2, p2 = stats.shapiro(np.log10(pop)) print(f'Raw scale: W={w1:.4f} p={p1:.4g}') print(f'Log scale: W={w2:.4f} p={p2:.4g}') print() print('Interpretation:') print(' p < 0.05 → reject normality') print(f' → Raw: {"normal" if p1 >= 0.05 else "NOT normal"}') print(f' → Log: {"normal" if p2 >= 0.05 else "NOT normal (but improved)"}') |
📤 実行結果:
💬 結果の読み方: 生データの W=0.69 → 対数変換で W=0.93 へと改善。 ただし対数変換後も p < 0.05 で完全な正規分布ではない。 EDA の段階で 「正規性前提の手法(t 検定・線形回帰の係数 CI)は対数スケールで使用するか、 ノンパラメトリック法を選ぶ」と判断できる。
SSDSE-B-2026 の 2023 年データで、 高齢化率 (= A1303 / A1101 × 100) を 47 都道府県で計算すると次のような構造が見えてきます。
| 統計量 | 値 | 解釈 |
|---|---|---|
| 平均 | 31.59% | 国全体で 3 割超が高齢者 |
| 最大値 | 39.06% (秋田県) | 「超高齢化」の先端 |
| 最小値 | 22.75% (東京都) | 若年層流入で抑制 |
| 最大-最小差 | 16.31 ポイント | 「国内で 1 つの国とは思えない格差」 |
EDA でこの構造が見えれば、 次の検証ステップ(地域別重回帰、 縦断分析、 政策効果の差分検定)への扉が開きます。 これが「EDA は仮説生成」の意味です。
実務 EDA の最大の時短ツールは 自動 EDA レポート。 ypandas-profiling (現 ydata-profiling)、 sweetviz、 dtale、 missingno など、 1 行で 100 列のヒストグラム・相関・欠損可視化が出る。 ここでは SSDSE-B-2026 (47 都道府県 × 約 120 カラム) に対する標準テンプレを示す。
🎯 このコードでやること:SSDSE-B-2026 を読み込み、 ydata-profiling で全列の自動レポート、 missingno で欠損パターン、 seaborn pairplot で 5 列の関係を 1 ファイルで吐き出す EDA テンプレ。
📥 入力データ (SSDSE-B-2026 ヘッダ抜粋):
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 35 | import pandas as pd import seaborn as sns import matplotlib.pyplot as plt import missingno as msno # SSDSE-B-2026 は 2 行ヘッダ: header=1 で列名(和訳)行をスキップし列コードを採用 df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年の 47 都道府県だけ抽出 print(f"形状: {df.shape}") # (47, 112) print(f"先頭 3 行 × 6 列:\n{df.iloc[:3, :6]}") print(f"\n数値列の dtype 件数:\n{df.dtypes.value_counts()}") print(f"\n欠損数 合計: {df.isna().sum().sum()}") # SSDSE-B は完全データ # 1. 自動 EDA レポート (HTML) # from ydata_profiling import ProfileReport # ProfileReport(df, title="SSDSE-B-2026 EDA").to_file("eda_report.html") # 2. 欠損パターン可視化 (matrix プロット) fig, ax = plt.subplots(figsize=(14, 5)) msno.matrix(df.iloc[:, :30], ax=ax, sparkline=False) plt.tight_layout() plt.savefig("eda_missing.png", dpi=110) # 3. 主要 4 列の pairplot (総人口・高齢者数・出生数・消費支出) focus = ['A1101', 'A1303', 'A4101', 'L3221'] focus_df = df[focus].apply(pd.to_numeric, errors='coerce') sns.pairplot(focus_df, diag_kind='kde', plot_kws={'alpha': 0.6}) plt.savefig("eda_pairplot.png", dpi=110) # 4. 数値要約 (describe + 歪度 + 尖度) summary = focus_df.describe(percentiles=[0.25, 0.5, 0.75]).T summary['skew'] = focus_df.skew() summary['kurt'] = focus_df.kurt() summary['cv'] = summary['std'] / summary['mean'] # 変動係数 print(f"\n要約統計 (歪度・尖度・CV):\n{summary[['mean','std','skew','kurt','cv']].round(2)}") |
📤 実行例:
💬 結果の読み方:47 県の総人口・65歳以上人口・出生数はいずれも 右歪み (skew > 1.8) + 東京が裾の外れ値。 これは log 変換が有効 という EDA 結論を意味する (相関を取る前に対数化を検討)。 一方 消費支出(二人以上の世帯, L3221)は skew=-0.54 とほぼ対称で県差も小さい (CV=0.08)。 自動レポートを見るのは 「考える」EDA の前の 5 分 と割り切る (思考停止しないこと)。
探索的データ分析 に取り組むときに、 学生・実務者・研究者がよく踏むワナをまとめました。 該当しそうな項目があれば、 自分の分析を見直してみてください。
dropna() で除いた瞬間、 47県の標本が 30 県に減ることもある。 何件落としたか必ず記録し、 結果に与える影響を考える。探索的データ分析(Exploratory Data Analysis (EDA))は、 プロセス 分野における基本概念の 1 つとして発展してきました。 学術領域では 20 世紀後半に体系化が進み、 21 世紀のデータ駆動社会の中で「実務で使う知識」として急速に普及。 とくに 2010 年代後半以降、 ビッグデータ・IoT・AI の進展に伴い、 用語の意味・適用範囲が再定義されつつあります。
日本では総務省・経産省・内閣府の各種計画(Society 5.0、 デジタル田園都市国家構想、 統計改革基本計画)で繰り返し言及される基幹概念。 SSDSE(教育用標準データセット)も、 これらの教育普及を目的に整備されたデータです。
OECD、 国連、 ISO、 IEC などの国際機関が、 探索的データ分析 に類する概念・標準を整備してきました。 たとえば:
探索的データ分析 を含むデータ分析の手法は、 日本では次の場面で使われています。 下の表は分野ごとの登場場面で、 この用語だけの話ではなくデータサイエンス全体の広がりを示します:
| 領域 | データサイエンスが使われる場面 |
|---|---|
| 高校・大学教育 | 情報 I/II、 数学 B(統計)、 教養統計、 専門統計の中核概念として登場 |
| 行政・政策 | EBPM、 デジタル庁施策、 自治体 DX、 地方創生交付金の根拠資料 |
| 企業・産業 | DX 推進、 データ分析人材育成、 経営判断、 マーケティング・品質管理 |
| 学術研究 | 公衆衛生、 教育学、 経済学、 社会学、 計算機科学などの分野横断研究 |
| 市民・メディア | 報道、 ファクトチェック、 行政情報の解釈、 民主主義の基盤 |
探索的データ分析 は、 隣接概念と混同されやすい用語の代表でもあります。 ここで違いを明確にしておきましょう:
| 混同される概念 | 探索的データ分析 との違い |
|---|---|
| 隣接する プロセス 系の用語 | 本ページの「🔗 関連用語」を参照。 並列カテゴリで対比すると明瞭 |
| より広い上位概念 | data-process ページで包含関係を確認 |
| 類似名・別名 | 英語名 (Exploratory Data Analysis (EDA)) を正式表記として参照 |
本サイト(用語解説)は「ジャストインタイム型データサイエンス教育」のリソースです。 つまり、 論文・実務・授業で その用語に出会ったタイミングで必要最低限の説明を得る、 という使い方を想定しています。 探索的データ分析 もその一例。
体系的に学びたい場合は、 まずグループ教材(data-process)から始め、 そこから 探索的データ分析 のような個別用語にドリルダウンしていくのが効率的です。
EDA は手作業の pandas + matplotlib が王道ですが、 場面に応じて以下のツール群を使い分けるとスループットが上がります。
| ツール | 用途 | 利点 | 注意点 |
|---|---|---|---|
| pandas + matplotlib | 手動 EDA の基盤 | 柔軟性最高、 細部まで制御可能 | コード量が増える |
| seaborn | 統計可視化 | pairplot, kdeplot, heatmap が短行で書ける | 大量データで描画遅い |
| pandas-profiling (ydata-profiling) | 自動レポート | 1 行で全体像 HTML を生成 | 100 列超で重い、 解釈は人手 |
| sweetviz | 2 群比較 EDA | A/B 比較、 train/test 比較に強い | 回帰問題には弱い |
| plotly / bokeh | インタラクティブ可視化 | ズーム・ツールチップで深掘り | 学習コスト中 |
| D-Tale | Excel 風 EDA | GUI で並べ替え・フィルタ・ヒストグラム | バッチ処理に不向き |
💡 実務の現場での推奨組み合わせ: pandas-profiling で全体スキャン → seaborn で深掘り → plotly で報告書用インタラクティブ図。
SSDSE-B-2026 は 2012-2023 年の 12 年間のデータを含むため、 都道府県別の時系列推移も EDA の対象になります。
🎯 このコードでやること: 全国合計人口と東京都人口の 12 年推移を折れ線で並べ、 集中度の変化を可視化する。
📥 入力データ: df 全行 (564 行)、 年 (SSDSE-B-2026 列) ごとに groupby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import matplotlib.pyplot as plt # 全国合計と東京都を年別に集計 nat = df.groupby('SSDSE-B-2026')['A1101'].sum() / 10000 # 万人 tky = df[df['Prefecture']=='東京都'].set_index('SSDSE-B-2026')['A1101'] / 10000 share = (tky / nat * 100).round(2) fig, ax = plt.subplots(1, 2, figsize=(14, 4.5)) ax[0].plot(nat.index, nat.values, marker='o', label='Japan total', color='steelblue') ax[0].plot(tky.index, tky.values, marker='s', label='Tokyo', color='crimson') ax[0].set_xlabel('Year'); ax[0].set_ylabel('Population (10k)') ax[0].legend(); ax[0].set_title('Population trajectory (2012-2023)') ax[1].plot(share.index, share.values, marker='D', color='darkorange') ax[1].set_xlabel('Year'); ax[1].set_ylabel('Tokyo share (%)') ax[1].set_title('Tokyo population share of Japan') plt.tight_layout() plt.savefig('eda_timeseries.png', dpi=100) print('Tokyo share (%):') print(share.to_string()) |
📤 実行結果:
💬 結果の読み方: 12 年間で東京都のシェアは +0.96 ポイント。 単純な比較では小さく見えるが、 47 都道府県の中で 1 県だけがこの分シェアを増やすには、 他 46 県から人口を引き寄せた必要がある。 これが「東京一極集中」の EDA 的根拠。
🎯 このコードでやること: SSDSE-B-2026 の人口関連 8 変量について、 全ペアの相関係数をヒートマップで一望する。 強い相関のペアと無相関のペアを瞬時に識別。
📥 入力データ: 2023 年データ 47 行 × 8 列 (人口、 年齢層別人口、 出生数、 死亡数、 転入数、 転出数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import seaborn as sns cols = ['A1101', 'A1301', 'A1302', 'A1303', 'A4101', 'A4200', 'A5101', 'A5102'] labels = ['Pop', 'Age0-14', 'Age15-64', 'Age65+', 'Births', 'Deaths', 'InMig', 'OutMig'] sub = df2023[cols].copy() sub.columns = labels corr = sub.corr() plt.figure(figsize=(8, 6.5)) sns.heatmap(corr, annot=True, fmt='.2f', cmap='RdBu_r', center=0, square=True, linewidths=0.5, cbar_kws={'shrink': 0.7}) plt.title('Correlation heatmap: Population-related vars (SSDSE-B 2023)') plt.tight_layout() plt.savefig('eda_heatmap.png', dpi=100) print(corr.round(2)) |
📤 実行結果:
💬 結果の読み方: 全変量が r ≈ 0.9〜1.0 — 「ほぼすべて人口規模に比例」という強烈な結論(人口移動 InMig/OutMig はやや低く r≈0.92〜0.98)。 EDA で「絶対数」のままでは何も区別できないことが分かる。 「比率に変換すれば隠れた構造が見える」という方針が確立する。
EDA の重要性を最も鮮烈に示すのは、 1973 年に統計学者 Frank Anscombe が提示した アンスコム四重奏 (Anscombe's Quartet) です。
4 つの異なるデータセットが、 平均・分散・相関係数・回帰直線という主要な統計量で すべて同一の値を示すにもかかわらず、 散布図を描くと 全く異なる構造を持っていることが視覚的に明らかになります。
| 指標 | データ I | データ II | データ III | データ IV |
|---|---|---|---|---|
| x の平均 | 9.0 | 9.0 | 9.0 | 9.0 |
| y の平均 | 7.50 | 7.50 | 7.50 | 7.50 |
| x の分散 | 11.0 | 11.0 | 11.0 | 11.0 |
| y の分散 | 4.125 | 4.125 | 4.125 | 4.125 |
| x と y の相関 | 0.816 | 0.816 | 0.816 | 0.816 |
| 回帰直線 | y=3+0.5x | y=3+0.5x | y=3+0.5x | y=3+0.5x |
| 散布図形状 | 線形でランダム誤差 | 明らかな曲線(2 次関数) | 完全線形 + 1 外れ値 | x が定数 + 1 外れ値 |
⚠️ 数値だけで判断していたら、 4 つのデータセットを「同じ」と見誤る。 これが「EDA を可視化中心で行うべき理由」の数学的根拠。 SSDSE-B-2026 でも、 人口と 65 歳以上人口の相関係数 r=0.99 だけ見て満足するのではなく、 散布図で東京都が右上に大きく離れて位置する(人口・高齢者数ともに突出)ことを確認するのが正しい EDA。
2017 年には Justin Matejka と George Fitzmaurice が「Datasaurus Dozen」を発表し、 「恐竜の絵を含む 13 個のデータセットが、 平均・分散・相関係数まですべて一致する」ことを示しました。 この衝撃的な事例も、 EDA の可視化重視の重要性を裏付けています。
分析を提出する前に、 以下の 15 項目を 1 つずつ確認してください。
df.shape, df.dtypes, df.isnull().sum() を確認したEDA (探索的データ分析) は記述統計 ・可視化 ・相関分析を行き来する反復作業で、 上流の生データ取り込みと、 下流のモデリング ・仮説検証を繋ぐ。 周辺には Tukey の五数要約 ・boxplot ・散布図行列 ・主成分分析が「可視化の語彙」として並ぶ。
EDA(探索的データ解析)は、 仮説検定やモデリングに進む前に「データに何が含まれているか」を可視化・要約統計・外れ値検出で把握する段階であり、 J.W.Tukey が 1977 年に体系化した。 SSDSE-B-2026 のような新しいデータに対しては、 まず分布・欠損・相関を一通り確認することで、 後段のモデル選択や因果推論の落とし穴を未然に防げる。
EDA (探索的データ分析) は単独の作業ではなく、 データ取得後の最初の問いかけと、 仮説検証・モデリング前の最終確認を兼ねる反復プロセスである。 記述統計 ・可視化 ・相関分析を行き来して洞察を引き出す。
EDA は「データの素性を理解するための探索」で、 上流の生データ取り込み直後に行い、 並列の記述統計・可視化・相関分析を組み合わせ、 下流のモデリング・特徴量設計・仮説検証を方向づける羅針盤として機能する。
EDA をどこまで深掘りするかは「データ規模・分析目的の明確さ・締切」の 3 軸で決まる。 探索的な仮説生成が目的なら時間をかけ、 既知の検証だけなら describe + boxplot で打ち切る判断が必要。
describe() と箱ひげ図で打ち切り、 検証に進む。SSDSE-B-2026 を例にすると、 まず head/describe で全体感、 次に都道府県別 boxplot で外れ値、 最後に散布図行列で多変量関係を順に確認するのが、 47 行データで現実的な EDA の進め方である。
SSDSE-B-2026 の実測値(2023 年・47 都道府県 × 4 変数 = 総人口 A1101・合計特殊出生率 A4103・住宅地平均価格 C5401・延べ宿泊者数 G7101)を使って、EDA の基本動作「① まず見る → ② 分布を見る → ③ 関係を見る → ④ 外れ値に気づく」を体験できます。ステップボタンと変数セレクタを切り替えるたびに、図と統計量がその場で再計算されます。同じデータでも「見方」を変えると違う発見がある——これが EDA の核心です。
図の上をマウスまたは指でなぞると、県名と実測値が表示されます(タッチ対応)
上のツアーが示すように、EDA は特定の 1 枚の図のことではなく、「要約統計 → 分布 → 関係 → 外れ値」と視点を切り替えながらデータに問いかける反復プロセスです。総人口は「平均 264.6 万人」と一言で要約すると普通に見えますが、ヒストグラムを描けば右に強く歪み(歪度 2.22)、箱ひげ図を描けば 9 都道府県が Tukey フェンスの外に出る——数値だけでは見えなかった構造が、見方を変えるたびに一つずつ現れます。モデリングを急ぐ前にこの対話に時間を使うほど、後段の手法選択(対数変換の要否・頑健な統計量の採用・層別の必要性)が的確になります。
仮説生成と検証は分けるのが現代の作法。EDA(探索)で見つけたパターンは「仮説」であって「結論」ではなく、同じデータで有意性検定まで済ませると多重比較の罠に落ちる。理想は、EDA で仮説を立て、仮説検定は新しいデータ(または最初に取り分けた検証用データ)で行う二段構え。Tukey 自身も探索的(exploratory)と確認的(confirmatory)の分析を明確に区別した。また近年は ydata-profiling(旧 pandas-profiling)や sweetviz のような自動 EDA ツールが、欠損・分布・相関のレポートを一括生成してくれる。ただし自動レポートは「①要約統計」を大量に並べるだけで、③④の「どのペアを深掘るか」「外れ値をどう解釈するか」という判断は依然として人間の仕事——上のツアーで体験した視点の切り替えこそが自動化できない部分である。
このページは既に散布図・箱ひげ図・相関・アンスコム四重奏まで扱っています。 ここでは重複を避け、 「平均という 1 個の数字を報告した瞬間に、 分布の 8 割が視界から消える」という一点に絞って掘り下げます。 EDA を「作業」ではなく「代表値への懐疑」として捉え直すのが本節の狙いです。
アンスコム四重奏の教訓は「要約統計が同じでも形は違う」でした。 その逆も同じくらい怖い——要約統計が 1 個だけだと、 形が違うことに永遠に気づけない。 EDA の最初の一歩は、 平均を求めることではなく「この平均は代表として信用できるか」を疑うことです。
SSDSE-B-2026 の 2023 年・47 都道府県で G7102 外国人延べ宿泊者数 を見ると、 これが極端な例として現れます(df[df['SSDSE-B-2026']==2023] で抽出した実測値):
| 指標(2023, 47 県) | 平均 | 中央値 | 平均/中央値 |
|---|---|---|---|
| G7102 外国人延べ宿泊者数(人泊) | 2,021,866 | 276,670 | 7.31 |
| A1101 総人口(人) | 2,645,809 | 1,549,000 | 1.71 |
| A4103 合計特殊出生率 | 1.293 | 1.300 | 0.994 |
外国人宿泊者数の平均は約 202 万人泊ですが、 中央値は 約 27.7 万人泊——平均は中央値の 7.3 倍です。 実際に平均を上回る県はわずか 8 県で、 47 県中 39 県が「平均以下」。 つまり「平均的な県」は現実にほぼ存在しません。 内訳は 東京都 34,378,530 / 大阪府 15,669,930 / 京都府 9,950,040 に対し、 下位は 島根県 46,930 / 福井県 55,840。 東京都の z スコアは +5.80——この 1 点が平均を丸ごと押し上げています。 一方で合計特殊出生率は平均も中央値もほぼ 1.30 で一致し、 平均が素直に代表として使えます。 同じ「47 県の平均」でも、 変数によって信頼度がまるで違う——これを見分けるのが EDA です。
最も多い実務事故は、 p ハッキングでも多重比較でもなく、 もっと素朴な 「平均だけ計算して分布を見ずに次へ進む」ことです。 上の G7102 で「日本の県は平均 200 万人泊の外国人が泊まる」と書けば、 数字は正しくても読者は完全に誤解します(現実の典型県は 30 万人泊未満)。 これは嘘ではなく、 代表値の選択ミスという EDA の失敗です。 対策は 3 つ:
さらに深い罠として、 平均以下が 39/47 という事実は「平均」の定義上ごく普通だと知っておくこと。 右歪み分布では過半数が平均を下回るのが当たり前で、 「半数が平均以下=異常」と早合点するのも別の誤読です。 平均・中央値・最頻の三者関係(右歪みなら 最頻<中央値<平均)を頭に置くのが 中心傾向の正しい使い方です。
1 変数ずつ目視するのは 5 変数までが限界です。 実務では 全列に対して「平均/中央値比」「歪度」「変動係数」を一括算出し、 代表値が怪しい変数を機械的にあぶり出すのが効率的です。 下は SSDSE-B-2026 の 2023 年断面に対する最小テンプレ(実データで動きます)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import pandas as pd, numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) d = df[df['SSDSE-B-2026'] == 2023] # 2023 年・47 都道府県 num = d.iloc[:, 3:].apply(pd.to_numeric, errors='coerce') rep = pd.DataFrame({ 'mean': num.mean(), 'median': num.median(), 'skew': num.skew(), # >1 なら強い右歪み }) rep['mean/median'] = rep['mean'] / rep['median'] # 代表値が「危ない」列 = 平均が中央値から大きく乖離 print(rep.sort_values('mean/median', ascending=False).head(5).round(2)) # → G7102(外国人延べ宿泊者数) が比 7.31 で最上位に並ぶ |
この「代表値ドック」を回すと、 レポート前に「平均で語ってよい列/中央値で語るべき列」を 109 列すべてについて数分で仕分けできます。 発展の方向は 2 つ——(1) 単変量の歪みを掴んだら 正規性検定や対数変換で後段のモデリング前提を整える、 (2) 「東京 1 点が牽引する相関」を疑い、 見かけの関係(疑似相関)や探索での偶然発見(多重検定)へ注意を広げる。 EDA は「代表値への懐疑」から始まり、 分布・関係・因果への懐疑へと連鎖していきます。
本節の角度をさらに深める内部ページ: 中心傾向(平均 vs 中央値の使い分け)、 散らばり(変動係数・IQR)、 箱ひげ図 と ヒストグラム(分布を 1 枚で診る)、 四分位数、 対数変換(右歪みの是正)、 正規性、 疑似相関、 多重検定。
※ 数値は data/raw/SSDSE-B-2026.csv を pd.read_csv(encoding='cp932', skiprows=[1]) で読み、 2023 年・47 都道府県断面から算出した実測値。 平均以下 39/47 県・東京都 z=+5.80 も同断面での実計算値です。