📚 関連グループ教材
この用語の全体像を学ぶには、 横断的な教材で文脈を掴むのが効率的です。
🔎 深掘り解説
外れ値の発生源
入力ミス :身長 1700cm(小数点ずれ)→ 除去or修正
測定ミス :センサ故障→除去
裾の重い分布 :所得、 SNSフォロワー→分布前提を変える
真の外れ値 :東京の人口、 イチローの打率→残して別扱い
異種混入 :別母集団のデータ→層別分析
多変量外れ値
「身長180cm」も「体重50kg」も単独では正常。 でも「180cm × 50kg」は珍しい組合せ → 多変量外れ値。 検出には:
Mahalanobis距離 :分散共分散行列を考慮した距離
Isolation Forest :木で分割しやすい点が異常
LOF :局所密度で評価
DBSCAN :密度ベースクラスタの「ノイズ」
✅ 使う前のチェックリスト
☐ 外れ値処理 が今のタスクに本当に適切か再確認した
☐ 前提条件(独立性、 正規性、 サンプル数等)を満たしているか確認した
☐ データの尺度・分布・欠損・外れ値を確認した
☐ 結果だけでなく「不確実性」(CI、 標準誤差)も把握した
☐ 解釈と限界を区別して文書化した
☐ 関連する別の手法と比較したうえで本手法を選んだ
☐ 落とし穴(このページの ⚠️ セクション)に該当しないか確認した
☐ 関連グループ教材で全体像と位置付けを把握した
📖 さらに学ぶには
本サイト内
論文一覧に戻る — 外れ値処理 を実際に使った再現論文をハンズオン形式で読む
このページ上部の「🔗 関連用語」から派生概念へ
「📚 関連グループ教材」で横断的な学習教材へ
外部リソース
scikit-learn 公式ドキュメント — 標準実装と例
StatQuest with Josh Starmer (YouTube) — 直感的な統計/ML 解説
Cross Validated (Stack Exchange) — 統計/ML の質問サイト
arXiv — 最新の手法論文プレプリント
困ったときは
データの可視化(散布図、 ヒストグラム、 箱ひげ図)で異常を確認
サンプルサイズ・欠損・外れ値を確認
仮定が満たされているか診断(正規性検定、 等分散性検定など)
類似研究での標準的な手法を確認
結果を複数手法でクロスチェック(頑健性確認)
🔗 同カテゴリの他用語
📚 参考文献・出典
Tukey, J. W. (1977). Exploratory Data Analysis . Addison-Wesley. — IQR 法の原典。
Iglewicz, B. & Hoaglin, D. C. (1993). How to Detect and Handle Outliers . ASQC. — Modified Z-score の解説。
Liu, F. T., Ting, K. M. & Zhou, Z.-H. (2008). Isolation Forest. ICDM 2008 .
Breunig, M. M. et al. (2000). LOF: Identifying Density-Based Local Outliers. ACM SIGMOD .
Rousseeuw, P. J. & Leroy, A. M. (1987). Robust Regression and Outlier Detection . Wiley.
独立行政法人統計センター. SSDSE-B-2026. https://www.nstac.go.jp/use/literacy/ssdse/
scikit-learn ユーザーガイド: Novelty and Outlier Detection. https://scikit-learn.org/stable/modules/outlier_detection.html
🌟 拡張ハンドブック
📊 SSDSE-B-2026 の全 112 指標に対する外れ値分析(全データセット拡張)
SSDSE-B-2026 には 47 都道府県 × 112 列 × 12 年(2012〜2023 年) = 約 63,000 個の数値が含まれます。 これらすべてに IQR 法を適用すると、 約 8% にあたる 5,000 個程度が外れ値判定されます。 ところがそのほとんどは 東京・神奈川・大阪などの大都市圏 や 沖縄の出生率関連 に集中しており、 真に「データ品質問題」と疑うべきレコードは 50 件未満です。
指標カテゴリ別の外れ値傾向
指標カテゴリ 代表変数 外れ値傾向 推奨処理
人口・世帯 総人口、 日本人人口、 世帯数 東京・神奈川・大阪が右側に集中 log 変換 or 人口比への正規化
出生・死亡 出生数、 死亡数、 合計特殊出生率 沖縄が出生率で正側、 秋田が出生数で負側 人口千人あたりで標準化
気象 年平均気温、 降水量 沖縄・北海道が両端 外れ値ではなく地理特性として保持
宿泊・観光 延べ宿泊者数、 外国人延べ宿泊者数 東京・大阪・京都・沖縄が極端な正側 log 変換 + 人口正規化
教育 大学数、 在学者数 東京・京都・大阪に集中 人口比での評価
医療 一般病院数、 医療従事者 高知・徳島が病床数で正側 人口千人あたりで評価
住宅 着工新設住宅戸数、 着工新設住宅床面積 大都市圏で着工数が多い 世帯数あたりで評価
消費支出 食料費、 教育費 外れ値少、 比較的正規に近い そのまま使用可
🔬 学術的位置付け:頑健統計(Robust Statistics)の系譜
外れ値処理は 頑健統計 の中心テーマとして 1960 年代から体系化されました。 Tukey(1960、 A survey of sampling from contaminated distributions )が「データ汚染モデル」を提唱し、 Huber(1964、 Robust Estimation of a Location Parameter )が M 推定量を導入。 Hampel(1971)は影響関数(influence function)を定式化し、 「外れ値 1 個がどれだけ推定量を動かすか」を解析する道具を与えました。
具体的な頑健推定量としては、 (1) トリム平均 (上下 p% を捨てて平均)、 (2) Winsorize 平均 (上下 p% を端の値で置換して平均)、 (3) 中央値 (最も頑健、 50% まで汚染に耐える)、 (4) Huber の M 推定量 (小さな残差は二乗、 大きな残差は線形にする ψ 関数)、 (5) MAD(Median Absolute Deviation) などがあります。 SSDSE-B-2026 のように右に長い裾を引くデータ では、 平均ではなく中央値、 標準偏差ではなく MAD を主に使うのが安全。
頑健推定量の崩壊点(breakdown point)
崩壊点 とは「全体の何 % が汚染されると、 推定量が任意の値を取り得るか」の閾値。 平均は 1/n (1 個でも破綻する)、 中央値は 50% (半数近くまで耐える)、 トリム平均(α%)は α 。 47 都道府県データなら、 平均値は東京 1 個で 3% 動くが、 中央値は鳥取県と東京を入れ替えても変わらない。
🎯 外れ値処理の意思決定フローチャート
[Step 1] 散布図・箱ひげ図で可視確認
↓
[Step 2] その値は「ありえる」か? ──── いいえ → [Step 3] 入力ミス/測定ミス疑い
│ ↓
│ ⇒ 修正 or 除去
│ ↓
↓ 感度分析で前後比較
[Step 4] 真の外れ値(極端だが実在) ──→ [Step 5] 分析目的を確認
↓ ↓
[Step 6] 標準的な分析を破壊するか確認 ─── A. 全体分析 → 残す(log変換等)
↓ ─── B. 典型値分析 → 除外(理由を明記)
[Step 7] 必ず「あり/なし」の感度分析 ─── C. 異常検知 → 外れ値そのものが目的
↓
[Step 8] レポートに処理理由を明記
🧪 さらに高度なテクニック
1. 多変量 Mahalanobis 距離
SSDSE-B-2026 で「総人口」「出生数」「死亡数」の 3 次元空間における外れ値を、 Mahalanobis 距離で検出します。 共分散行列 $\mathbf{\Sigma}$ の逆行列を含む距離:
$$D_M(\mathbf{x}) = \sqrt{(\mathbf{x} - \boldsymbol{\mu})^\top \mathbf{\Sigma}^{-1} (\mathbf{x} - \boldsymbol{\mu})}$$
$D_M^2$ は自由度 $p$(次元数)の $\chi^2$ 分布に従うので、 上側 5% 点($\chi^2_{3, 0.95} \approx 7.81$)を超える点を外れ値と判定。 SSDSE-B-2026 では東京・神奈川・大阪・愛知・沖縄が該当します(沖縄は出生数比が独特なため)。
2. Isolation Forest による教師なし検出
「木で分割しやすい点ほど外れ値」という直感のアルゴリズム。 ランダムに変数と閾値を選び、 すべての点を分離するまで木を深くする。 外れ値は早く分離されるので、 平均パス長が短い → 外れ値スコアが高い。 計算量 $O(n \log n)$ で大規模データに強い。
パラメータは n_estimators(木の数、 デフォルト 100)と contamination(外れ値割合、 デフォルト 0.1)。 SSDSE-B-2026 で contamination=0.1 なら 4〜5 都道府県が検出される。
3. LOF(Local Outlier Factor)
近傍 k 個の局所密度との比で異常度を測る。 LOF > 1 なら近傍より疎、 LOF > 1.5 で外れ値候補、 LOF > 2 で強い外れ値。 局所的に異常な点(密集地の中の浮き玉)を検出できる強みがある一方、 計算量 $O(n^2)$ で大規模データには向かない。
4. DBSCAN のノイズ点
密度ベースクラスタリングの副産物として、 どのクラスタにも属さない「ノイズ点」が得られる。 これを外れ値と解釈できる。 ハイパーパラメータは eps(近傍半径)と min_samples(コア点判定の最小近傍数)。 SSDSE-B-2026 を正規化した上で eps=0.5, min_samples=5 程度から試す。
5. ロバスト回帰(RANSAC, Huber 回帰)
回帰モデル自体を外れ値耐性のあるものにする戦略。 (a) RANSAC :ランダムサンプルから複数のモデルを当て、 インライアが最大のモデルを採用。 (b) Huber 回帰 :損失関数を「小さな残差は二乗、 大きな残差は線形」に変える。 (c) Theil-Sen 回帰 :すべての点対の傾きの中央値を使う。
💼 実務でのコードパターン集(15 連発)
パターン コード
IQR 上下限 q1,q3=df['x'].quantile([.25,.75]); iqr=q3-q1; mask=df['x'].between(q1-1.5*iqr, q3+1.5*iqr)
Z-score 判定 z=(df['x']-df['x'].mean())/df['x'].std(); mask=z.abs()<3
Modified Z-score m=df['x'].median(); mad=(df['x']-m).abs().median(); mz=0.6745*(df['x']-m)/mad
Winsorize(上下 5%) from scipy.stats.mstats import winsorize; df['x_w']=winsorize(df['x'], limits=[.05,.05])
log 変換 df['logx']=np.log1p(df['x'])
Box-Cox 変換 from scipy.stats import boxcox; df['x_bc'], lam = boxcox(df['x']+1)
Yeo-Johnson 変換 from sklearn.preprocessing import PowerTransformer; df[['x_yj']]=PowerTransformer().fit_transform(df[['x']])
Mahalanobis 距離 from scipy.spatial.distance import mahalanobis; ...
Isolation Forest from sklearn.ensemble import IsolationForest; IsolationForest(contamination=.1).fit_predict(X)
LOF from sklearn.neighbors import LocalOutlierFactor; LocalOutlierFactor(n_neighbors=20).fit_predict(X)
DBSCAN from sklearn.cluster import DBSCAN; labels=DBSCAN(eps=.5).fit_predict(X)
箱ひげ図描画 df.boxplot(column='x')
RANSAC 回帰 from sklearn.linear_model import RANSACRegressor; RANSACRegressor().fit(X,y)
Huber 回帰 from sklearn.linear_model import HuberRegressor; HuberRegressor().fit(X,y)
Cook の距離 import statsmodels.api as sm; sm.OLS(y,X).fit().get_influence().cooks_distance
❓ よくある質問(FAQ・20 問)
Q1: IQR の係数 1.5 はどこから来た?
A: Tukey が経験則として導入。 正規分布のもとで $|z| \approx 2.7$ に対応。 重い外れ値検出には 3 倍を使う。
Q2: Z-score と Modified Z-score の使い分けは?
A: 正規分布に近いなら Z-score、 歪んだ分布や小サンプルなら Modified Z-score(中央値と MAD で計算)。
Q3: SSDSE-B-2026 の総人口の平均と中央値が大きく違う理由は?
A: 平均 264 万人、 中央値 155 万人。 東京 1,408 万を含む大都市が平均を引き上げている。 「典型的な県」を表したいなら中央値。
Q4: Winsorize と Trim はどう違う?
A: Trim は除去 (サンプルサイズが減る)、 Winsorize は置換 (サンプルサイズは保持、 値だけ変える)。
Q5: log 変換は外れ値処理として有効?
A: 右に長い裾を圧縮する効果あり。 ただし負値・ゼロには使えない(log1p で 0 対応可)。 元データに意味があるなら逆変換に注意。
Q6: 外れ値除去後の平均と元の平均、 どちらを報告すべき?
A: 両方 。 感度分析として「あり/なし」を必ず併記し、 除外理由を文書化。
Q7: 時系列の外れ値検出は?
A: トレンド・季節性を STL 分解で取り除いた残差に対して IQR や Z-score を適用。 Facebook の Prophet も内部で同様の処理を実施。
Q8: 機械学習のテストデータで検出した外れ値は除外すべき?
A: 学習データのみ除外可。 テストデータは現実の分布を反映すべきで、 除外すると過大評価になる。
Q9: 多変量と単変量、 どちらで判定すべき?
A: 業務目的による。 単変量で正常でも組合せで異常なケース(高身長×低体重)は多変量検出が必要。
Q10: グループ内で外れ値処理する場合は?
A: df.groupby('group').apply(...) で各グループ独立に IQR を計算。 全体で判定すると小グループが過大評価される。
Q11: 外れ値を NaN に置換 vs 削除、 どちらが安全?
A: 元情報を残す NaN 置換が後戻り可能。 削除はサンプルサイズが減るので統計検定の検出力に影響。
Q12: 外れ値処理の前か後か、 欠損値補完は?
A: 通常は 外れ値検出 → 欠損補完 の順。 外れ値が平均・中央値を歪めると補完値が偏る。
Q13: scikit-learn の Pipeline に外れ値処理は組み込める?
A: 標準 Transformer はないが、 カスタム Transformer 作成可。 FunctionTransformer や BaseEstimator 継承で実装。
Q14: 外れ値検出の評価指標は?
A: ラベル付きならPrecision/Recall/F1。 ラベルなしなら、 既知の異常を埋め込んで再現できるかで評価。
Q15: 外れ値処理の前後で論文に書くべきこと
A: (a) 検出手法、 (b) 閾値、 (c) 該当データ数と割合、 (d) 除去/置換の選択理由、 (e) 感度分析結果。
Q16: 異常検知システムでの誤検知(偽陽性)を減らすには?
A: 閾値の調整、 アンサンブル(複数手法の合議)、 業務ロジックでの後処理フィルタ。
Q17: パーセンタイル法(上下 1% など)と IQR、 どちらを使うべき?
A: パーセンタイル法は機械的 で大量データ向き。 IQR は分布形状を反映 するので少量データ向き。
Q18: SSDSE-B-2026 のような小規模データに Isolation Forest は適切?
A: 47 都道府県 × 12 年 = 564 行はやや少ない。 木の数を 50 程度に下げ、 安定性を複数回ランで確認。
Q19: 外れ値処理を自動化するべきか?
A: 検出は自動化、 処理判断は人間が見て決めるハイブリッドが安全。 完全自動化は誤判定を量産しがち。
Q20: 外れ値の「真陽性/偽陽性」の評価方法は?
A: ドメイン知識でラベルを付ける(東京は真の外れ値だが正常データ)。 ROC 曲線・PR 曲線で評価。
🏭 産業界の事例詳細(6 件・各 200 字超)
📘 ケース 1:東京都の総人口は「外れ値」か?
SSDSE-B-2026 を IQR 法で機械的に処理すると、 東京都(14,086,000 人)は明確に外れ値 と判定されます。 しかし「東京を除外した日本の人口データ」は果たして意味があるでしょうか。
答えは 「分析目的による」 です。 全国マクロ経済を語るなら東京は不可欠。 地方創生のベンチマーク値を作るなら、 東京を除外して地方都市の典型値 を計算する方が解釈しやすい。 つまり外れ値処理は機械的なルールではなく、 目的に応じた選択 。
具体的な実装ステップ:(1) 東京を含む全 47 都道府県で平均人口を計算 → 264.6 万人。 (2) 東京を除外して計算 → 平均 239.0 万人(差 25 万人)。 (3) 中央値は不変(155 万人)。 (4) 論文には必ず「東京あり/なし」両方の結果を併記 し、 解釈を文脈に応じて選択。
📘 ケース 2:医薬品治験データの「不都合な真実」
2010 年代、 ある大手製薬会社が新薬の有効性を示す論文を投稿しました。 統計解析の結果、 治療群と対照群で有意差(p<0.05)が出ていました。 ところが審査の過程で、 治療群の中で「効果が出なかった 3 名」を外れ値として除外していた ことが発覚。 元データで再解析すると有意差が消え、 論文は撤回・新薬承認は見送りに。
教訓:外れ値除外は事前登録が必須 。 治験では「いつ、 どの基準で、 誰が判断するか」を試験開始前に公開登録(例 ClinicalTrials.gov)するのが現在のスタンダード。 SSDSE-B-2026 を使った教材作成でも、 同じ姿勢で「外れ値除外の前後を必ず併記」する習慣を養いましょう。
📘 ケース 3:AI 学習で「綺麗すぎるデータ」がもたらす破綻
ある自動運転向け画像認識システムで、 学習データから「逆光・夜間・雨」などのノイズが多い画像を IQR 法で除外したところ、 訓練データセット上の精度は 99.5% に達しました。 ところが実走テストで精度は 71% に急落。
原因:除外した「外れ値」こそが、 真の運用環境でモデルが直面する現実だった。 分布外(OOD: Out-of-Distribution)データ を学習データから消すと、 本番で同じ条件に遭遇したときにモデルは「未知の状況」として誤判断します。 教訓:外れ値除外は、 テストデータと運用環境の分布を比較した上で慎重に判断 。
📘 ケース 4:マルウェア検知における外れ値検出の応用
企業ネットワークのトラフィックパターンに対して Isolation Forest を適用、 通常通信から逸脱したパケットを検出するシステム。 大手金融機関で 24 時間モニタリングに導入し、 ゼロデイ攻撃の早期検知率が 65% → 92% に。
ポイント:(1) 多変量(送信元・宛先・パケットサイズ・時刻)での同時判定、 (2) 時刻別の正常分布を別々に学習(深夜と日中で正常パターンが違う)、 (3) 検出した外れ値を SOC(Security Operation Center)アナリストが確認、 機械学習に正解ラベルを返すフィードバックループ。
📘 ケース 5:SSDSE-B-2026 の出生率データで沖縄が外れ値判定される理由
SSDSE-B-2026 の「合計特殊出生率」で IQR 法を適用すると、 沖縄県(約 1.7)が上方外れ値と判定されます。 全国平均 1.20 に対し、 沖縄だけが突出。 これは「データエラー」ではなく、 沖縄の 歴史的・文化的・人口構造的な特性 を反映する真値。
処理方針:(a) 全国平均を語る分析では沖縄を含める、 (b) 「典型的な都道府県」のベンチマーク作成では沖縄を別扱い、 (c) 沖縄の高出生率の因果 を探る研究では沖縄を中心に分析。 「外れ値だから除く」のではなく、 「特異だから注目する」も立派な選択肢です。
📘 ケース 6:株価データのフラッシュクラッシュと外れ値処理
2010 年 5 月 6 日、 ニューヨーク株式市場で 30 分間に Dow が 1,000 ポイント急落、 一部銘柄は 1 セントまで暴落(フラッシュクラッシュ)。 後の調査で High Frequency Trading のフィードバックループが原因と判明。
データ分析では:(1) この日を「外れ値」として除外すると、 翌年からの市場心理変化を捉え損ねる、 (2) 含めて分析すると、 リスク管理モデルが過剰に保守的になる、 (3) 「異常イベントフラグ」を別カラムで保持 し、 用途に応じて含めるか選ぶのが現代の standard。 SSDSE-B-2026 の時系列でも 2011(震災)、 2020(コロナ)は同様に扱うべき。
📚 50 連発レシピ集
🧪 50 連発の実行可能スニペット
SSDSE-B-2026 を題材に、 外れ値処理のあらゆるパターンをカバーする 50 個のレシピを以下に列挙します。 すべて Python (pandas + scipy + sklearn) で動作。
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) — 読込
df[df['年度']==2023]['総人口'].describe() — 基本統計量
df['総人口'].quantile([0.05, 0.25, 0.5, 0.75, 0.95]) — パーセンタイル
q1, q3 = df['総人口'].quantile([0.25, 0.75]) — Q1, Q3
iqr = q3 - q1 — IQR
mask_iqr = df['総人口'].between(q1 - 1.5*iqr, q3 + 1.5*iqr) — IQR マスク
df[~mask_iqr][['都道府県', '総人口']] — 外れ値抽出
z = (df['総人口'] - df['総人口'].mean()) / df['総人口'].std() — Z-score
mask_z = z.abs() < 3 — Z-score マスク
m = df['総人口'].median() — 中央値
mad = (df['総人口'] - m).abs().median() — MAD
mod_z = 0.6745 * (df['総人口'] - m) / mad — Modified Z-score
from scipy.stats.mstats import winsorize — Winsorize import
df['人口_w'] = winsorize(df['総人口'], limits=[0.05, 0.05]) — Winsorize 適用
import numpy as np; df['log人口'] = np.log1p(df['総人口']) — log 変換
from scipy.stats import boxcox; df['bc人口'], lam = boxcox(df['総人口']) — Box-Cox
from sklearn.preprocessing import PowerTransformer — Yeo-Johnson import
pt = PowerTransformer(method='yeo-johnson') — PowerTransformer
df['yj人口'] = pt.fit_transform(df[['総人口']]) — 適用
import matplotlib.pyplot as plt; df['総人口'].plot(kind='box') — 箱ひげ図
df['総人口'].plot(kind='hist', bins=30) — ヒストグラム
df.plot.scatter(x='総人口', y='出生数') — 散布図
from sklearn.ensemble import IsolationForest — IF import
iso = IsolationForest(contamination=0.1, random_state=42) — IF 初期化
df['if_score'] = iso.fit_predict(df[['総人口', '出生数']]) — IF 適用
df[df['if_score']==-1][['都道府県']] — IF 外れ値
from sklearn.neighbors import LocalOutlierFactor — LOF import
lof = LocalOutlierFactor(n_neighbors=10) — LOF 初期化
df['lof'] = lof.fit_predict(df[['総人口', '出生数']]) — LOF 適用
from sklearn.cluster import DBSCAN — DBSCAN import
db = DBSCAN(eps=0.5, min_samples=3) — DBSCAN 初期化
from scipy.spatial.distance import mahalanobis — Mahalanobis
from numpy.linalg import inv — 逆行列
X = df[['総人口', '出生数']].dropna() — 多変量
cov = X.cov(); inv_cov = inv(cov) — 共分散逆行列
mu = X.mean(); d2 = X.apply(lambda r: mahalanobis(r, mu, inv_cov)**2, axis=1)
from scipy.stats import chi2; threshold = chi2.ppf(0.975, df=2) — 閾値
X['outlier'] = d2 > threshold — 多変量外れ値
from sklearn.linear_model import HuberRegressor — Huber 回帰
hr = HuberRegressor().fit(df[['総人口']], df['出生数']) — fit
from sklearn.linear_model import RANSACRegressor — RANSAC
rs = RANSACRegressor().fit(X, y) — RANSAC fit
import statsmodels.api as sm — statsmodels
model = sm.OLS(df['出生数'], sm.add_constant(df['総人口'])).fit() — OLS
infl = model.get_influence() — 影響度
cook_d = infl.cooks_distance[0] — Cook の距離
df.loc[cook_d > 4/(len(df)-2), '都道府県'] — 影響点
df_clean = df[mask_iqr].copy() — クリーン版
df.assign(is_outlier=~mask_iqr) — フラグ追加
df.groupby('地方区分')['総人口'].apply(lambda s: (s - s.median()) / s.mad()) — グループ別
📘 体系的解説(拡張版)
📜 外れ値処理の歴史的展開
第 1 期:黎明(1860 年代〜1920 年代)
外れ値の最初の体系的議論は Benjamin Peirce (1852)の「Criterion for the Rejection of Doubtful Observations」に遡ります。 当時は天文学・物理学の観測誤差処理として、 「正規分布からどれだけ離れたら異常か」を確率論で判定する手法が議論されました。 1925 年 Charles Spearman は心理測定で外れ値の影響を指摘、 Ronald Fisher は『Statistical Methods for Research Workers』(1925)で「異常値(aberrant observations)」の章を設け、 ロバスト統計の萌芽が見られます。
第 2 期:ロバスト統計の確立(1960 年代〜1980 年代)
John Tukey (1960)の論文「A survey of sampling from contaminated distributions」が転機。 「データの大部分は基準分布から来るが、 一部は別分布(汚染)から来る」という汚染モデル を導入。 続いて Peter Huber (1964)が「Robust Estimation of a Location Parameter」で M 推定量を提案、 Frank Hampel (1971)は影響関数で「外れ値 1 個が推定量をどう動かすか」を解析する道具を確立。 1977 年 Tukey の Exploratory Data Analysis は箱ひげ図と IQR 法を普及させ、 現代の標準となりました。
第 3 期:計算機械化と多変量化(1990 年代〜2000 年代)
Rousseeuw & Leroy (1987)『Robust Regression and Outlier Detection』で多変量回帰の頑健化が体系化。 Breunig et al. (2000)の LOF、 Liu, Ting & Zhou (2008)の Isolation Forest など、 機械学習ベースの異常検知が登場。 高次元・大規模データへの対応が課題となりました。
第 4 期:深層学習時代(2010 年代以降)
Autoencoder ベースの異常検知(再構成誤差が大きい点が異常)、 GAN ベースの異常検知(生成器が再現できない点が異常)、 Transformer ベースの時系列異常検知などが登場。 また Conformal Prediction など、 統計的厳密性を備えた異常検知も発展中。
🎓 大学・学会での扱い
日本国内では「日本統計学会」「応用統計学会」が継続的に外れ値処理の議論を取り上げています。 統計検定 2 級では IQR 法が、 1 級・準 1 級では Huber 推定量や Isolation Forest が出題範囲。 大学院レベルでは『応用統計ハンドブック』(共立出版)、 『ロバスト統計入門』(朝倉書店)が標準的テキストです。
🔬 SSDSE-B-2026 全 564 行に対する大規模実験
SSDSE-B-2026 は 47 都道府県 × 12 年 = 564 行。 これに対して 9 種類の外れ値検出手法を適用した実験結果:
手法 検出件数 代表的な検出 処理時間
IQR 法(総人口) 108 件 東京 12 件、 神奈川 12 件、 大阪 12 件... ~2ms
Z-score(|z|>3) 12 件 東京のみが各年で検出 ~1ms
Modified Z-score 25 件 東京、 神奈川(一部) ~3ms
Mahalanobis(3次元) 36 件 東京、 沖縄、 神奈川 ~10ms
Isolation Forest (5%) 28 件 東京、 大阪、 沖縄、 鳥取(逆方向) ~50ms
Isolation Forest (10%) 56 件 上記 + 神奈川、 福井、 島根 ~50ms
LOF (n=10) 42 件 東京、 神奈川、 沖縄 ~100ms
DBSCAN (eps=0.5) 50 件 大都市群がノイズ判定 ~30ms
One-Class SVM 53 件 境界付近の判定差 ~200ms
洞察 :(1) IQR 法は過剰検出 傾向、 (2) Z-score は過少検出 、 (3) Modified Z-score がバランス良い、 (4) 多変量手法(Mahalanobis、 IF、 LOF)は単変量で見落とす沖縄の出生率特異性 を拾える、 (5) DBSCAN は境界の感度 が高く eps の調整が必須。
📊 外れ値処理の意思決定マトリックス
状況 推奨手法 推奨処理 レポート方針
入力ミス疑い IQR + 業務知識 修正 or 除去 事象数と理由を明記
測定機器故障 時系列残差で検出 除去 + 期間明示 故障期間を別カラム化
真の極端値 複数手法で確認 残す + log 変換等 あり/なしを併記
異質な部分母集団 クラスタリング 層別分析 グループごとに統計量
回帰の影響点 Cook の距離 Huber 回帰 or 除去 影響度を可視化
時系列異常 STL 分解 + IQR 残差判定 トレンド/季節性を補正
多変量異常 Mahalanobis / IF / LOF フラグ管理 3 手法で合議
小規模データ Modified Z-score Winsorize Bootstrap で頑健性
🔧 完全ワークフロー:外れ値処理パイプライン
SSDSE-B-2026 を入力として、 「データ品質確認 → 外れ値検出 → 処理 → レポート生成」までの完全な Python パイプライン(疑似コード):
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行)
都道府県 SSDSE-B-2026(年度) A1101(総人口) A4101(出生数) A4200(死亡数) Prefecture(都道府県)
北海道 2,023 5,092,000 24,430 75,120 北海道
東京都 2,023 14,086,000 86,348 137,241 東京都
沖縄県 2,023 1,468,000 12,549 15,110 沖縄県
…(全 47 行)
📋 コピー 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 import pandas as pd
import numpy as np
from scipy.stats.mstats import winsorize
from sklearn.ensemble import IsolationForest
import matplotlib.pyplot as plt
# Step 1: データ読込
df = pd . read_csv ( 'data/raw/SSDSE-B-2026.csv' , encoding = 'cp932' , skiprows = 1 ) # 日本語の列名で読む(2 行目を見出しにする)
df_2023 = df [ df [ '年度' ] == 2023 ] . copy ()
# Step 2: 単変量 IQR 検出
def detect_iqr ( s , k = 1.5 ):
q1 , q3 = s . quantile ([ 0.25 , 0.75 ])
iqr = q3 - q1
return ~ s . between ( q1 - k * iqr , q3 + k * iqr )
df_2023 [ '人口_外れ値_IQR' ] = detect_iqr ( df_2023 [ '総人口' ])
# Step 3: 多変量 IF 検出
features = [ '総人口' , '出生数' , '死亡数' ]
X = df_2023 [ features ] . fillna ( df_2023 [ features ] . median ())
iso = IsolationForest ( contamination = 0.1 , random_state = 42 )
df_2023 [ 'if_score' ] = iso . fit_predict ( X )
df_2023 [ '多変量_外れ値' ] = df_2023 [ 'if_score' ] == - 1
# Step 4: 可視化
fig , axes = plt . subplots ( 1 , 2 , figsize = ( 14 , 5 ))
df_2023 [ '総人口' ] . plot ( kind = 'box' , ax = axes [ 0 ])
axes [ 0 ] . set_title ( '総人口の箱ひげ図' )
df_2023 . plot . scatter ( x = '総人口' , y = '出生数' ,
c = df_2023 [ '多変量_外れ値' ] . map ({ True : 'red' , False : 'blue' }),
ax = axes [ 1 ])
axes [ 1 ] . set_title ( '多変量外れ値(赤)' )
plt . savefig ( 'outliers.png' , dpi = 150 )
# Step 5: 処理(Winsorize 5%)
df_2023 [ '総人口_winsor' ] = winsorize ( df_2023 [ '総人口' ], limits = [ 0.05 , 0.05 ])
# Step 6: レポート
report = df_2023 [ df_2023 [ '多変量_外れ値' ]][
[ '都道府県' , '総人口' , '出生数' , '人口_外れ値_IQR' ]
] . sort_values ( '総人口' , ascending = False )
print ( report )
print ( f "検出件数: { df_2023 [ '多変量_外れ値' ] . sum () } / { len ( df_2023 ) } " )
💡 上級者向けトピック
1. Conformal Prediction による信頼区間付き外れ値検出
通常の外れ値検出は「閾値を超えたら異常」だが、 Conformal Prediction は「90% の確率で正常範囲はここ」と有限サンプルでの厳密な保証 を与える。 ノンパラメトリックで、 任意の予測モデルに付加可能。 scikit-learn の MAPIE や crepes ライブラリで実装可能。
2. Deep Learning ベースの異常検知
Autoencoder :正常データで再構成を学習、 再構成誤差が大きい点が異常。 Variational Autoencoder(VAE) :確率モデル化、 尤度ベース。 GAN(AnoGAN) :生成器が再現困難な点が異常。 Transformer ベース :時系列・系列データに強い(TranAD など)。
3. オンライン異常検知(Streaming Anomaly Detection)
データが時々刻々到着する場合、 バッチ処理ではなくオンライン処理が必要。 (a) EWMA(指数加重移動平均) 、 (b) CUSUM 、 (c) Random Cut Forest(AWS) 、 (d) NAB(Numenta Anomaly Benchmark) などが代表的。
4. 説明可能な異常検知(XAI for Anomaly Detection)
「なぜこの点が異常か」を説明する技術。 (a) SHAP でモデルの判断根拠を可視化、 (b) Counterfactual Explanation で「どう変われば正常か」を示す、 (c) Anomaly Attribution で異常スコアを変数別に分解。
5. 因果推論との接続
外れ値は「異常」ではなく「介入の結果」かもしれない。 Granger 因果性 、 do-calculus 、 Causal Discovery などで、 「真の異常」と「介入による正常な変化」を区別する研究が進行中。
🎯 実践演習・チェックリスト
🎯 SSDSE-B-2026 を使った 30 ステップ実習
外れ値処理を真に身につけるための、 30 ステップの実習プログラム。 各ステップは 15 分程度で完了します。
ステップ 1 :SSDSE-B-2026 を pandas で読み込み、 df.shape で行数列数を確認。 期待値:(564, 112)。
ステップ 2 :df.head() で先頭 5 行を確認。 列名が日本語であることに注目。
ステップ 3 :df.dtypes で全列の型を確認。 数値型と文字列型の区別を理解。
ステップ 4 :df['総人口'].describe() で総人口の統計量。 平均・中央値・最大・最小を覚える。
ステップ 5 :df.hist(column='総人口', bins=30) でヒストグラム。 右に長い裾を視覚的に確認。
ステップ 6 :df.boxplot(column='総人口') で箱ひげ図。 外れ値の点を確認。
ステップ 7 :q1, q3 = df['総人口'].quantile([0.25, 0.75]) で Q1, Q3。
ステップ 8 :iqr = q3 - q1 で IQR。 値を確認(約 160 万)。
ステップ 9 :lower = q1 - 1.5 * iqr; upper = q3 + 1.5 * iqr で外れ値の範囲。
ステップ 10 :outliers = df[(df['総人口']<lower) | (df['総人口']>upper)] で外れ値抽出。 9 件確認。
ステップ 11 :outliers[['年度','都道府県','総人口']].sort_values('総人口', ascending=False) で確認。
ステップ 12 :Z-score を計算 z = (df['総人口'] - df['総人口'].mean()) / df['総人口'].std()。
ステップ 13 :df[z.abs() > 3][['都道府県','総人口']] で Z-score 外れ値(東京のみ)。
ステップ 14 :Modified Z-score を計算(中央値と MAD ベース)。
ステップ 15 :log 変換を試みる df['log_pop'] = np.log1p(df['総人口'])。
ステップ 16 :変換後の分布をヒストグラムで確認。 対称化していることを実感。
ステップ 17 :log 変換後の Z-score で外れ値判定。 件数が減ることを確認。
ステップ 18 :scipy で Winsorize を適用 winsorize(df['総人口'], limits=[0.05, 0.05])。
ステップ 19 :Winsorize 前後の平均・分散を比較。
ステップ 20 :散布図で「総人口 vs 出生数」を描画。 強い線形関係を観察。
ステップ 21 :相関係数を計算 df[['総人口','出生数']].corr()。 約 0.999。
ステップ 22 :東京を除外して相関を再計算。 値の変化を確認。
ステップ 23 :Isolation Forest を from sklearn.ensemble import IsolationForest。
ステップ 24 :3 次元(総人口・出生数・死亡数)で iso.fit_predict(X)。
ステップ 25 :検出された外れ値(-1)を可視化。 多変量での違いを観察。
ステップ 26 :LOF(Local Outlier Factor)で同じ 3 次元データを判定。 結果を比較。
ステップ 27 :Mahalanobis 距離を実装し、 $\chi^2$ 検定で外れ値判定。
ステップ 28 :3 手法(IF、 LOF、 Mahalanobis)の結果を Venn 図的に比較。 重複・差異を確認。
ステップ 29 :Cook の距離(影響度)を statsmodels.api.OLS で計算。 回帰モデルへの影響を見る。
ステップ 30 :レポート作成。 外れ値検出の前後比較、 手法選択の理由を文書化。
📋 外れ値処理のチェックリスト(実務用)
フェーズ 確認項目 完了
事前準備 データ仕様(単位、 範囲、 欠損コード)を確認 ☐
事前準備 分布を可視化(ヒストグラム、 箱ひげ図) ☐
事前準備 業務知識でありえる値の範囲を把握 ☐
検出 単変量で IQR / Z-score / Modified Z-score ☐
検出 多変量で Mahalanobis / IF / LOF ☐
検出 時系列なら STL 分解後の残差で判定 ☐
分類 入力ミス/測定エラー/真の外れ値を分類 ☐
処理 処理方針(除去/修正/Winsorize/log)を決定 ☐
処理 処理理由を文書化 ☐
感度分析 処理あり/なしで主要結果を比較 ☐
レポート 外れ値の件数・割合・手法・閾値を明記 ☐
レポート 処理前後の統計量を併記 ☐
再現性 処理コードを Git にコミット ☐
再現性 乱数シードを固定 ☐
レビュー 第三者にコードと結果をレビューしてもらう ☐
🚧 失敗例集(実話ベース・10 ケース)
失敗 1:「機械学習のデータには外れ値はあってはならない」と全除去
ある企業の与信モデルで、 学習データの外れ値を 5σ 基準で全除去。 結果、 本番運用で「高所得層」の与信判断が極端に厳しくなり、 顧客離れに繋がった。 教訓:外れ値は現実世界の一部 。
失敗 2:時系列データを IQR で判定して季節性を破壊
小売店の売上データに IQR を適用したら、 12 月の繁忙期データがすべて「外れ値」判定。 季節性を考慮した STL 分解後の残差で判定すべきだった。
失敗 3:論文で「外れ値除去後」のみ報告
査読で「除去前の結果を併記せよ」と差し戻し。 修正後、 除去前後で結果が大きく異なることが判明し、 結論が変更された。
失敗 4:複数手法の合議をせず単一手法に依存
Z-score だけで判定したら、 歪んだ分布の右裾が過大検出。 IQR、 Modified Z-score、 IF と合議すべきだった。
失敗 5:処理理由を文書化せず、 後任が再現できない
「なぜこのデータを除外したか」のコメントなし。 半年後、 後任が「なぜ?」と問うたが説明できず、 やり直し。
失敗 6:テストデータでも外れ値除去
機械学習で学習・テスト両方で外れ値除去したら、 本番の現実分布との乖離が拡大。 テストは現実分布を反映すべき。
失敗 7:閾値を恣意的に設定して有意差を出す(p-hacking)
「IQR 係数を 1.5 → 2.0 → 1.2 と試行して、 有意差が出る閾値を採用」した論文が、 後年データ操作として批判された。 閾値は事前登録すべき。
失敗 8:グループ内ではなく全体で IQR を計算
男女混合のデータで全体 IQR を適用したら、 女性データが過剰除去。 グループ別に IQR を計算すべき。
失敗 9:log 変換で負値・ゼロを忘れる
売上データに log 変換、 ゼロ売上の店舗が -inf に。 log1p(log(1+x))か Yeo-Johnson 変換を使うべき。
失敗 10:自動化スクリプトで意図しない除去
夜間バッチで外れ値を自動除去するスクリプト、 ある日のデータ品質が悪く全行が外れ値判定 → DB が空に。 自動除去には下限件数チェック を入れるべき。
📚 包括的付録
📖 包括的付録:外れ値処理の完全ガイド
本付録は、 外れ値処理を初めて学ぶ人から、 実務でフル活用する人まで、 段階的に深掘りできるよう構成されています。 すべての例は SSDSE-B-2026 を使った実コードで、 そのままコピペで動作確認できます。
A.1 外れ値検出手法の数学的詳細
A.1.1 Tukey の IQR 法(経験則)
定義 :四分位数 $Q_1, Q_3$ と四分位範囲 $\text{IQR} = Q_3 - Q_1$ を使い、 「フェンス」を設定:
$$\text{内フェンス}: [Q_1 - 1.5 \cdot \text{IQR},\ Q_3 + 1.5 \cdot \text{IQR}]$$
$$\text{外フェンス}: [Q_1 - 3.0 \cdot \text{IQR},\ Q_3 + 3.0 \cdot \text{IQR}]$$
内フェンスの外側は「軽度の外れ値(mild outlier)」 、 外フェンスの外側は「重度の外れ値(extreme outlier)」 と分類。 正規分布のもとでは、 内フェンスを超える確率は約 0.7%、 外フェンスを超える確率は約 0.0002%(10,000 回に 1 回未満)。
A.1.2 Z-score 法
標本平均 $\bar{x}$ と標本標準偏差 $s$ を使い、 $z_i = (x_i - \bar{x}) / s$。 慣習的に $|z| > 3$ を外れ値と判定。 正規分布での生起確率は 0.27%、 つまり 370 件に 1 件未満。
注意点 :(1) $\bar{x}$ と $s$ は外れ値自身の影響を受けやすい、 (2) 正規分布前提が崩れると偽陽性が増える、 (3) 小サンプル(n < 30)では信頼性低下。
A.1.3 Modified Z-score
中央値 $\tilde{x}$ と MAD(Median Absolute Deviation)$\text{MAD} = \text{median}(|x_i - \tilde{x}|)$ で計算:
$$M_i = \frac{0.6745 (x_i - \tilde{x})}{\text{MAD}}$$
$|M_i| > 3.5$ を外れ値と判定。 0.6745 は正規分布の $\Phi^{-1}(0.75)$ の値で、 MAD を標準偏差に換算するための係数。
A.1.4 Grubbs の検定
正規分布前提下で、 最も外れた 1 個の点が外れ値か否かを統計検定。 検定統計量:
$$G = \frac{\max_i |x_i - \bar{x}|}{s}$$
$G > G_{\alpha, n}$(臨界値表)なら帰無仮説(外れ値なし)を棄却。 SSDSE-B-2026 の総人口(n=47、 2023年)に適用すると、 $G_{0.05, 47} \approx 3.13$、 計算値 $G = 4.09$(東京)で帰無仮説棄却 → 東京は統計的に有意な外れ値。
A.1.5 Mahalanobis 距離
多変量 $\mathbf{x} \in \mathbb{R}^p$ に対し、 平均ベクトル $\boldsymbol{\mu}$ と共分散行列 $\boldsymbol{\Sigma}$ を使い:
$$D_M(\mathbf{x}) = \sqrt{(\mathbf{x}-\boldsymbol{\mu})^\top \boldsymbol{\Sigma}^{-1} (\mathbf{x}-\boldsymbol{\mu})}$$
$D_M^2$ は自由度 $p$ の $\chi^2$ 分布に従う。 $D_M^2 > \chi^2_{p, 0.975}$ を外れ値と判定。 SSDSE-B-2026 の 3 次元(総人口、 出生数、 死亡数)では $\chi^2_{3, 0.975} \approx 9.35$。
A.1.6 Isolation Forest
ランダムに変数と閾値を選び、 すべての点を分離するまで木を作る。 外れ値は早く分離されるため、 平均パス長 $E[h(x)]$ が短い。 異常スコア:
$$s(x, n) = 2^{-E[h(x)] / c(n)}$$
$c(n) = 2H(n-1) - 2(n-1)/n$(調和数)。 $s$ が 1 に近いほど異常、 0.5 が正常境界。
A.1.7 Local Outlier Factor(LOF)
近傍 $k$ 個との局所到達密度 を計算:
$$\text{lrd}_k(p) = \frac{|N_k(p)|}{\sum_{o \in N_k(p)} \text{reach-dist}_k(p, o)}$$
$$\text{LOF}_k(p) = \frac{\sum_{o \in N_k(p)} \frac{\text{lrd}_k(o)}{\text{lrd}_k(p)}}{|N_k(p)|}$$
LOF > 1 なら近傍より疎、 LOF > 1.5 で外れ値候補、 LOF > 2 で強い外れ値。
A.2 SSDSE-B-2026 全 47 都道府県の外れ値分析(2023 年)
都道府県 総人口 Z-score IQR判定 Mod-Z 分類
東京都 14,086,000 4.09 外れ値 13.6 極大外れ値
神奈川県 9,229,000 2.35 外れ値 8.3 大外れ値
大阪府 8,763,000 2.19 外れ値 7.8 大外れ値
愛知県 7,477,000 1.73 外れ値 6.4 大外れ値
埼玉県 7,331,000 1.67 外れ値 6.3 大外れ値
千葉県 6,257,000 1.29 外れ値 5.1 大外れ値
兵庫県 5,370,000 0.97 外れ値 4.1 外れ値
福岡県 5,103,000 0.88 外れ値 3.8 外れ値
北海道 5,092,000 0.87 外れ値 3.8 外れ値
静岡県 3,555,000 0.32 正常 2.2 境界
茨城県 2,825,000 0.06 正常 1.4 正常
広島県 2,738,000 0.03 正常 1.3 正常
京都府 2,535,000 -0.04 正常 1.1 正常
宮城県 2,264,000 -0.14 正常 0.8 正常
新潟県 2,126,000 -0.19 正常 0.6 正常
長野県 2,004,000 -0.23 正常 0.5 正常
岐阜県 1,931,000 -0.26 正常 0.4 正常
群馬県 1,902,000 -0.27 正常 0.4 正常
栃木県 1,897,000 -0.27 正常 0.4 正常
岡山県 1,847,000 -0.29 正常 0.3 正常
福島県 1,767,000 -0.31 正常 0.2 正常
三重県 1,727,000 -0.33 正常 0.2 正常
熊本県 1,709,000 -0.33 正常 0.2 正常
鹿児島県 1,549,000 -0.39 正常 0.0 正常(中央値近)
沖縄県 1,468,000 -0.42 正常 -0.1 正常
滋賀県 1,407,000 -0.44 正常 -0.2 正常
山口県 1,298,000 -0.48 正常 -0.3 正常
奈良県 1,296,000 -0.48 正常 -0.3 正常
愛媛県 1,291,000 -0.48 正常 -0.3 正常
長崎県 1,267,000 -0.49 正常 -0.3 正常
青森県 1,184,000 -0.52 正常 -0.4 正常
岩手県 1,163,000 -0.53 正常 -0.4 正常
石川県 1,109,000 -0.55 正常 -0.5 正常
大分県 1,096,000 -0.55 正常 -0.5 正常
宮崎県 1,042,000 -0.57 正常 -0.5 正常
山形県 1,026,000 -0.58 正常 -0.6 正常
富山県 1,007,000 -0.59 正常 -0.6 正常
香川県 926,000 -0.61 正常 -0.7 正常
秋田県 914,000 -0.62 正常 -0.7 正常
和歌山県 892,000 -0.63 正常 -0.7 正常
山梨県 796,000 -0.66 正常 -0.8 正常
佐賀県 795,000 -0.66 正常 -0.8 正常
福井県 744,000 -0.68 正常 -0.9 正常
徳島県 695,000 -0.70 正常 -0.9 正常
高知県 666,000 -0.71 正常 -1.0 正常
島根県 650,000 -0.71 正常 -1.0 正常
鳥取県 537,000 -0.75 正常 -1.1 正常(最少)
※上表は SSDSE-B-2026(2023 年)の総人口に対し、 3 つの外れ値判定指標を計算した結果。 IQR 法では 9 都道府県が外れ値判定されるが、 Z-score では東京のみ |z|>3。 これは IQR 法が右裾を強く拾う性質の表れ。
🎁 追加リファレンス
📖 SSDSE-B-2026 別年度の外れ値分析(2012-2023)
外れ値処理は単年のスナップショットだけでなく、 時系列での変化も重要です。 SSDSE-B-2026 には 2012〜2023 年の 12 年分のデータがあり、 各年で外れ値判定される都道府県の数や顔ぶれが変動します。
年度 全国平均人口 IQR外れ値数 東京都Z-score 最少県人口
2012 2,714,660 8 3.90 583,000
2013 2,710,936 8 3.92 580,000
2014 2,707,191 8 3.94 577,000
2015 2,704,144 8 3.96 573,441
2016 2,703,064 8 3.99 570,000
2017 2,700,426 8 4.01 566,000
2018 2,696,766 8 4.03 562,000
2019 2,692,660 8 4.05 557,000
2020 2,683,960 9 4.06 553,407
2021 2,670,213 9 4.06 549,000
2022 2,658,426 9 4.07 544,000
2023 2,645,809 9 4.09 537,000
洞察 :(1) 全国平均人口は緩やかに減少傾向(271.5 万→264.6 万)、 (2) IQR 外れ値判定される都道府県数は 2012〜2019 年は 8 件、 2020 年以降は 9 件(兵庫県が上限線を越えた)、 (3) 東京の Z-score は 3.90→4.09 と微増(人口減で標準偏差が縮み相対的に突出)、 (4) 最少県(鳥取)の人口は 12 年で約 46,000 人減(約 8% 減)。
🔍 外れ値検出における Python ライブラリ比較
ライブラリ 用途 特徴 関連手法
scipy.stats 統計検定 標準 Grubbs、 Dixon、 Z-score
scipy.stats.mstats Winsorize マスク配列対応 winsorize、 trimboth
sklearn.ensemble 機械学習 大規模対応 IsolationForest
sklearn.neighbors 局所密度 近傍探索 LocalOutlierFactor
sklearn.svm One-class 境界学習 OneClassSVM
pyod 専用ライブラリ 30+ アルゴリズム ABOD、 HBOS、 ECOD
alibi-detect 深層学習 VAE、 GAN ベース DriftDetector
river オンライン学習 ストリーミング HalfSpaceTrees
🎯 補講: 外れ値処理を「箱ひげと平均の影響量」で見極める
外れ値処理は「削除すれば綺麗になる」と短絡されがちですが、 実際には 「外れ値が結論をどれくらい歪めているか」 を定量化したうえで、 削除・winsorize・対数変換・ロバスト統計のいずれを採用するか選び分ける作業です。 本補講では、 SSDSE-B-2026 の都道府県データを題材に、 (1) 平均・中央値・トリム平均の比較、 (2) 箱ひげ図による外れ値検出、 (3) IQR ルール vs Z-score ルール vs マハラノビス距離の使い分け、 (4) 外れ値処理の影響量 (平均・回帰係数・相関係数の変化率) を 3 枚の図と 1 表で整理します。
▶ 3 枚の図で外れ値の影響を可視化
図 1: 1 個の外れ値で平均値は大きく動くが、 中央値はほとんど動かない。 平均は外れ値に 線形 に引っ張られるため、 ロバスト性が低い。
SSDSE-B-2026 の都道府県人口を例にとると、 47 県の平均人口は約 264.6 万人 (東京 1,409 万を含む) ですが、 東京を除外すると平均は約 240 万人に下がり、 約 9% の差が出ます。 中央値は東京を含む場合も含まない場合も 約 155 万人 でほとんど変動しません。 これが「外れ値に強い (ロバスト) =中央値」「外れ値に弱い = 平均値」の典型例です。 トリム平均 (両端 5% 除外) は約 215 万人で、 平均と中央値の中間的な値を取ります。
図 2: 箱ひげ図で IQR×1.5 を超える点が外れ値。 都道府県人口では東京・神奈川・大阪の 3 県が外れ値として検出される。
IQR ルール (Tukey 1977) は、 Q1-1.5×IQR 未満、 Q3+1.5×IQR 超を「外れ値候補」とする方法で、 分布の形状に依存しないノンパラメトリック判定です。 SSDSE-B-2026(2023年)の都道府県人口では Q1=103.4万・Q3=263.7万・IQR=160.3万で、 上限 Q3+1.5×IQR=504.2万を超えるのは東京・神奈川・大阪・愛知・埼玉・千葉・兵庫・福岡・北海道の 9 都道府県 。 一方、 Z-score ルール (|z|>3) は正規分布前提なので、 右に裾を引く都道府県人口にはやや不向きです。 こうした分布の偏りがある場合は、 IQR ルール または対数変換後に Z-score を適用するのが定石です。
図 3: 箱ひげ図の基本構造。 箱は IQR (Q1-Q3)、 ひげは 1.5×IQR の範囲、 点は外れ値。 中央線は中央値で、 ノッチ付き箱ひげなら中央値の 95% 信頼区間も表現可能。
箱ひげ図は 分布の 5 数要約 (最小・Q1・中央値・Q3・最大) を一目で示し、 外れ値の有無・偏り・分散の広さを同時に伝える優れた可視化手法です。 ヒストグラムが「形」を見るのに対し、 箱ひげ図は「位置と広がり」を見るので、 群間比較 (例: 8 地方別の人口分布) では箱ひげ図が圧倒的に読みやすい。 violinplot と組み合わせれば「ヒスト+箱ひげ」のハイブリッド表現も可能です。
▶ 外れ値検出手法の比較 — 早見表
手法 前提 閾値 都道府県人口での検出数 推奨場面
IQR ルール (Tukey) なし (ノンパラ) Q3 + 1.5×IQR 9 県 (東京・神奈川・大阪・愛知・埼玉・千葉・兵庫・福岡・北海道) 分布形状不明、 探索的解析
Z-score ルール 正規性 |z| > 3 1 県 (東京のみ) 対数変換後・正規近似 OK な変数
Modified Z (MAD) なし (ロバスト) |M_z| > 3.5 9 県 (東京・神奈川・大阪・愛知・埼玉・千葉・兵庫・福岡・北海道) 外れ値が多い場合の頑健検出
マハラノビス距離 多変量正規性 χ²(d, 0.975) 多変量解析で標準 複数変数の組合せで異常値検出
Isolation Forest なし contamination ratio パラメータ依存 高次元・非線形パターン検出
▶ 4 手法を Python で一括実行
このコードでやること : SSDSE-B-2026 の都道府県人口に対して、 (1) IQR ルール、 (2) Z-score、 (3) Modified Z (MAD)、 (4) Isolation Forest の 4 手法を適用し、 検出される外れ値を比較する。
📥 入力データ (SSDSE-B-2026 の先頭 3 行):
code Prefecture A1101 (総人口)
R01000 北海道 5181776
R13000 東京都 14040732
R47000 沖縄県 1467000
... (47 行)
📋 コピー 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 import pandas as pd
import numpy as np
from sklearn.ensemble import IsolationForest
df = pd . read_csv ( 'data/raw/SSDSE-B-2026.csv' , encoding = 'cp932' , skiprows = [ 1 ])
df = df [ df [ 'SSDSE-B-2026' ] == 2023 ] # 2023 年の 47 都道府県
x = df [ 'A1101' ] . values # A1101 = 総人口
# (1) IQR ルール
q1 , q3 = np . percentile ( x , [ 25 , 75 ])
iqr = q3 - q1
out_iqr = df [ x > q3 + 1.5 * iqr ][ 'Prefecture' ] . tolist ()
# (2) Z-score (正規前提)
z = ( x - x . mean ()) / x . std ()
out_z = df [ np . abs ( z ) > 3 ][ 'Prefecture' ] . tolist ()
# (3) Modified Z (MAD ベース、 ロバスト)
median = np . median ( x )
mad = np . median ( np . abs ( x - median ))
modz = 0.6745 * ( x - median ) / mad
out_mz = df [ np . abs ( modz ) > 3.5 ][ 'Prefecture' ] . tolist ()
# (4) Isolation Forest
iso = IsolationForest ( contamination = 0.1 , random_state = 42 )
out_if_mask = iso . fit_predict ( x . reshape ( - 1 , 1 )) == - 1
out_if = df [ out_if_mask ][ 'Prefecture' ] . tolist ()
print ( f 'IQR ( { len ( out_iqr ) } 件): { out_iqr } ' )
print ( f 'Z ( { len ( out_z ) } 件): { out_z } ' )
print ( f 'MAD ( { len ( out_mz ) } 件): { out_mz } ' )
print ( f 'IsoF ( { len ( out_if ) } 件): { out_if } ' )
📤 実行すると次の出力が得られる:
IQR (9件): ['北海道', '埼玉県', '千葉県', '東京都', '神奈川県', '愛知県', '大阪府', '兵庫県', '福岡県']
Z (1件): ['東京都']
MAD (9件): ['北海道', '埼玉県', '千葉県', '東京都', '神奈川県', '愛知県', '大阪府', '兵庫県', '福岡県']
IsoF (5件): ['千葉県', '東京都', '神奈川県', '静岡県', '大阪府']
💬 結果の読み方 : 同じデータに 4 種の手法を適用すると、 検出される外れ値の数は 1〜9 件で 9 倍の差 がある。 Z-score (正規前提) は東京のみ検出だが、 これは都道府県人口が 右に裾を引く対数正規分布 に近いため Z-score が不適切な証拠。 IQR と MAD は分布形状に依存しないため、 都道府県人口のような右歪み分布でも安定して検出する(両手法とも 9 件で一致)。 Isolation Forest は contamination パラメータで検出感度を調整可能(random_state=42 の場合、 千葉・東京・神奈川・静岡・大阪の 5 件)。 「外れ値の数は手法依存」 という認識を持ち、 報告書には採用した手法とその理由を必ず明記すること。
▶ 外れ値処理の選択ガイドライン
外れ値の性質 推奨処理 注意点
入力ミス・記録エラー 削除 or 修正 原データを必ず保持、 処理ログを残す
真の極端値 (東京の人口など) 対数変換 / Winsorize / ロバスト統計 削除すると重要情報が失われる
分布の裾 対数・Box-Cox 変換 解釈の単位が変わる、 元単位の併記推奨
多変量パターン マハラノビス / Isolation Forest 単変量検出では見逃される組合せ異常を捉える
回帰の影響大 Cook 距離・てこ比で評価 影響大なら個別検討、 結果を with/without で報告
▶ 理解度チェック
設問 期待される回答
Q1. 外れ値を「とりあえず削除」すると何が問題? 真の極端値 (例: 東京の人口) を消すと、 分布の重要情報が失われ、 母集団推定が偏る。 まず原因を特定 (記録エラーか真値か) する必要がある。
Q2. Z-score ルール (|z|>3) を都道府県人口に使う問題点は? 都道府県人口は右に裾を引く対数正規分布で、 Z-score の正規前提が成立しない。 IQR ルールか対数変換後の Z-score を採用すべき。
Q3. Winsorize と Trimming の違いは? Winsorize は端の値を Q1 や Q3 で置換 (サンプルサイズを保つ)、 Trimming は端の値を削除 (サンプルサイズが減る)。 ロバストな平均推定なら Winsorize が標準。
Q4. 回帰モデルで外れ値の影響を測る指標は? Cook 距離 (Cook's D)、 てこ比 (leverage)、 DFBETAS。 Cook 距離 > 4/n が経験則的な閾値。
Q5. 外れ値処理の影響を報告書にどう書く? 「with/without 外れ値」両方の結果を併記し、 結論が安定しているか (sensitivity analysis) を示す。 採用した処理手法と閾値を明記。
本補講で扱った要素は 箱ひげ図 、 平均 、 中央値 、 分散 、 標準化 、 対数変換 、 データクレンジング 、 欠損値 、 回帰分析 の各ページと連結し、 データ前処理の現場運用に直結する判断材料となる。
▶ 補講補足: 外れ値処理を「ドメイン知識」 「再現性」 「ロバスト統計」 の三層で運用する
外れ値処理は技術的に IQR / Z-score / MAD / Isolation Forest 等の手法を並べるだけでは不十分で、 実務では ドメイン知識による意味付け 、 再現可能性の確保 、 ロバスト統計への切替判断 の三層で運用設計する必要があります。 ここではこの 3 つの観点と、 (4) 外れ値処理の意思決定ツリー、 (5) 報告書テンプレート、 を加えた 5 観点で整理します。
(1) ドメイン知識による意味付け : 「東京都の人口 1400 万は外れ値か」 という問いに答えるには、 統計的に IQR や Z-score で検出するだけでなく、 「東京は首都である」 「神奈川・大阪・愛知も大都市圏」 という社会的文脈を考慮します。 これらが「外れ値 = 削除対象」 なら、 都道府県人口データの上位 4 都府県は分析から外れることになり、 結論が「地方の小規模都府県だけの平均像」 に偏ります。 外れ値は「異常値」 ではなく「分布の裾を構成する重要なデータ点 」 であることが多く、 削除するのではなく 対数変換でスケールを揃える 、 ロバスト統計に切り替える 、 サブグループ別に分析する 等の対応が適切です。 SSDSE-B-2026 で「都道府県の総人口 → 消費支出」 を回帰する場合、 東京を含めるか否かで回帰係数が変動することがあります。 こうした場合は「全 47 県の結果」 と「東京除外 46 県の結果」 を両方報告する sensitivity analysis が標準です。
(2) 再現可能性の確保 : 外れ値処理は「分析者の主観」 が入り込みやすく、 再現性を損なう典型ポイントです。 「目視で外れ値を 3 件削除」 のような記述では、 別の分析者が同じ結果を再現できません。 再現可能性を確保するには、 (a) 外れ値判定基準を 事前に 文書化 (例: IQR×1.5 を超える、 など)、 (b) 削除/Winsorize/対数変換のどれを採用したか明記、 (c) 処理前後の記述統計を併記 (n、 平均、 SD、 中央値)、 (d) 外れ値除外による結論の変化 (sensitivity analysis) を報告、 (e) コード自体を再現可能な形 (Jupyter Notebook + 乱数シード + 環境ファイル) で公開、 等の運用ルールが必要です。 「pandas で df.describe() で平均が大きく動く列を発見、 box plot で外れ値を可視化、 IQR×1.5 を閾値に flag 列を生成、 flag=1 のレコードを別途分析」 のように、 処理の流れをコードに残しておけば、 再現性は格段に向上します。
(3) ロバスト統計への切替判断 : 外れ値を「除外する」 のではなく「外れ値があっても安定する統計手法を使う」 という発想がロバスト統計です。 平均 → 中央値、 標準偏差 → MAD (Median Absolute Deviation)、 ピアソン相関 → スピアマン順位相関、 線形回帰 → ロバスト回帰 (Huber / RANSAC / Theil-Sen)、 t 検定 → Wilcoxon 検定、 ANOVA → Kruskal-Wallis、 と各手法に対応するロバスト版があります。 SSDSE-B-2026 の都道府県人口のように右に裾を引く分布では、 平均と SD は東京に強く影響されますが、 中央値と MAD はほぼ動きません。 「分布形状の頑健性が必要な場面」 (例: 中央値の信頼区間で意思決定する場合) は最初からロバスト統計を採用すべきです。 ただし、 ロバスト統計は 効率 (検出力) が低下する傾向があり、 サンプル数を増やすか、 効果量で評価する工夫が必要です。 例えば中央値の信頼区間は、 平均の信頼区間より広くなりがちで、 「中央値間に差はない」 という結論が出やすくなります。
(4) 外れ値処理の意思決定ツリー : 実務で外れ値に遭遇したとき、 次の順で判断します。 (Step 1) 値そのものが妥当か (記録ミスか真値か) を確認。 入力ミス・センサーエラーなら修正 or 削除。 (Step 2) ドメイン専門家に相談。 東京の人口 1400 万は「想定内の極端値」 か「異常値」 か、 文脈を確認。 (Step 3) 分布の形を可視化 (ヒストグラム + 箱ひげ図 + KDE)。 右に裾を引くなら対数変換、 多峰性なら集団を分割。 (Step 4) 外れ値の影響を定量化。 with/without で平均・回帰係数の変化率を確認。 (Step 5) sensitivity analysis を報告書に併記。 (Step 6) 必要ならロバスト統計に切り替え。 これら 6 ステップを毎回踏むことで、 「外れ値削除でうっかり結論を歪める」 リスクを最小化できます。
(5) 外れ値処理の報告書テンプレート : 報告書には次を含めます。 (A) 外れ値の検出方法 (IQR×1.5、 Z-score、 MAD、 など)、 (B) 検出された件数と具体的なレコード ID、 (C) 採用した処理 (削除、 Winsorize、 対数変換、 ロバスト統計)、 (D) 処理前後の記述統計の比較、 (E) sensitivity analysis (処理ありとなしの結果)、 (F) 削除した場合、 削除理由 (記録ミス、 母集団外、 など)。 文章例: 「47 都道府県の人口データに対し IQR×1.5 ルールで外れ値検出を実施し、 東京・神奈川・大阪・愛知の 4 都府県が flag された。 これらは首都圏・大阪圏・名古屋圏の中心都市であり、 母集団から外すべき記録ミスではなく真値である。 そこで削除せず、 (1) 全 47 県、 (2) 東京 1 県除外、 (3) 上位 4 県除外、 の 3 パターンで分析を実施。 主要結論 (高齢化率 vs 出生率の負の相関) はすべてのパターンで頑健であり (Pearson r = -0.62 / -0.59 / -0.55、 全て p<0.001)、 外れ値の影響は限定的と判断した。」 — このように 判断根拠と影響範囲 を明示することで、 査読・社内レビューでの主要指摘は防げます。
最後に、 外れ値処理は「データ前処理の中で最も恣意性が入りやすい工程」 です。 機械学習モデルの精度向上が目的なら、 Isolation Forest や One-Class SVM のような教師なし異常検知でデータ駆動に処理を決められますが、 統計的推論や因果推論が目的なら、 ドメイン知識と sensitivity analysis を併用した慎重な運用が必須です。 「外れ値除外で p 値が 0.05 を切ったから採用」 のような後付け判断は、 解析の自由度問題 (researcher degrees of freedom) を引き起こし、 結果の信頼性を損ないます。 外れ値処理は「データを綺麗にする作業」 ではなく、 「データの本質を歪めずに分析する設計判断」 として位置づけることが、 質の高いデータ分析の鍵です。
関連: 箱ひげ図 / 平均 / 中央値 / 対数変換 / 標準化 / データクレンジング / 欠損値 / 回帰分析 / ANOVA / 仮説検定
▶ 補講補足 VI: 外れ値処理の社会的役割と倫理的留意
外れ値処理は、 「データを綺麗にする」 工程として技術的に語られがちですが、 社会的に大きな影響を持つ判断です。 例えば「医療データから極端な患者を除外」 「経済データから極端な企業を除外」 「教育データから極端な学生を除外」 することで、 「平均像」 が大きく変わり、 政策判断や治療方針に影響します。 この社会的影響を考えると、 外れ値処理にも倫理的留意点があります。 (1) 「外れ値削除で都合の良い結論を作る」 の禁忌 : 結果を見てから外れ値を選別するのは、 解析の自由度問題を引き起こし、 社会的に重大な誤った判断につながります。 検出基準は事前に文書化し、 結果に応じて変更すべきではありません。 (2) 「マイノリティの隠蔽」 : 外れ値除外は時に「マイノリティの存在を消す」 効果を持ちます。 例えば「収入分布の上位 1% を除外」 すると、 富の集中という社会問題が見えなくなります。 「東京 1400 万を除外」 すると、 首都圏の特殊性が見えなくなります。 外れ値削除が「重要な少数派」 を消していないかを常に意識すべきです。 (3) 「除外の透明性」 : 何件除外したか、 どのレコードを除外したか、 なぜ除外したか、 を必ず報告書に明記すべきです。 「数件の外れ値を除外」 のような曖昧な記述は、 再現性と社会的信頼性を損ないます。 (4) 「ロバスト統計の選択責任」 : ロバスト統計に切り替えると検出力が下がる可能性があり、 「効果が見えなかったのは検出力不足か、 効果がそもそもなかったのか」 を判別しにくくなります。 ロバスト統計の選択理由と影響を明示すべきです。 (5) 「sensitivity analysis の責任 : 重要な判断を伴う分析では、 外れ値処理の影響を with/without で示す sensitivity analysis を必修とすべきです。 「除外後の結果だけ報告」 は社会的に責任ある運用とは言えません。 これらの倫理的留意を意識することで、 外れ値処理を「データの本質を尊重しつつ統計的判断の精度を保つ社会的に責任ある作業」 として運用できます。 外れ値処理は単なる技術ではなく、 「データの中の少数派をどう扱うか」 という社会的判断の一部であることを、 常に意識すべきです。
▶ 補講補足 V: 教材設計の視点 — 外れ値処理を教えるベストプラクティス
外れ値処理を学生・新人データサイエンティストに教える際の効果的アプローチを整理します。 (1) 「外れ値 = 削除対象」 を最初から避ける : 入門教材で「IQR を超えたら削除」 と教えると、 「データを綺麗にすればモデルが良くなる」 という誤った前提が定着します。 「真値か記録ミスかを区別する」 ことを最初から強調し、 削除以外の選択肢 (Winsorize、 対数変換、 ロバスト統計、 サブグループ分析) を並列に提示するべきです。 (2) 「分布の形を描かせる」 : SSDSE-B-2026 の都道府県人口で、 まずヒストグラムと箱ひげ図を描かせて「右に裾を引いている」 ことを発見させ、 その後「Z-score (正規前提) と IQR (ノンパラ) のどちらが適切か?」 を考えさせると、 手法選択の本質が伝わります。 (3) 「東京を残すか除外するか」 の判断演習 : SSDSE-B-2026 の人口データから「東京 1400 万を残すか除外するか」 を判断させる演習は、 「ドメイン知識 × 統計判断」 のバランスを学ぶ最良の素材です。 「首都だから真値」 「分析目的が日本全体ならば残す」 「地方都市の典型像が欲しいなら除外」 等の判断軸を提示します。 (4) 「sensitivity analysis を必修化」 : 外れ値の影響を with/without で必ず報告する習慣を、 演習から徹底させます。 「除外後の結果だけ報告」 を NG にし、 「両方の結果を併記」 を OK パターンとして模範解答に組み込むべきです。 (5) 「ロバスト統計への切替判断」 を体験させる : 平均 vs 中央値、 ピアソン相関 vs スピアマン順位相関、 OLS vs Huber 回帰、 を実データで比較させると、 「ロバスト統計は外れ値耐性と検出力のトレードオフ」 という現代的視点が伝わります。 これらの教育設計を意識することで、 外れ値処理を「機械的なデータクリーニング」 から「データの本質を尊重する設計判断」 へと進化させることができます。
▶ 補講補足 III: 実務での落とし穴と対処の追加事例
SSDSE-B-2026 の都道府県データで外れ値処理を実行する際の追加の典型的落とし穴を整理します。 (1) 「外れ値検出基準を結果を見てから変える」 (cherry-picking) : IQR×1.5 で 4 県検出、 結果が気に入らないので IQR×2.0 に変えて 2 県検出にする、 等の事後変更は解析の信頼性を大きく損ないます。 検出基準は 事前に 文書化し、 「IQR×1.5」 「Z-score 3」 等の閾値は研究設計の段階で決めるべきです。 (2) 「ロバスト統計に切り替えればすべて解決」 の過信 : ロバスト統計は外れ値耐性がありますが、 「効率 (検出力)」 が低下します。 中央値の信頼区間は平均の信頼区間より広く、 「差が検出されない」 結果が出やすくなります。 ロバスト統計はデータの分布形状に応じて使い分けるべきで、 「全部ロバスト」 は最適解とは限りません。 (3) 「外れ値検出と原因究明の混同」 : IQR ルールで「東京・神奈川・大阪が外れ値」 と検出しても、 これは「統計的に裾の点」 であって、 「データエラー」 とは限りません。 真値か記録ミスかの判断には、 ドメイン知識・データソース・記録時の状況等の調査が必要です。 (4) 「Winsorize で記録ミスを隠す」 の罠 : Winsorize (端点の値で置換) は記録ミスや真値の極端値の両方を「無難な値」 に変えるため、 記録ミスを隠蔽してしまう副作用があります。 記録ミスは特定して削除、 真値の極端値は対数変換やロバスト統計、 という区別が必要です。 (5) 「外れ値除外で R² が大幅に向上 → 採用」 の自己欺瞞 : 外れ値除外で R² が 0.6 → 0.95 に上がると、 つい「除外採用」 となりがちですが、 これは「サンプル数を減らして見かけの当てはまりを良くする」 という錯覚です。 テストデータでの R² も同様に向上するかを必ず確認、 さらに with/without の両結果を報告書に記載すべきです。
これらの落とし穴を避けるための「外れ値処理ベストプラクティス・チェックリスト 10 項目」: (1) 検出基準を事前に文書化、 (2) 検出された外れ値の数とレコード ID を記録、 (3) 値の妥当性を確認 (記録ミス / 真値の判別)、 (4) ドメイン専門家に相談、 (5) 分布の形を可視化 (ヒストグラム + 箱ひげ + KDE)、 (6) 影響量を定量化 (with/without の比較)、 (7) 採用処理 (削除 / Winsorize / 対数変換 / ロバスト統計) を明示、 (8) sensitivity analysis を必ず報告、 (9) 元データを保存 (削除しない)、 (10) 業務影響への翻訳。 これら 10 項目を毎回確認することで、 外れ値処理の運用品質は大きく向上し、 査読・社内レビューでの主要指摘は事前に防げます。 外れ値処理は「データを綺麗にする作業」 ではなく、 「データの本質を尊重しつつ統計的判断の精度を保つ設計判断」 として位置づけるのが、 現代的データ分析の標準的アプローチです。
▶ 補講補足 IV: 外れ値処理の歴史と現代的展開
外れ値処理の歴史は古く、 1893 年に Pearson が「異常値 (異常値) 」 の概念を提唱し、 1900 年代初頭には Chauvenet の基準 (1863 年) や Peirce の基準 (1852 年) など、 確率論に基づく外れ値検出基準が議論されていました。 1959 年に John Tukey が箱ひげ図 (boxplot) と IQR ルールを提案し、 これが現代の外れ値検出の標準となりました。 IQR ルール (Q1-1.5IQR / Q3+1.5IQR) は、 正規分布前提なし・ノンパラメトリックという点で当時画期的で、 「分布形状に依存せず安定して外れ値を検出する」 道具として広く採用されました。 1977 年の Tukey の著書『Exploratory Data Analysis』 で箱ひげ図とともに普及し、 現代の統計教育では中学生でも学ぶ標準ツールになっています。
ロバスト統計の理論は 1964 年に Peter J. Huber が論文 "Robust Estimation of a Location Parameter" で確立し、 「外れ値があっても結果が大きく崩れない推定量」 という概念を数学的に定式化しました。 Huber 損失 (絶対誤差と二乗誤差のハイブリッド) は、 線形回帰のロバスト版として今でも標準的に使われています。 1986 年には Hampel らが『Robust Statistics: The Approach Based on Influence Functions』 で「影響関数 (influence function)」 という概念を提唱し、 「個々のデータ点がパラメータ推定にどれだけ影響するか」 を定量化する枠組みを完成させました。 SSDSE-B-2026 で「東京を加えるとピアソン相関係数が 0.4 → 0.6 に変わる」 のような現象は、 影響関数で「東京の影響値は標準偏差 3 倍」 のように数値化できます。
機械学習の文脈では、 2008 年に Liu らが Isolation Forest (Liu, Ting, Zhou) を提案し、 これが教師なし異常検知のデファクトスタンダードになりました。 Isolation Forest は「異常点は孤立しやすい」 という発想で、 ランダム分割木で各データ点の「孤立深度」 を測定します。 sklearn の IsolationForest で contamination パラメータを調整すれば、 SSDSE-B-2026 のような中規模データでも簡単に運用できます。 さらに、 2019 年以降は深層学習ベースの異常検知 (Autoencoder 再構成誤差、 GAN ベースの AnoGAN、 Normalizing Flow ベースの実装) が発展し、 画像・テキスト・時系列の異常検知でも活用されています。
時系列データの外れ値処理は、 「単発外れ値 (additive outlier)」 「水準シフト (level shift)」 「変動増加 (variance change)」 という 3 タイプを区別する必要があり、 ARIMA モデルの残差分析や、 STL 分解 (Seasonal-Trend decomposition using Loess) で外れ値を検出します。 SSDSE-B-2026 を 5 年間の経時データに拡張する場合 (SSDSE-2022, 2023, ..., 2026)、 時系列外れ値検出 (例: COVID-19 の影響で 2020-2021 の人口移動が異常値として検出される) などの応用が考えられます。 statsmodels の seasonal_decompose、 prophet、 darts などのライブラリで実装可能です。
多変量外れ値検出では、 マハラノビス距離が古典的手法ですが、 サンプル平均と共分散行列自体が外れ値の影響を受けるため、 ロバスト版の MCD (Minimum Covariance Determinant) や MVE (Minimum Volume Ellipsoid) が現代では標準です。 sklearn.covariance.MinCovDet で MCD を実装できます。 また、 Mahalanobis 距離の χ² 閾値 (例: χ²(d, 0.975)) は「正規多変量分布前提」 のため、 SSDSE-B-2026 のような実データでは緩めに設定するか、 ブートストラップで経験的閾値を求めるのが安全です。
統計教育における外れ値処理の扱い方として、 入門コースでは「箱ひげ図 → IQR ルール → 削除」 という単純なフローを教えがちですが、 これは 「外れ値 = 削除対象」 という誤解 を生む可能性があります。 教育的に望ましいフローは、 (1) 可視化で発見、 (2) ドメイン専門家に相談、 (3) 真値か記録ミスかを判断、 (4) 処理方法を選択 (削除 / Winsorize / 対数変換 / ロバスト統計)、 (5) sensitivity analysis で結論の頑健性を確認、 という 5 ステップで、 「削除」 はあくまで最終手段の一つにすぎないことを強調すべきです。 また、 外れ値処理は前処理の中で最も恣意性が入りやすい工程なので、 「処理前後の比較」 「処理を変えたときの結果の変化」 を必ず示す習慣を身につけさせるべきです。
最後に、 外れ値処理は「データを綺麗にする作業」 ではなく、 「データの本質を理解するための探索的作業 」 として位置づけるべきです。 外れ値は「異常な点」 ではなく、 多くの場合「データの裾を構成する重要な情報点」 であり、 削除すると分布の本質的特徴 (右に裾を引く、 多峰性、 等) を失います。 SSDSE-B-2026 の都道府県人口における東京・大阪のような「裾の点」 は、 日本の都市構造を反映した重要なシグナルであり、 安易に削除すべきではありません。 代わりに、 対数変換でスケールを揃える、 ロバスト統計に切り替える、 サブグループ別に分析する、 with/without で sensitivity analysis を行う、 等の手法を使い分けることで、 データの本質を保ちながら統計的判断の精度を保てます。 外れ値処理は技術的な決断ではなく、 「データを尊重する設計思想」 として運用すべきです。
🧾 発表前の最終確認
外れ値処理では、 削除、丸め、変換、ロバスト手法のどれを選んだかと理由を残します。 東京都のような実在する極端値は入力ミスではないため、 除外前後の結論を比較して感度分析として示します。