Day 013 — 分散・標準偏差・外れ値(分析)

2026-04-22 白 / Phase 1 分析 分散・標準偏差・外れ値

📚 背景知識(読んでから問題へ)

標準偏差とは?

データがどれだけ「バラついている」かを表す数値です。

  • 標準偏差が小さい → データが平均のそばに集まっている(整列した社員の身長)
  • 標準偏差が大きい → データが広く散らばっている(日本全国の年収)

外れ値(Outlier)とは?

他のデータとかけ離れた値のこと。

例: クラスの身長 [160, 162, 165, 168, 170, 210] → 210 は外れ値

IQR(四分位範囲)法

外れ値を検出するための定番手法。

Q1 = 25パーセンタイル(下から25%の位置の値)
Q3 = 75パーセンタイル(下から75%の位置の値)
IQR = Q3 - Q1

外れ値の境界:
  下限 = Q1 - 1.5 × IQR
  上限 = Q3 + 1.5 × IQR

この範囲を外れた値を「外れ値」として扱います。箱ひげ図(boxplot)はこの方法を視覚化したものです。

Kaggleでなぜ重要?

  • 外れ値をそのまま学習に使うとモデルが歪む(特に線形回帰)
  • 外れ値をどう扱うか(除去・変換・保持)が特徴量エンジニアリングの基本

📝 問題

以下のデータは「架空のECサイトの顧客1人あたりの月間購入金額(円)」です。

import numpy as np
import pandas as pd

data = [1200, 1500, 1800, 1600, 1400, 1700, 1300, 1550, 1650, 1450,
        1800, 1200, 1350, 1600, 1500, 99800, 1400, 1700, 1250, 1600]

以下の分析を行いなさい:

  1. 平均・中央値・標準偏差を計算する
  2. IQR法で外れ値の境界(上限・下限)を計算し、外れ値を特定する
  3. 外れ値を除いた平均と除く前の平均を比較し、外れ値の影響を説明する
  4. 箱ひげ図(boxplot)を描いて外れ値を視覚的に確認する

🔍 ヒント(段階的開示)

ヒント1(方向性)

numpy と pandas の基本統計関数(mean, median, std, percentile)を使えばほとんど解ける。

boxplot は matplotlib の plt.boxplot() または seaborn の sns.boxplot() を使う。

ヒント2(IQR法のコード)
q1 = np.percentile(data, 25)
q3 = np.percentile(data, 75)
iqr = q3 - q1
lower = q1 - 1.5 * iqr
upper = q3 + 1.5 * iqr
ヒント3(外れ値の除去)
data_array = np.array(data)
mask = (data_array >= lower) & (data_array <= upper)
data_clean = data_array[mask]
outliers = data_array[~mask]

模範解答

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data = [1200, 1500, 1800, 1600, 1400, 1700, 1300, 1550, 1650, 1450,
        1800, 1200, 1350, 1600, 1500, 99800, 1400, 1700, 1250, 1600]

data_array = np.array(data)

# 1. 基本統計
mean_val   = np.mean(data_array)
median_val = np.median(data_array)
std_val    = np.std(data_array)

print(f"平均:     {mean_val:.1f} 円")
print(f"中央値:   {median_val:.1f} 円")
print(f"標準偏差: {std_val:.1f} 円")

# 2. IQR法で外れ値を検出
q1 = np.percentile(data_array, 25)
q3 = np.percentile(data_array, 75)
iqr = q3 - q1
lower = q1 - 1.5 * iqr
upper = q3 + 1.5 * iqr

print(f"\nQ1: {q1}, Q3: {q3}, IQR: {iqr}")
print(f"外れ値の境界: [{lower:.1f}, {upper:.1f}]")

mask = (data_array >= lower) & (data_array <= upper)
outliers    = data_array[~mask]
data_clean  = data_array[mask]

print(f"外れ値: {outliers}")

# 3. 外れ値除去前後の比較
mean_before = np.mean(data_array)
mean_after  = np.mean(data_clean)
print(f"\n外れ値除去前の平均: {mean_before:.1f} 円")
print(f"外れ値除去後の平均: {mean_after:.1f} 円")
print(f"差: {mean_before - mean_after:.1f} 円")

# 4. 箱ひげ図
fig, axes = plt.subplots(1, 2, figsize=(10, 4))
axes[0].boxplot(data_array)
axes[0].set_title("外れ値あり")
axes[0].set_ylabel("購入金額(円)")

axes[1].boxplot(data_clean)
axes[1].set_title("外れ値除去後")
axes[1].set_ylabel("購入金額(円)")

plt.tight_layout()
plt.savefig("boxplot_outlier.png")
plt.show()
print("boxplot_outlier.png を保存しました")

実行結果:

▶ 出力を見る
平均:     6665.0 円
中央値:   1525.0 円
標準偏差: 21668.9 円

Q1: 1375.0, Q3: 1675.0, IQR: 300.0
外れ値の境界: [925.0, 2125.0]
外れ値: [99800]

外れ値除去前の平均: 6665.0 円
外れ値除去後の平均: 1497.4 円
差: 5167.6 円

🪜 Step-by-Step 解説

1
基本統計の確認

平均が 6665円 なのに中央値が 1525円。この差が大きいのは 外れ値(99800円)が平均を引き上げているから

→ 外れ値がある場合、平均より 中央値のほうが実態を表す

2
IQR法の計算
  • Q1(25パーセンタイル)= 1375円:下位25%の顧客の「境界値」
  • Q3(75パーセンタイル)= 1675円:上位25%の顧客の「境界値」
  • IQR = 300円:中央50%のデータの幅
  • 上限 = 1675 + 1.5 × 300 = 2125円
  • 99800円 >> 2125円 → 明確な外れ値
3
外れ値の影響を数字で確認

平均が 6665円 → 1497円 に大幅変化(差: 5167円)。

たった1件の外れ値が平均を4倍以上に膨らませていた。

4
箱ひげ図の読み方
|---------|-------|        ← ひげ(whisker)= 境界まで
    [   ========  ]       ← 箱 = Q1〜Q3(中央50%)
          |               ← 中央線 = 中央値
  ×                       ← 点 = 外れ値(boxの外の点)

📐 数学・統計の補足(文系向け)

標準偏差 21668円 は非常に大きい値。これは「ほとんどの顧客は1500円前後なのに、1人だけ10万円近く使っている」という状況を数字で示している。

標準偏差が大きい = データが信用できないかもしれない。Kaggleでは最初にこのバラつきをチェックするのがルーティン。


🏆 Kaggleでの実践的な使い方

  1. EDA(探索的データ分析)の第一歩: df.describe() で std を確認 → stdが mean と同じくらい大きければ外れ値を疑う
  2. ターゲット変数の外れ値: House Prices コンペでは価格の外れ値を log変換して扱う(後のPhaseで学ぶ)
  3. 特徴量エンジニアリング: 外れ値をclippingする np.clip(data, lower, upper) もよく使う手法

⚠️ よくある誤解・ミス

誤解・ミスなぜ起こるか正しい理解
外れ値を必ず除去する「ノイズだ」と思い込む外れ値が重要な情報の場合も。まず「なぜ外れているか」を考える
平均だけで判断する最も馴染みのある統計量中央値・stdと一緒に確認するのが基本
IQRの1.5は絶対教科書通り2.0や3.0を使うこともある。データと問題次第

🚀 次のステップ

  • 発展: log変換(外れ値を小さく見せる変換)
  • 次回予告: 確率の基礎(確率とは何か)

🎯 自己評価

自分の回答

気づき・メモ