Social Data Science Courseware

2. 探索的データ分析 (EDA) の型

学習目標

  • EDA(Exploratory Data Analysis)の目的とステップを説明できる
  • 全体把握・分布確認・関係探索・グループ別比較の 4 ステップを実行できる
  • 集計と可視化を往復しながら仮説を立てるパターンを身につける
  • 仮説と発見をノートブックに記録して、次の分析につなげられる

本文

EDA とは何か

探索的データ分析(EDA) は、データを開いた直後にやる「予備調査」のことです。仮説を立てる前に、データに 何があり、どんな分布で、どんな関係が潜んでいるか を眺めることで、その後の分析の方向性を決めます。

EDA の目的は次の 2 つに整理できます:

  1. データを信用できる状態にする — 欠損・外れ値・表記揺れを見つけ、必要なら前処理に戻る
  2. 仮説の種を見つける — 「これは関係していそうだ」「ここに偏りがある」と気付くポイントを記録する

EDA はコードを書いて終わりではなく、「気付いたことをメモする」までがセット です。ノートブックのテキストセルに発見を書き残しておくと、後で報告や次の分析に役立ちます。

EDA の 4 ステップ

EDA は次の順序で進めるのが基本パターンです。

1. 全体把握  → 何があるか・どれだけあるか
2. 分布確認  → 各変数の散らばり方
3. 関係探索  → 変数同士のつながり
4. グループ比較  → カテゴリ別の差異

これは一度通すだけのフローではなく、気付きが出るたびに前のステップに戻ったり、次のステップに進んだりを往復する のが現実の動き方です。

ステップ 1:全体把握

データを読み込んだら、まず規模と中身の概要を確認します。

df.shape         # 行数・列数
df.columns       # 列名
df.dtypes        # 各列の型
df.info()        # 欠損数と型を一覧
df.head()        # 先頭 5 行
df.describe()    # 数値列の要約統計

ここで気付くべきこと:

  • 行数は分析に十分か(100 行と 10 万行で取れる結論は違う)
  • 数値列/カテゴリ列の内訳
  • 欠損が多い列はないか
  • 想定外の値が入っていないか(最小値が -9999、最大値が異常に大きいなど)

ステップ 2:分布確認

各変数 1 つずつの 散らばり方 を見ます。

数値変数 — ヒストグラム

import matplotlib.pyplot as plt
plt.hist(df["年齢"], bins=20)
plt.xlabel("年齢")
plt.ylabel("頻度")
plt.show()

ヒストグラムから読み取れること:

  • データが 正規分布に近いか、歪んでいるか
  • 山が複数あるか(バイモーダル → 2 つの集団が混ざっている可能性)
  • 外れ値の有無

数値変数 — 箱ひげ図

import seaborn as sns
sns.boxplot(data=df, y="収入")

中央値・四分位範囲・外れ値が一目で分かります。複数のカテゴリで分布を比べたいときに有効です。

カテゴリ変数 — value_counts() と棒グラフ

df["都市"].value_counts()
df["都市"].value_counts().plot.bar()

「どんなカテゴリが何個ずつあるか」を確認できます。表記揺れもここで気付くチャンス。

ステップ 3:関係探索

「2 つの変数がどう関連しているか」を見るステップです。

数値 × 数値 — 散布図と相関

plt.scatter(df["年齢"], df["収入"])
plt.xlabel("年齢")
plt.ylabel("収入")
plt.show()

df[["年齢", "収入"]].corr()   # 相関係数

相関係数は -11 の値で、絶対値が大きいほど線形関係が強いことを意味します。ただし 相関は因果ではない ことを忘れずに。

複数変数を一気に — ペアプロット

sns.pairplot(df[["年齢", "収入", "勤続年数"]])

すべての変数ペアの散布図と、対角線にヒストグラムが並んだ「探索の万能ツール」です。重い処理なので、列数を絞ってから呼ぶのが現実的。

ステップ 4:グループ別比較

カテゴリで分けて、数値変数の挙動の違いを見ます。

df.groupby("都市")["収入"].describe()        # 要約統計をグループ別に
sns.boxplot(data=df, x="都市", y="収入")     # 分布をグループ別に
sns.scatterplot(data=df, x="年齢", y="収入", hue="性別")  # 第 3 変数で色分け

ここで「東京と大阪で収入の分布がずいぶん違う」「男性と女性で年齢-収入の関係に差がある」のような気付きが得られれば、仮説の出発点になります。

仮説形成のループ

EDA の最終産物は 「次に検証すべき仮説」 です。たとえば次のような気付きが出てきます:

  • 「30 代後半で収入の伸びが鈍るように見える → 業種別に分けると違いが見えるか」
  • 「特定の都市だけ家族向けスポットが多い → アンケート対象の偏りか実態か」
  • 「欠損が特定のグループに集中している → サンプリングバイアスの可能性」

これらをメモに残し、必要なら追加の整形(前処理)に戻ったり、本格的な分析(次の単元以降)に進んだりします。

よく出る躓きどころ

  • describe() だけで満足する — 平均と標準偏差だけでは分布の形(歪み・複数山)は分からない。ヒストグラムを必ず見る
  • 相関を因果と取り違える — 強い相関があっても、因果関係を主張するには別の根拠が必要
  • ペアプロットを大規模データで呼んで重くなる — 列をいくつかに絞るか、ランダムサンプリングしてから
  • 「気付き」を残さない — 後で見返したときに何を発見したか分からなくなる。ノートブックの Markdown セルに必ず書く

サンプルコード

演習

income.csv を題材に、4 ステップを順に通してください。

  1. 全体把握shape / info() / describe() を呼び、欠損や型に異常がないか確認する
  2. 分布確認年齢収入 のヒストグラムを描く
  3. 関係探索年齢 × 収入 の散布図を描き、相関係数も計算する
  4. グループ比較都市 別、性別 別の収入分布を箱ひげ図で比較する

各ステップの後に、テキストセルで 気付いたこと を 1〜2 文ずつ書きなさい。気付きから生まれた「次に調べたい仮説」を最後にまとめると、本単元のゴールに到達します。

発展課題(オプション)

  • sns.pairplotincome.csv のすべての数値列を 1 つの図にまとめる
  • sns.heatmap(df.corr(), annot=True) で相関行列をヒートマップとして可視化
  • 自分でデータセットを 1 つ用意して、本単元の 4 ステップを丸ごと再現してみる