売上の平均が上がった。問い合わせの多い曜日が見えた。散布図にきれいな線が現れた。そこからすぐに施策を決める前に、誰を数え、何が記録されず、別の集計でも同じ形になるのかを確かめます。
探索的データ分析(EDA)は、データを理解し、次に確かめる問いを作るための分析です。 NISTは、グラフの集まりというより、構造・外れた観測・仮定などを調べるアプローチとして説明しています。NIST:What is EDA?
30秒で要点
- 最初に、1行が何を表すか、対象期間、単位、除外条件をそろえます。
- 分布・欠測・外れ値はセットで見ます。欠測をゼロ、極端値を誤りと決めつけません。
- 件数が多いことと割合が高いこと、相関があることと原因であることを分けます。
- 探索で見つけたパターンは候補です。比較を重ねて選んだ結果には、その選び方も関わります。
- 最後に「分かったこと・別の説明・次に確かめること」を残します。
探索と確認を分ける
EDAでは、問いを立て、集計や図を作り、その結果から問いを修正します。最初からすべての仮説が決まっている必要はありません。データを見ながら、想定しなかった入力ミスや新しい説明候補に気づくことにも価値があります。
一方、施策が指標を変えたかを確かめたいなら、比較対象、指標、対象期間、判定方法を定める確認的な分析が必要です。同じ散布図や回帰分析でも、未知の関係を探すために使う場合と、事前の問いを評価するために使う場合があります。
表が収まらない場合は、横にスクロールできます
| 観点 | 探索で行うこと | 確認へ進むときに決めること |
|---|---|---|
| 問い | 分布や関係から説明候補を作る | どの仮説を、何と比較するか |
| データ | 品質や集計条件を調べる | 対象・収集方法・評価用データの分け方 |
| 分析 | 図や条件を変え、見え方を確かめる | 主指標、分析方法、除外・停止の条件 |
| 報告 | 試した条件と候補、残る疑問を残す | 事前の計画と実際の変更を区別する |
確認中に新しい疑問が生まれ、再び探索へ戻ることもあります。ただし、そのデータで見つけた仮説を、同じデータで独立に確かめたとは言えません。 探索の反復は有用ですが、見つけ方を隠すと確からしさを読み違えます。R for Data Science 第1版:EDA、ASA:p値に関する公式声明の案内
最初に行・単位・期間を決める
可視化の前に、データの説明を短く書きます。例えば問い合わせ対応なら、1行は「問い合わせ1件」なのか「返信1回」なのかで、件数も平均時間も変わります。同じ問い合わせを複数行で数えたまま、顧客数として解釈しないようにします。
表が収まらない場合は、横にスクロールできます
| 確認すること | 問い合わせデータでの確認例 |
|---|---|
| 対象と期間 | どの窓口の、いつ受け付けた問い合わせか |
| 行と識別子 | 問い合わせIDは一意か。結合で行が増えていないか |
| 列の意味と単位 | 初回返信までの暦時間か、営業時間だけか。単位は時間か分か |
| 記録されない状態 | 時刻の記録漏れ、未返信、対象外を区別できるか |
| 更新・取得時点 | 後から返信された案件が、集計に反映されているか |
| 比較条件 | 窓口、受付時間帯、難易度、休日の扱いが同じか |
数値に見えるIDは量ではありません。郵便番号や顧客コードの平均を計算しても、業務上の意味は得られません。日付の型、単位の混在、あり得ない負数、重複IDもここで確認します。
仮想10件で、分布と欠測を一緒に見る
以下は説明用の仮想データです。実顧客の成果ではありません。同じ窓口・同じ週に受け付け、すべて初回返信済みの10件を対象とします。うち2件は時刻の記録漏れで、返信時間が分かりません。
表が収まらない場合は、横にスクロールできます
| 問い合わせID | 初回返信までの時間 |
|---|---|
| A | 1時間 |
| B | 2時間 |
| C | 2時間 |
| D | 3時間 |
| E | 3時間 |
| F | 4時間 |
| G | 4時間 |
| H | 21時間 |
| I | 欠測 |
| J | 欠測 |
記録のある8件の合計は40時間、平均は5時間、中央値は3時間です。欠測は全10件中2件で20%です。平均5時間は記録のある8件の平均であり、10件全体の平均はこの情報だけでは分かりません。欠測をゼロにすると平均は4時間となり、「不明」を「即時返信」に置き換えてしまいます。
21時間を仮に除くと、残る7件の合計は19時間、平均は約2.71時間です。中央値は3時間のままです。この違いは「1件が平均をどの程度動かすか」を示します。21時間が入力ミスなのか、休日をまたいだ実際の対応なのか、難しい案件なのかは、数値の並びだけでは決まりません。
業務負荷や総待ち時間を把握したいなら、大きい値も重要です。通常の範囲を説明したい場合も、中央値と一緒に分布や長い待ち時間の件数を示すと、代表値だけでは消える問題を残せます。
変数の型に合わせて図を選ぶ
図は「何が知りたいか」に合わせて選びます。少数の観測なら、集約した図だけでなく元の点を見せると、値の重なりや件数が分かります。
表が収まらない場合は、横にスクロールできます
| 調べたいこと | 最初に使う図・表 | 読むときの条件 |
|---|---|---|
| 数値の分布 | ヒストグラム、ドットプロット、箱ひげ図 | ヒストグラムの階級幅を変えて形を確認。箱だけでは件数や複数の山が隠れる |
| カテゴリの構成 | 件数表、棒グラフ | 不明・その他を隠さず、割合の分母も併記する |
| 時間の変化 | 時系列の折れ線、曜日別・時間帯別集計 | 欠測期間、休日、営業時間、集計間隔、計測変更を確認する |
| 数値同士の関係 | 散布図 | 直線以外の形、少数の極端値、グループ差も見る |
| グループごとの数値 | 箱ひげ図と点、ヒストグラム | 各群の件数を示し、同じ軸で比較する |
| カテゴリ同士の関係 | クロス集計、割合を示すヒートマップ | 行割合と列割合のどちらかを明記する |
密度曲線は平滑化の設定で形が変わります。点が大量に重なる散布図では、透明度や区画ごとの件数を使う方法もあります。図がきれいに見える設定を選んだだけで結論を強めないことが大切です。R for Data Science 第1版:分布と変数間の関係
Q-Qプロットは分位点同士を比べ、分布の形を調べる図です。別の標本との比較や、理論分布との比較で使われます。線に近く見えるだけで、仮定が正しいと確定するわけではありません。NIST:Quantile-Quantile Plot
時系列では、周期的な動きと持続する変化を分けて考えます。季節分解や自己相関を使う場合も、観測間隔、欠測、十分な周期数を先に確認します。自己相関は時間差を持つ値の関連を見るもので、それが見つからないだけで完全なランダム性を証明できるわけではありません。同じ人や店舗を繰り返し測った値も、互いに独立な別人の観測とは扱えません。NIST:Autocorrelation Plot
欠測は理由と分母を記録する
欠測には、入力し忘れた、回答を避けた、そもそも対象外、まだ結果が出ていない、といった異なる事情があります。未返信の案件を返信済み案件から落として平均時間を出すと、遅い案件ほど集計されにくい可能性があります。先ほどの仮想例が「全件返信済み」としたのは、この違いを混ぜないためです。
欠測率を全体だけでなく、時期・窓口・顧客区分などでも確認します。ただし、表から原因がすべて分かるわけではありません。
表が収まらない場合は、横にスクロールできます
| 欠測機構 | 考え方 | 判断上の注意 |
|---|---|---|
| MCAR | 欠測の起き方が、観測された値にも欠けた値にも依存しない | 単に「偶然だろう」と置かず、記録過程を確認する |
| MAR | 観測済みの情報を条件にすると、欠測の起き方が欠けた値に依存しない | どの観測情報で条件づけるかが必要 |
| MNAR | 観測済みの情報を考慮しても、欠けた値自体への依存が残る | 観測できない部分について別の仮定も検討する |
観測されたデータだけから、MARとMNARを区別することはできません。 記録方法の確認、追加調査、仮定を変えた感度分析が必要になることがあります。削除や平均補完を既定の処理にせず、なぜその方法を選ぶかを残します。van Buuren:欠測の概念と識別
外れ値は調べるきっかけであり、削除命令ではない
箱ひげ図で使われることの多い1.5×IQRの基準は、第1四分位数から下へ、第3四分位数から上へ、四分位範囲の1.5倍を超えた値を目立たせるものです。少数のデータでは四分位数の計算法でも境界が変わるため、使用した定義を確認します。
Zスコアは平均からの距離を標準偏差で表しますが、「絶対値3以上なら誤り」とは限りません。分布の形や件数、複数の極端値が互いに影響を隠す場合も考える必要があります。NISTも、外れ値を識別する検定の仮定や、誤検出・見落としに注意を向けています。NIST:Detection of Outliers
実務では次の順で確認すると、処理理由を説明できます。
- 原票・計測ログを見て、入力や単位、結合の誤りを確かめる。
- 実際の事象なら、対象に含める目的か、別の群として扱うべきかを考える。
- 修正・除外した件数と理由を残し、処理前後で結論が変わるかを示す。
複数の数値の組み合わせでは、各列が普通でも組み合わせが珍しいことがあります。マハラノビス距離やLOFなどはその探索候補ですが、距離の定義、列の尺度、参照する近傍、データ量に依存します。検出ラベルをそのまま不正・不良・不要な顧客と読み替えないでください。scikit-learn:外れ値検出の仮定と手法
関係を見つけても、原因はまだ決まらない
広告費と売上が一緒に増えていても、広告が原因とは限りません。繁忙期に両方が増える、売上の見込みが高いから広告費を増やす、といった別の説明があり得ます。散布図では全体だけでなく、期間や顧客層を分けた関係も見ます。ただし、細かく分けすぎると件数が減り、偶然の形も見つかりやすくなります。
相関係数一つでは、曲線状の関係や少数点の影響を見落とします。NISTの散布図の解説も、線形・非線形の形や外れ値を確認する用途と、因果の証明を区別しています。NIST:Scatter Plot
変数が増えたとき
散布図行列や相関行列は関係を広く見る入口です。PCAは複数の数値を少数の軸に要約する方法、クラスタリングは似た観測をまとめる方法として使えます。ただし、標準化、使用する列、距離、群の数で結果は変わります。「顧客が本来この分類に分かれる」と確定する道具ではありません。scikit-learn:PCA、クラスタリングの前提
分類が業務上意味を持つか、別期間にも現れるか、結果を知った後の列を予測に混ぜていないかを確認します。具体的な手法へ進むときは、多変量解析を業務で使うときの条件も参照してください。
多く探したあとの当たりを検証済みにしない
曜日、地域、端末、商品、年齢層と比較を増やすほど、目立つ違いを見つける機会も増えます。見つかった1件だけを報告すると、どれだけ探した結果なのかが伝わりません。
単純化した仮想例として、すべての帰無仮説が真で、各検定が互いに独立し、それぞれ誤って棄却する確率が5%だとします。20回のうち少なくとも1回誤って棄却する確率は、1 − 0.95の20乗で約64.2%です。これは独立性などを置いた計算例で、実際の探索すべての誤り率を表す数字ではありません。
確認したい比較を事前に絞る、複数比較を考慮する、探索に使わなかったデータで確かめる、といった方法があります。Bonferroni法は複数比較への一つの対応ですが、探索の経緯を消すものでも、どの状況でも最善の方法でもありません。NIST:Bonferroni method
将来の予測が目的なら、評価データへ未来の情報が混ざらない分け方が必要です。時間を無視したランダム分割が常に適切とは限りません。施策の因果効果が目的なら、実験計画と比較の設計へ進みます。p値の閾値だけで採用を決めず、効果の大きさ、費用、失敗時の影響も合わせて判断します。ASA:統計的有意性とp値
小売とWebで次に確かめること
小売なら、売上金額の分布だけでなく、値引き・返品・欠品・購入機会の違いを調べます。「会員の再購入が多い」という関連を見つけても、会員化の効果とは限りません。元から購入意欲の高い人が会員になる可能性があります。再購入率を比べるなら、初回購入から同じ長さの追跡期間を確保できるかも確認します。
Webでは件数と割合を分けます。説明用の仮想比較で、同じ長さの集計期間に、Aは対象100人中10人、Bは対象200人中12人が購入したとします。各人は各期間で1回だけ数えます。Bは購入者数が多くても、購入した人の割合はAの10%に対し6%です。ここから改善や悪化の原因を決めることはできず、流入元、端末、計測条件などを確認します。
表が収まらない場合は、横にスクロールできます
| 発見した候補 | 別の説明として確認すること | 次の確認 |
|---|---|---|
| 特定商品の客単価が高い | 大口注文、値引き、返品の扱い | 取引明細と購入者単位の分布を併記 |
| 週末の問い合わせが少ない | 営業時間や訪問者数が違う | 受付可能時間や対象人数を分母にする |
| 滞在が長い人ほど購入する | 迷っている、購入後の閲覧を含む | 時点とイベント順序を確認する |
| 特定の顧客群で離脱が多い | 追跡期間や契約更新時期が違う | 同じ観測機会を持つ群で再集計する |
これらは分析の問いの例であり、特定企業で観測された改善実績ではありません。
Pythonで最小確認を再現する
次の例は先ほどの仮想10件を使います。Python 3の標準ライブラリだけで動き、追加インストールや外部ファイルは不要です。欠測にはNoneを使い、値が分かる8件を明示して集計します。Python:statistics
from statistics import mean, median
# 仮想例。全件返信済みで、Noneは時刻の記録漏れ。
response_hours = [1, 2, 2, 3, 3, 4, 4, 21, None, None]
observed = [x for x in response_hours if x is not None]
missing = len(response_hours) - len(observed)
print(f"total={len(response_hours)}, observed={len(observed)}, missing={missing}")
print(f"missing_rate={missing / len(response_hours):.0%}")
print(f"mean={mean(observed):.2f}, median={median(observed):.2f}")
# 21時間の1件を仮に除いた感度確認。実データの削除ルールではない。
without_case_h = observed[:-1]
print(f"sensitivity_mean={mean(without_case_h):.2f}")
assert sum(observed) == 40
assert mean(observed) == 5
assert median(observed) == 3
期待する出力は次のとおりです。
total=10, observed=8, missing=2
missing_rate=20%
mean=5.00, median=3.00
sensitivity_mean=2.71
このコードは全件欠測など任意の入力に対応する汎用処理ではなく、入力を固定した学習用の確認です。実務へ移すときは、空の集計対象、単位、負数、対象外値、更新されたデータをどう扱うかも決めます。
表計算で始めても構いません。反復する集計にはSQL、分析過程を保存する用途にはPythonやR、共有にはBIなど、目的で選びます。ツールの比較はデータ分析ツールの選び方にまとめています。
最小検証:一つの結論に一枚のメモを残す
「平均返信時間は5時間だった」で終えず、対象の定義、取得日、全件数と有効件数、欠測・除外、使った図と集計方法を残します。その上で、結論を次の三つに分けます。
- 分かったこと:仮想10件のうち記録済み8件の平均は5時間、中央値は3時間。
- まだ分からないこと:欠測2件の時間、21時間の理由、他の週でも同じか。
- 次に確かめること:記録漏れの原因と案件Hの原記録を確認し、同じ定義で別の週を集計する。
列の意味が不明なままなら、図を増やす前に担当者へ確認します。問いが具体化できたら、統計的な判断の分岐や仮説検証の進め方を使い、追加観測・比較実験・保留のどれが必要かを選んでください。