活用テクニック2026年4月8日

外れ値検出の完全ガイド — IQR・Isolation Forest・アンサンブル手法で異常値を見極める

データに含まれる外れ値はモデル精度を大きく左右します。IQR 法から Isolation Forest、アンサンブル外れ値検出まで、代表的な手法の原理と使い分け、そして除去 vs 保持の判断基準を体系的に解説します。

Qast の外れ値検出レポート。複数手法の比較結果が表示されている。

外れ値(Outlier)とは、他のデータポイントから大きく外れた異常な値のことです。外れ値が存在すると、平均値や標準偏差が歪み、回帰モデルの係数が過度にその値に引っ張られ、予測精度が低下します。一方で、外れ値がビジネス上重要なシグナル(不正取引、機器の異常など)を示している場合もあります。この記事では、外れ値を検出する代表的な手法とその使い分け、そして「除去すべきか、保持すべきか」の判断基準を詳しく解説します。

外れ値の種類 — 単変量外れ値と多変量外れ値

外れ値には大きく分けて 2 つの種類があります。単変量外れ値は、1 つの変数のみを見たときに異常な値です。例えば、年齢が 200 歳や、身長が 300cm といった値です。多変量外れ値は、個々の変数としては正常でも、変数の組み合わせで見ると異常なデータポイントです。例えば、「年齢 5 歳で年収 1000 万円」は、年齢も年収も単独では正常な範囲ですが、組み合わせとしては異常です。多変量外れ値の検出には、IQR やZ スコアのような単変量手法では不十分で、Isolation Forest や LOF のような手法が必要になります。

IQR 法 — シンプルで信頼性の高い統計的手法

IQR 法(四分位範囲法)は、最も広く使われている外れ値検出手法の一つです。第 1 四分位数(Q1, 25%点)と第 3 四分位数(Q3, 75%点)の差である IQR を計算し、Q1 - 1.5 × IQR より小さい値、または Q3 + 1.5 × IQR より大きい値を外れ値と判定します。この手法の長所は、平均や標準偏差に依存しないため外れ値自体の影響を受けにくいことです。箱ひげ図のヒゲの範囲がまさに IQR 法の外れ値判定基準です。

python
import pandas as pd
import numpy as np

def detect_outliers_iqr(series, multiplier=1.5):
    """IQR 法で外れ値を検出する。"""
    Q1 = series.quantile(0.25)
    Q3 = series.quantile(0.75)
    IQR = Q3 - Q1
    lower_bound = Q1 - multiplier * IQR
    upper_bound = Q3 + multiplier * IQR

    outliers = series[(series < lower_bound) | (series > upper_bound)]
    print(f"Q1={Q1:.2f}, Q3={Q3:.2f}, IQR={IQR:.2f}")
    print(f"許容範囲: [{lower_bound:.2f}, {upper_bound:.2f}]")
    print(f"外れ値の数: {len(outliers)} / {len(series)} ({len(outliers)/len(series)*100:.1f}%)")
    return outliers

# 使用例
df = pd.read_csv("dataset.csv")
outliers = detect_outliers_iqr(df["annual_income"])

Z スコア法 — 正規分布を仮定した検出

Z スコア法は、各データポイントが平均からどれだけ離れているかを標準偏差の倍数で表し、その絶対値が閾値(通常 3)を超える値を外れ値と判定します。正規分布を仮定しているため、データが正規分布に近い場合に有効です。ただし、平均と標準偏差は外れ値の影響を受けやすいため、外れ値の割合が高いデータでは正しく機能しない場合があります。その場合は、中央値と MAD(中央絶対偏差)を使った修正Zスコア(Modified Z-score)が頑健な代替手法になります。

Z スコア法の閾値は 3 が一般的ですが、これは「正規分布の 99.7% 信頼区間」に相当します。より保守的に 2.5 を使うこともあります。閾値の選択はデータのドメインに依存するため、一律に決めず、ヒストグラムで分布を確認してから判断しましょう。

Isolation Forest — 機械学習ベースの外れ値検出

