外れ値と頑健性|記述統計と標本

このページはプロモーション(広告)を含みます。

記述統計と標本(中級・読む25分+演習35分)

この授業のゴール

仕事でどう使うか

外れ値は『消すべき邪魔者』ではなく、『確認すべき情報』です。入力ミスなら直す、本物の大口なら残す、別の集団なら分けて扱う。この判断が、集計結果の信頼性を決めます。

路線 この授業の使いどころ
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つあります。

  1. 入力ミス:12.0万円と入力すべきところを、小数点を落として120にした。
  2. 本物の極端な値:貸し切りの大型イベントがあり、実際に120万円売れた。
  3. 別の集団:普段の店舗売上ではなく、ネット通販の売上が混入した。

原因によって、取る行動は全く違います。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$ を外れ値の目安とすることがあります。ただし次の弱点があります。

頑健な指標:

指標 内容 外れ値への強さ
中央値 並べた真ん中の値 強い
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))

出力は次のとおりです。

指標 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つの値で自由に動かせることを意味します。

試してみましょう。

  1. base の値を1つ増やして 10 個にして、last を 120 にすると、平均への影響は小さくなるでしょうか。データ数が増えるほど、1件の影響は小さくなります。
  2. last を -1000 にしても、中央値は動きません。下側の極端な値でも同じ性質です。
  3. 係数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円低く出て、報告が誤ります。集計前の単位確認(単位と桁と丸め)が抜けています。

直し方:境界の外にある値を見つけたら、削除する前に『単位・桁』を疑う。元データの定義を確認して訂正し、訂正した件数と内容を記録する。

まとめ

用語

外れ値(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である。このことから導かれる注意点はどれか。

  1. ① z得点が3を超えれば、必ず外れ値である
  2. ② 少数のデータでは、どんなに極端な値でも |z|>3 にならず、外れ値を見逃す
  3. ③ z得点は外れ値の判定に使ってはならない
  4. ④ n が大きいほど |z| の最大値は小さくなる
解答と解説

正解:②

標本サイズ n では |z| の最大値が (n−1)/√n に制限されます。n=9 なら約2.67で、3には届きません。

問2 IQRルールで外れ値候補が見つかった。最初に取るべき行動はどれか。

  1. ① 原因(入力ミス・本物の極端な値・別集団)を確認する
  2. ② ただちに削除する
  3. ③ 平均で置き換える
  4. ④ 何もせず、そのまま報告する
解答と解説

正解:①

外れ値は誤りとは限りません。原因によって訂正・保持・分離を決めます。削除は最後の手段で、理由と件数を記録します。

問3 9日間の売上 8, 9, 9, 10, 11, 11, 12, 13, 120(万円)で、IQRルールの上側境界はいくつか(Q1=9、Q3=12)。

  1. ① 13
  2. ② 15
  3. ③ 16.5
  4. ④ 18
解答と解説

正解:③

IQR=12−9=3。上側境界は Q3+1.5×IQR=12+4.5=16.5 です。

問4 外れ値を含むデータの代表値として、一般に最も影響を受けにくいものはどれか。

  1. ① 平均
  2. ② 範囲(最大−最小)
  3. ③ 標準偏差
  4. ④ 中央値
解答と解説

正解:④

中央値は順位の真ん中の値で、端の値が大きく変わっても動きません。平均・範囲・標準偏差は極端な値の影響を直接受けます。

問5 10人の顧客のうち1人が売上の76%を占めている。この1人を外れ値として削除する前に、最も重要な確認はどれか。

  1. ① 削除すると標準偏差が小さくなるか
  2. ② その値が本物の大口顧客か、入力ミスか
  3. ③ 削除すると平均が下がるか
  4. ④ ヒストグラムの色が見やすいか
解答と解説

正解:②

本物の大口顧客なら、事業上最も重要な情報です。削除は売上の実態を隠します。入力ミスなら訂正します。

問6 注文金額(円)に 3.2 という値が1件あり、他は2,000〜3,500円だった。最も疑うべき原因はどれか。

  1. ① 千円単位の値が円単位の列に混入した
  2. ② 本物の注文で、3.2円の商品がある
  3. ③ 標準偏差の計算ミス
  4. ④ ヒストグラムの階級幅が広すぎる
解答と解説

正解:①

他の値より3桁小さく、3.2千円=3,200円と読めば他の値と同じ水準です。単位の混在の典型例です。

次に学ぶこと

次は 層別と集計の罠 で、集団を分けて見る層別と、集計の仕方で結論が逆転する落とし穴(シンプソンのパラドックス)を学びます。戻るなら 代表値と散らばり で代表値と散らばりを復習します。

この授業の確認問題だけで習得とはしません。ST01 の総合テストと別データの自力課題で判定します。外れ値と欠損の品質チェックは 欠損・重複・異常・品質検証(有料版) で、頑健な統計は 再標本化・頑健な統計(有料版) で続きます。

キャリア学習:データサイエンティスト・機械学習エンジニア・DX推進・研究者を目指す人の学習アプリ。164モジュール・984授業を、ブラウザで動くSQLとPythonの演習で。基礎と各分野の最初のモジュールは無料。全部は2,980円の買い切り。

アプリを無料で開く有料版と無料版の違い