外れ値と頑健性|記述統計と標本
このページはプロモーション(広告)を含みます。
記述統計と標本(中級・読む25分+演習35分)
この授業のゴール
- 四分位範囲(IQR)の1.5倍ルールで外れ値の候補を見つけ、境界値を計算できる
- 外れ値を含む場合と除いた場合で、平均・中央値・標準偏差がどう動くかを数値で比べられる
- 外れ値の原因(入力ミス・本物の極端な値・別集団の混入)を区別し、削除・訂正・保持の判断を理由付きで説明できる
- z得点のルールが少数データで外れ値を見逃す理由を説明できる
仕事でどう使うか
外れ値は『消すべき邪魔者』ではなく、『確認すべき情報』です。入力ミスなら直す、本物の大口なら残す、別の集団なら分けて扱う。この判断が、集計結果の信頼性を決めます。
| 路線 | この授業の使いどころ |
|---|---|
| DS(データサイエンティスト) | 集計前の品質確認。単位の混在(円と千円)や桁の誤りを外れ値として発見し、データ提供元に確認する。分析ログに『何を・なぜ・何件』処理したかを残します |
| ML(機械学習エンジニア) | 外れ値で学習が歪むのを防ぐ(外れ値に強い損失、クリッピング、対数変換)。ただし不正検知のように外れ値自体が予測対象の場合は、消してはいけません |
| DX(DX推進・AI企画) | KPI(Key Performance Indicator:重要業績評価指標)の報告に中央値やIQRを併記する。ごく一部の大口案件や異常に長い処理が、平均を大きく動かすことを経営層に説明できます |
| RS(研究者) | 外れ値の扱いを研究計画で事前に決める。結果を見てから都合よく除外すると、結論の信頼性を損ないます。除外基準と件数を論文に書きます |
この授業の目的は、外れ値を見つける式を覚えることではなく、見つけたあとに何をするかの判断を言葉にすることです。
前提
次の言葉を使います。
コードは numpy の np.percentile(分位点)、np.mean、np.median、np.std(ddof=1 で標本標準偏差)を使います。
身近な状況:1日だけ売上が120万円だった
架空のカフェの、9日間の売上(万円)です。
| 日 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|
| 売上(万円) | 8 | 9 | 9 | 10 | 11 | 11 | 12 | 13 | 120 |
合計203万円、平均は 203÷9≒22.6万円です。担当者は「1日平均22.6万円」と月次報告に書こうとしました。しかし、9日中8日は13万円以下です。22.6万円という日は1日もありません。
9日目の120万円は、本当に120万円だったのでしょうか。可能性は3つあります。
- 入力ミス:12.0万円と入力すべきところを、小数点を落として120にした。
- 本物の極端な値:貸し切りの大型イベントがあり、実際に120万円売れた。
- 別の集団:普段の店舗売上ではなく、ネット通販の売上が混入した。
原因によって、取る行動は全く違います。1なら訂正、2なら残して『特別な日』と注記、3なら分けて集計します。この授業では、値が怪しいと気づく方法と、原因ごとの判断を学びます。
直感的な説明:クラスに一人だけ巨人がいる
身長を測るクラスに、一人だけ3メートルの人が混ざっていたとします。
- 平均身長は大きく上がります。クラスのほとんどが平均より低くなります。
- 中央値(真ん中の人)は、ほとんど動きません。
- 散らばり(標準偏差)は一人のために大きく跳ね上がります。
このように、一部の極端な値に動かされにくい性質を頑健性(robustness)といいます。中央値や四分位範囲は頑健で、平均や標準偏差は頑健ではありません。
ただし、3メートルの人は『測り間違い』かもしれません。巨人が本当にいた(本物の値)としても、『クラスの典型的な身長』を知りたいなら中央値のほうが適切です。一方で『クラス全員の身長の合計』を知りたいなら、巨人を含めた平均が必要です。目的によって、使う指標も、外れ値の扱いも変わります。
用語:外れ値とは『他の大半の値から大きく離れた値』のことです。『誤りの値』ではありません。誤りかどうかは、原因を調べて初めて決まります。
正確な定義:IQRルール・z得点・頑健な指標
IQR(1.5倍)ルール:第1四分位数 $Q_1$、第3四分位数 $Q_3$、四分位範囲 $\mathrm{IQR}=Q_3-Q_1$ から、次の境界を計算します。
$$\text{下側境界}=Q_1-1.5\times\mathrm{IQR},\qquad \text{上側境界}=Q_3+1.5\times\mathrm{IQR}$$
境界の外にある値を外れ値の候補とします(箱ひげ図の『ひげ』の外側に点で描かれる値です)。係数1.5は慣習で、絶対的な基準ではありません。外れ値は削除する対象ではなく『確認する対象』です。
z得点:$z_i=(x_i-\bar{x})\div s$。$x_i$ は値、$\bar{x}$ は標本平均、$s$ は標本標準偏差で、単位のない値になります。$|z|>3$ を外れ値の目安とすることがあります。ただし次の弱点があります。
- 平均と標準偏差は外れ値自身に引っ張られるので、外れ値が大きいほど $s$ も大きくなり、$z$ が小さく出ます(マスキング)。
- 標本サイズ $n$ のとき、標本標準偏差を使った $|z|$ の最大値は $(n-1)\div\sqrt{n}$ です。$n=9$ なら $8\div3\approx2.67$ で、どんなデータでも $|z|>3$ にはなりません。
頑健な指標:
| 指標 | 内容 | 外れ値への強さ |
|---|---|---|
| 中央値 | 並べた真ん中の値 | 強い |
| IQR | $Q_3-Q_1$ | 強い |
| MAD(中央絶対偏差) | 各値の中央値からの距離の絶対値の中央値 | 強い |
| トリム平均 | 両端の一部を除いて平均 | 比較的強い |
| 平均、標準偏差、範囲 | 全部の値に依存する | 弱い |
ウィンザー化とは、境界を超えた値を境界の値に置き換える(切り詰める)処理です。データを捨てずに影響を弱めますが、元のデータの値は変わるので、実施したことを記録します。
段階付き例題:9日間の売上で外れ値を判断する
ステップ1:四分位数を出す。 9個なので $Q_1$ は $1+8\times0.25=3$ 番目の9、中央値は5番目の11、$Q_3$ は $1+8\times0.75=7$ 番目の12。IQR=12−9=3。
ステップ2:境界を計算する。 下側:$9-1.5\times3=4.5$。上側:$12+1.5\times3=16.5$。8〜13は範囲内で、120だけが上側境界を超えます。外れ値の候補は120の1件です。
ステップ3:z得点で比べる。 標本標準偏差は約36.58万円、平均は約22.56万円で、120の $z=(120-22.56)\div36.58\approx2.66$。$|z|>3$ のルールでは検出されません。IQRルールは検出できます。
ステップ4:外れ値の有無で指標を比べる。
import numpy as np
x = [8, 9, 9, 10, 11, 11, 12, 13, 120]
q1, med, q3 = np.percentile(x, [25, 50, 75])
iqr = q3 - q1
low, high = q1 - 1.5 * iqr, q3 + 1.5 * iqr
print("Q1, 中央値, Q3, IQR:", q1, med, q3, iqr)
print("境界:", low, high)
print("外れ値候補:", [v for v in x if v < low or v > high])
mean, s = np.mean(x), np.std(x, ddof=1)
print("平均:", round(mean, 2), " 標本SD:", round(s, 2), " z(120):", round((120 - mean) / s, 2))
y = x[:-1] # 120を除いた8日
print("除外後 平均:", round(np.mean(y), 3), " 中央値:", np.median(y), " SD:", round(np.std(y, ddof=1), 2))
出力は次のとおりです。
- Q1, 中央値, Q3, IQR:9.0 11.0 12.0 3.0
- 境界:4.5 16.5、外れ値候補:[120]
- 平均 22.56、標本SD 36.58、z(120) 2.66
- 除外後 平均 10.375、中央値 10.5、SD 1.69
| 指標 | 120を含む | 120を除く |
|---|---|---|
| 平均 | 22.56 | 10.375 |
| 中央値 | 11 | 10.5 |
| 標準偏差 | 36.58 | 1.69 |
ステップ5:原因を調べて決める。 店長に確認すると、『12.0万円と入力するところを120と入力した』と判明しました。→ 訂正します。訂正後の平均は 95÷9≒10.56万円、中央値11万円です。もし『大型イベントで実際に120万円売れた』なら、120は残して『イベント日を含む平均』と『除く平均』を並べて報告します。
操作して理解する:外れ値の大きさを変えて感度を見る
9日目の値を 12、120、1200 に変えたとき、平均・中央値・標準偏差がどう動くかを確かめます。感度分析(条件を変えて結果の動きを見る分析)の簡単な例です。
import numpy as np
base = [8, 9, 9, 10, 11, 11, 12, 13]
for last in (12, 120, 1200):
x = base + [last]
print(last, "平均:", round(np.mean(x), 2),
" 中央値:", np.median(x),
" SD:", round(np.std(x, ddof=1), 2))
出力は次のとおりです。
| 9日目の値 | 平均 | 中央値 | 標準偏差 |
|---|---|---|---|
| 12 | 10.56 | 11.0 | 1.67 |
| 120 | 22.56 | 11.0 | 36.58 |
| 1200 | 142.56 | 11.0 | 396.54 |
9日目が120から1200に10倍になっても、中央値は11のままです。平均は 10.56→22.56→142.56 と暴れます。『平均が頑健でない』とは、1つの値で自由に動かせることを意味します。
試してみましょう。
baseの値を1つ増やして 10 個にして、lastを 120 にすると、平均への影響は小さくなるでしょうか。データ数が増えるほど、1件の影響は小さくなります。lastを-1000にしても、中央値は動きません。下側の極端な値でも同じ性質です。- 係数1.5を3に変えると、外れ値と判定される値は増えるでしょうか、減るでしょうか。係数を大きくすると境界が広がり、判定は厳しくなって減ります。
発展:破綻点・MAD・多次元の外れ値
破綻点:データの何%を極端な値に置き換えると、統計量が無意味な値になるか、を表します。平均は1件で崩れるので破綻点は実質0%。中央値は約50%まで耐えます。IQRは約25%です。
MAD による基準化:$\mathrm{MAD}=\mathrm{median}(|x_i-\mathrm{median}(x)|)$。正規分布を仮定するなら、$1.4826\times\mathrm{MAD}$ が標準偏差に対応します。『中央値からの距離が3×1.4826×MAD を超えたら外れ値候補』という頑健なz得点(修正z得点)は、マスキングに強い方法です。
例題の9日間では、中央値11、各値との差の絶対値は 3, 2, 2, 1, 0, 0, 1, 2, 109 で、その中央値(MAD)は 2 です。120の修正z得点は $109\div(1.4826\times2)\approx36.8$ で、はっきり検出されます。
多次元の外れ値:1つの列では普通の値でも、組み合わせが異常な場合があります(身長180cmと体重40kg)。1列ずつ見るだけでは見つからず、距離(マハラノビス距離)や異常検知の手法が必要です(クラスタ・次元削減・異常検知(有料版))。
外れ値を残す選択:不正検知や設備の異常検知では、外れ値自体が目的です。また、ごく少数の大口顧客が売上の大半を占める事業では、外れ値を除くと事業の実態を見失います。外れ値の扱いは統計の問題というより、事業の問題でもあります。
よくある失敗
失敗1:理由なく自動で外れ値を削除する
誤った例:10人の顧客の購入額(千円)が 3, 4, 4, 5, 5, 6, 6, 7, 8, 152 のとき、IQRルールで152が外れ値なので削除して『平均5.3千円』と報告する。
import numpy as np
w = [3, 4, 4, 5, 5, 6, 6, 7, 8, 152]
print("合計:", sum(w), " 152の占める割合:", round(152 / sum(w), 2))
print("平均(全件):", np.mean(w), " 中央値:", np.median(w))
print("平均(152を除く):", round(np.mean(w[:-1]), 2))
出力は『合計: 200 152の占める割合: 0.76』『平均(全件): 20.0 中央値: 5.5』『平均(152を除く): 5.33』です。
誤りの理由:152が本物の大口顧客なら、売上の76%はこの1人から来ています。削除して『平均5.3千円』と報告すると、売上計画の見積もりが大きく外れます。
直し方:原因を調べる。本物なら残し、『大口顧客を含む平均20.0千円・中央値5.5千円、大口1人で売上の76%』と報告する。事業上重要な情報です。
失敗2:z得点 |z|>3 だけで検出しようとする
誤った例:9日間の売上の120万円に対して、z得点が2.66なので『外れ値ではない』と判断する。
import numpy as np
n = 9
print("標本サイズ9での |z| の最大値:", round((n - 1) / np.sqrt(n), 3))
x = [8, 9, 9, 10, 11, 11, 12, 13, 120]
print("120のz:", round((120 - np.mean(x)) / np.std(x, ddof=1), 3))
出力は『標本サイズ9での |z| の最大値: 2.667』『120のz: 2.664』です。
誤りの理由:外れ値が平均と標準偏差を引き上げるため、自分自身の $z$ が小さく出ます。n=9 では $|z|$ は2.667を超えられず、どんなに大きな値でも $|z|>3$ になりません。
直し方:標本が小さいとき、外れ値が含まれる可能性があるときは、IQRルールや修正z得点(MAD)を使う。複数の方法で確認するのが安全です。
失敗3:単位の混在を見逃して平均を出す
架空の注文金額(円)に、1件だけ千円単位(3.2千円)で入力された行が混ざっています。
import numpy as np
p = [2400, 3100, 2800, 2650, 3300, 2900, 3050, 2750, 3.2]
q1, q3 = np.percentile(p, [25, 75])
low = q1 - 1.5 * (q3 - q1)
print("平均:", round(np.mean(p), 2), " 中央値:", np.median(p))
print("下側境界:", low, " 候補:", [v for v in p if v < low])
fixed = p[:-1] + [3.2 * 1000] # 千円を円に直す
print("訂正後の平均:", round(np.mean(fixed), 2))
出力は『平均: 2550.36 中央値: 2800.0』『下側境界: 2050.0 候補: [3.2]』『訂正後の平均: 2905.56』です。
誤りの理由:3.2円の注文は存在しません。平均は約355円低く出て、報告が誤ります。集計前の単位確認(単位と桁と丸め)が抜けています。
直し方:境界の外にある値を見つけたら、削除する前に『単位・桁』を疑う。元データの定義を確認して訂正し、訂正した件数と内容を記録する。
まとめ
- 外れ値は『他の値から大きく離れた値』で、誤りとは限らない。原因(入力ミス・本物・別集団)を調べて、訂正・保持・分離を決める。
- IQRルールは Q1−1.5×IQR と Q3+1.5×IQR を境界にする。z得点は小標本で外れ値を見逃す(n=9 では |z|≦2.67)。
- 中央値・IQR・MADは頑健。平均・標準偏差・範囲は外れ値の影響を直接受ける。
- 外れ値の有無で指標を比べる(感度分析)。差が大きいなら両方を報告する。
- 削除・訂正・ウィンザー化を行ったら、方法と件数を記録する。
用語
- 外れ値(outlier)
他の大半の値から大きく離れた値。誤りとは限らず、原因を調べて扱いを決める。
- 頑健性(robustness)
一部の極端な値に結果が動かされにくい性質。中央値やIQRは頑健。
- IQRルール(1.5 × IQR rule)
Q1−1.5×IQR と Q3+1.5×IQR を境界とし、その外の値を外れ値の候補とする方法。
- MAD(中央絶対偏差)(median absolute deviation)
各値の中央値からの距離の絶対値の中央値。外れ値に強い散らばりの指標。
- トリム平均(trimmed mean)
両端の一定割合の値を除いて計算した平均。
よくある質問
外れ値は削除してよいのですか。
入力ミスや測定エラーと確認できたものは、訂正または削除します。本物の値は、原則として残します。削除・訂正した場合は『何を・なぜ・何件』を記録します。結果を見てから都合よく削除すると、結論が信頼できなくなります。
IQRルールの1.5は、なぜ1.5なのですか。
統計学者テューキーが提案した慣習で、正規分布なら約0.7%の値が境界の外に出る程度です。理論的な必然はありません。3倍にすれば『極端な外れ値』のみを検出できます。目的に合わせて決め、使った係数を書きます。
外れ値がある場合、平均は使ってはいけませんか。
使えます。合計や総量が目的なら、外れ値を含めた平均が必要です。典型的な水準を伝えたいなら中央値のほうが適切です。両方を併記して、差が大きいこと自体を伝えるのが良い報告です。
ウィンザー化やトリム平均は、いつ使いますか。
外れ値を捨てずに影響を弱めたいときに使います。たとえば上下5%を切り詰めます。元のデータが変わるため、使った処理と割合を記録します。標準的な指標として中央値とIQRで足りる場面も多いです。
外れ値が多すぎて、全体の1割以上になった場合は?
外れ値ではなく『別の集団が混ざっている』可能性が高いです。集団を分けて集計する、分布全体の形(二峰など)を確認する、といった対応を検討します(層別と集計の罠)。
機械学習では、外れ値はどう扱いますか。
線形モデルは外れ値の影響を受けやすいので、クリッピングや対数変換、外れ値に強い損失(Huber損失など)を使います。木に基づくモデルは比較的影響を受けにくいです。不正検知のように外れ値が目的なら、消さずに特徴量として使います(クラスタ・次元削減・異常検知(有料版))。
確認問題
問1 9件のデータで、標本標準偏差を使った z 得点の絶対値の最大値は約2.67である。このことから導かれる注意点はどれか。
- ① z得点が3を超えれば、必ず外れ値である
- ② 少数のデータでは、どんなに極端な値でも |z|>3 にならず、外れ値を見逃す
- ③ z得点は外れ値の判定に使ってはならない
- ④ n が大きいほど |z| の最大値は小さくなる
解答と解説
正解:②
標本サイズ n では |z| の最大値が (n−1)/√n に制限されます。n=9 なら約2.67で、3には届きません。
問2 IQRルールで外れ値候補が見つかった。最初に取るべき行動はどれか。
- ① 原因(入力ミス・本物の極端な値・別集団)を確認する
- ② ただちに削除する
- ③ 平均で置き換える
- ④ 何もせず、そのまま報告する
解答と解説
正解:①
外れ値は誤りとは限りません。原因によって訂正・保持・分離を決めます。削除は最後の手段で、理由と件数を記録します。
問3 9日間の売上 8, 9, 9, 10, 11, 11, 12, 13, 120(万円)で、IQRルールの上側境界はいくつか(Q1=9、Q3=12)。
- ① 13
- ② 15
- ③ 16.5
- ④ 18
解答と解説
正解:③
IQR=12−9=3。上側境界は Q3+1.5×IQR=12+4.5=16.5 です。
問4 外れ値を含むデータの代表値として、一般に最も影響を受けにくいものはどれか。
- ① 平均
- ② 範囲(最大−最小)
- ③ 標準偏差
- ④ 中央値
解答と解説
正解:④
中央値は順位の真ん中の値で、端の値が大きく変わっても動きません。平均・範囲・標準偏差は極端な値の影響を直接受けます。
問5 10人の顧客のうち1人が売上の76%を占めている。この1人を外れ値として削除する前に、最も重要な確認はどれか。
- ① 削除すると標準偏差が小さくなるか
- ② その値が本物の大口顧客か、入力ミスか
- ③ 削除すると平均が下がるか
- ④ ヒストグラムの色が見やすいか
解答と解説
正解:②
本物の大口顧客なら、事業上最も重要な情報です。削除は売上の実態を隠します。入力ミスなら訂正します。
問6 注文金額(円)に 3.2 という値が1件あり、他は2,000〜3,500円だった。最も疑うべき原因はどれか。
- ① 千円単位の値が円単位の列に混入した
- ② 本物の注文で、3.2円の商品がある
- ③ 標準偏差の計算ミス
- ④ ヒストグラムの階級幅が広すぎる
解答と解説
正解:①
他の値より3桁小さく、3.2千円=3,200円と読めば他の値と同じ水準です。単位の混在の典型例です。
次に学ぶこと
次は 層別と集計の罠 で、集団を分けて見る層別と、集計の仕方で結論が逆転する落とし穴(シンプソンのパラドックス)を学びます。戻るなら 代表値と散らばり で代表値と散らばりを復習します。
この授業の確認問題だけで習得とはしません。ST01 の総合テストと別データの自力課題で判定します。外れ値と欠損の品質チェックは 欠損・重複・異常・品質検証(有料版) で、頑健な統計は 再標本化・頑健な統計(有料版) で続きます。
キャリア学習:データサイエンティスト・機械学習エンジニア・DX推進・研究者を目指す人の学習アプリ。164モジュール・984授業を、ブラウザで動くSQLとPythonの演習で。基礎と各分野の最初のモジュールは無料。全部は2,980円の買い切り。
アプリを無料で開く有料版と無料版の違い