Isolation Forest は、2008 年に Liu らが提案した、機械学習ベースの外れ値検出アルゴリズムです。基本的なアイデアは「外れ値は通常のデータよりも少ない分割で孤立(isolate)できる」というものです。ランダムに特徴量と分割値を選んで二分木を構築し、データポイントが孤立するまでの平均パス長(木の深さ)を計算します。外れ値は少ない分割で孤立するため、パス長が短くなります。多変量外れ値の検出に優れ、高次元データでも効率的に動作します。

  1. 1

    ランダムな分割による二分木の構築

    各ノードでランダムに 1 つの特徴量を選び、その特徴量の値域からランダムに分割値を選んで、データを左右に分岐させます。これを再帰的に繰り返し、各データポイントが孤立するか、木の深さの上限に達するまで続けます。

  2. 2

    パス長の計算

    各データポイントについて、ルートノードから孤立するまでのパス長(ノード数)を計算します。外れ値は正常データよりもパス長が短くなります。複数の木を構築し、パス長の平均を取ります。

  3. 3

    異常スコアの算出

    パス長を正規化して 0〜1 の異常スコアに変換します。スコアが 1 に近いほど外れ値の可能性が高く、0.5 以下なら正常と判断されます。contamination パラメーターで外れ値の想定割合を指定できます。

python
from sklearn.ensemble import IsolationForest
import pandas as pd
import numpy as np

# Isolation Forest による多変量外れ値検出
X = df.select_dtypes(include=["number"]).dropna()

iso_forest = IsolationForest(
    n_estimators=200,
    contamination=0.05,  # 外れ値の想定割合 5%
    random_state=42,
)
predictions = iso_forest.fit_predict(X)
scores = iso_forest.decision_function(X)

# -1 が外れ値、1 が正常
outlier_mask = predictions == -1
print(f"検出された外れ値: {outlier_mask.sum()} / {len(X)} ({outlier_mask.mean()*100:.1f}%)")

# 異常スコアの分布
print(f"正常データのスコア(平均): {scores[~outlier_mask].mean():.4f}")
print(f"外れ値のスコア(平均):     {scores[outlier_mask].mean():.4f}")

LOF(Local Outlier Factor)— 局所密度に基づく検出

LOF(Local Outlier Factor)は、各データポイントの周辺密度を近傍のデータポイントの密度と比較することで、外れ値を検出する手法です。Isolation Forest との違いは、LOF が「局所的な密度」に注目する点です。密度の高いクラスターと密度の低いクラスターが混在するデータでは、LOF の方が適切に外れ値を検出できます。例えば、都市部の人口密度が高い地点群と農村部の低い地点群がある場合、LOF は各地域の基準で外れ値を判定できます。

アンサンブル外れ値検出 — 複数手法の統合

単一の手法だけでは外れ値の検出精度に限界があります。IQR 法は多変量外れ値を検出できず、Isolation Forest は局所密度の違いに弱く、LOF は高次元データでパフォーマンスが低下します。アンサンブル外れ値検出は、複数の手法で検出結果を統合することで、各手法の弱点を補い合い、より信頼性の高い検出を実現します。

  1. 1

    多数決方式

    複数の手法(IQR、Z スコア、Isolation Forest、LOF)でそれぞれ外れ値判定を行い、過半数以上の手法で外れ値と判定されたデータポイントのみを最終的な外れ値とします。偽陽性を減らす効果があります。

  2. 2

    スコア平均方式

    各手法の異常スコアを 0〜1 に正規化して平均し、閾値を超えたポイントを外れ値とします。各手法のスコアを連続値として活用するため、多数決方式よりも柔軟な判定が可能です。

  3. 3

    段階的フィルタリング

    まず IQR 法で明らかな単変量外れ値を検出し、次に Isolation Forest で多変量外れ値を検出するという段階的なアプローチです。検出の解釈がしやすく、どの手法で検出されたかのトレーサビリティが確保できます。

外れ値検出ではドメイン知識が極めて重要です。統計的に外れ値と判定されたデータが、ビジネス上は正常な値(高額商品の売上、VIP 顧客の利用頻度など)であるケースは珍しくありません。自動検出の結果を機械的に除外するのではなく、必ずビジネスの文脈で確認しましょう。

外れ値の影響分析 — 除去前後の比較

外れ値を検出したら、次のステップは「その外れ値がモデルにどの程度影響しているか」を定量的に評価することです。影響分析では、外れ値を含むデータと除去したデータの両方でモデルを学習し、精度を比較します。外れ値除去後に精度が向上すればノイズであった可能性が高く、精度が低下すれば外れ値が重要な情報を含んでいた可能性があります。

python
from sklearn.ensemble import IsolationForest, GradientBoostingRegressor
from sklearn.model_selection import cross_val_score
from sklearn.neighbors import LocalOutlierFactor
import numpy as np

def analyze_outlier_impact(X, y, outlier_mask):
    """外れ値の除去がモデル精度に与える影響を評価する。"""
    model = GradientBoostingRegressor(n_estimators=100, random_state=42)

    # 全データで評価
    score_all = cross_val_score(model, X, y, cv=5, scoring="neg_mean_absolute_error")

    # 外れ値を除去して評価
    X_clean = X[~outlier_mask]
    y_clean = y[~outlier_mask]
    score_clean = cross_val_score(model, X_clean, y_clean, cv=5, scoring="neg_mean_absolute_error")

    print(f"全データ:      MAE = {-score_all.mean():.4f} (+/- {score_all.std():.4f})")
    print(f"外れ値除去後:  MAE = {-score_clean.mean():.4f} (+/- {score_clean.std():.4f})")
    print(f"除去したサンプル数: {outlier_mask.sum()} ({outlier_mask.mean()*100:.1f}%)")

    improvement = (-score_all.mean()) - (-score_clean.mean())
    if improvement > 0:
        print(f"→ MAE が {improvement:.4f} 改善しました。外れ値除去は有効です。")
    else:
        print(f"→ MAE が {-improvement:.4f} 悪化しました。外れ値は重要な情報を含んでいる可能性があります。")

# 使用例
iso = IsolationForest(contamination=0.05, random_state=42)
mask = iso.fit_predict(X) == -1
analyze_outlier_impact(X, y, mask)

除去 vs 保持 — 判断のフレームワーク

  1. 1

    除去すべきケース

    データ入力ミス(年齢が -5 歳、体温が 500 度)、測定機器の故障によるノイズ、明らかなテストデータの混入(テスト用に入力されたダミーレコード)など、データの品質問題に起因する外れ値は除去すべきです。

  2. 2

    保持すべきケース

    不正検知やアノマリー検知など、外れ値そのものが予測対象である場合は保持します。また、VIP 顧客の高額取引や季節的なピーク値など、ビジネス上正常な値であれば保持が適切です。

  3. 3

    変換・補正すべきケース

    外れ値の原因が不明で、除去が適切かどうか判断できない場合は、Winsorize(上下 1% の値をクリッピング)や対数変換で影響を緩和する方法が妥協策になります。

Qast の二段階外れ値検出

Qast では、外れ値検出を二段階で実行します。第一段階では IQR 法と Z スコア法による単変量外れ値の検出を行い、各カラムごとに外れ値の数と割合を表示します。第二段階では Isolation Forest による多変量外れ値の検出を行い、複数の特徴量を総合的に考慮した異常データポイントを特定します。さらに、外れ値の影響分析として、外れ値を含む場合と除去した場合の統計量(平均、標準偏差、相関係数)の比較テーブルが自動生成されます。ユーザーはレポートを確認して「除去する」「保持する」「変換する」の判断を行い、その設定を学習ジョブに反映できます。

Qast の外れ値検出は EDA レポート上での「提案」です。自動的に外れ値が除去されることはありません。最終的な判断はユーザーに委ねられるため、安心してレポートの情報を参考にしてください。不明な場合は、外れ値を含むモデルと除去したモデルの両方を Qast で学習して精度を比較するのが最も確実な方法です。

Qast を導入してみませんか?

導入のご相談やデモのご依頼は、お気軽にお問い合わせください。