LOF(局所外れ値因子)による異常検知 — 局所的な密度の違いを捉える

これまで扱った異常検知手法——マハラノビス距離One-Class SVMIsolation Forest——には、ある共通の弱点があります。それは、データの密度が場所によって大きく異なる場合に苦戦することです。たとえば、ある領域には点が密集し、別の領域にはまばらに散らばっている。このとき「全体で見た距離や分割のしやすさ」では、密集領域のすぐ外にある異常を、まばら領域の正常な点と区別できません。

この「局所的な密度の違い」に正面から取り組むのが LOF(Local Outlier Factor, 局所外れ値因子) です。LOFの発想はこうです——ある点が異常かどうかは、絶対的な密度ではなく、その点の密度が「近傍の点たちの密度」と比べてどれだけ低いかで決めるべきだ。密集領域の点は近傍も密、まばら領域の点は近傍もまばら。だから「自分と近傍の密度比」を見れば、密度が不均一でも公平に異常を測れる、というわけです。

本記事では、大域的手法の限界から出発し、k近傍・局所到達可能密度(lrd)・LOFの定義・近傍数の選び方までを、Pythonの実測とともに解説します。k近傍法の知識があると理解がスムーズです。

LOFの概念

図のように、密なクラスタと疎なクラスタが共存するデータで、密なクラスタのすぐ外にある点(赤の星)は「局所的な異常」です。絶対距離では疎クラスタの正常点と区別できませんが、LOFはこれを捉えます。

大域的手法の限界

まず、なぜ密度の違いが問題になるのかを見ます。

大域的手法の限界

図は、各点を「大域的なk近傍距離(近傍20点までの平均距離)」で色付けしたものです。密なクラスタの点は距離が小さく(青)、疎なクラスタの点は距離が大きい(赤)。問題は、密クラスタのすぐ外にある局所異常(緑の輪)の距離が、疎クラスタの正常点と同程度になってしまうことです。大域的な距離だけで判定すると、この局所異常を「疎クラスタの普通の点」と取り違えてしまいます。「どこを基準にするか」を固定した手法は、密度が場所ごとに違うデータで破綻するのです。

k近傍と到達可能距離

LOFは、各点の「局所的な密度」を近傍から推定します。まず基礎となるのが k近傍k-距離 です。

k近傍とk-距離

点 $p$ の k-距離 $\text{k-dist}(p)$ は、$p$ から $k$ 番目に近い点までの距離です。これがその点の周りの「混み具合」の目安になります。さらにLOFでは、密度推定を安定させるため 到達可能距離(reachability distance) を使います。

$$ \begin{equation} \text{reach-dist}_k(p, o) = \max\{\text{k-dist}(o),\ d(p, o)\} \end{equation} $$

これは「点 $p$ から点 $o$ への距離」を、$o$ のk-距離で下から押さえたものです。$p$ が $o$ に非常に近くても、$o$ の混み具合(k-距離)以上には近いとみなさない、という平滑化で、密度推定のばらつきを抑えます。

局所到達可能密度(lrd)

到達可能距離を使って、各点の 局所到達可能密度(local reachability density, lrd) を定義します。

局所到達可能密度

$$ \begin{equation} \text{lrd}_k(p) = 1 \Big/ \left( \frac{1}{|N_k(p)|}\sum_{o \in N_k(p)} \text{reach-dist}_k(p, o) \right) \end{equation} $$

これは「近傍までの平均到達可能距離の逆数」です。近傍が近い(密集している)ほど分母が小さく、lrdは大きく(高密度)なります。逆に近傍が遠い(まばら)ほどlrdは小さく(低密度)なります。要するに、lrdはその点の局所的な密度を表す量です。

LOFの定義

そしてLOFは、この局所密度の 近傍との比 で定義されます。

LOFの定義

$$ \begin{equation} \text{LOF}_k(p) = \frac{1}{|N_k(p)|}\sum_{o \in N_k(p)} \frac{\text{lrd}_k(o)}{\text{lrd}_k(p)} \end{equation} $$

分子は「近傍の点たちの密度」、分母は「自分の密度」。つまりLOFは、自分の周りがどれだけ疎か(近傍と比べて)を表します。この「比」を取ることが、密度の不均一性を吸収する鍵です。密クラスタの点も疎クラスタの点も、近傍と同程度の密度なら比は1に近くなり、正常と判定されます。

LOF値の意味

LOF値の解釈は明快です。LOF ≈ 1 なら近傍と同程度の密度=正常。LOF > 1(おおむね1.5以上)なら近傍より自分が疎=局所的な異常。LOF < 1 なら近傍より密でこれも正常です。絶対的な密度ではなく相対的な密度比で測るので、密度が場所ごとに違っても公平に異常を検出できます。

Pythonで確かめる

密なクラスタ(標準偏差0.15)と疎なクラスタ(標準偏差1.5)が共存するデータに、密クラスタのすぐ外の「局所異常」を加えます。LOFと、大域的なk近傍距離で、異常をどれだけ捉えられるか比べます。

import numpy as np
from sklearn.neighbors import LocalOutlierFactor, NearestNeighbors
from sklearn.metrics import roc_auc_score

rng = np.random.default_rng(0)
dense  = rng.normal([0,0], 0.15, (200,2))      # 密なクラスタ
sparse = rng.normal([6,6], 1.5,  (200,2))      # 疎なクラスタ
local_anom = np.array([[0.8,0.8],[-0.8,0.6],[0.7,-0.8]])  # 密クラスタ外の局所異常
X = np.vstack([dense, sparse, local_anom])
y = np.r_[np.zeros(400), np.ones(len(local_anom))]

# LOF(局所密度比)
lof = LocalOutlierFactor(n_neighbors=20).fit(X)
lof_score = -lof.negative_outlier_factor_

# 大域的なk近傍距離(近傍20点の平均距離)
nn = NearestNeighbors(n_neighbors=20).fit(X)
dist, _ = nn.kneighbors(X)
knn_score = dist.mean(1)

print(f"LOF          ROC-AUC = {roc_auc_score(y, lof_score):.3f}")
print(f"kNN距離(大域) ROC-AUC = {roc_auc_score(y, knn_score):.3f}")
print(f"局所異常: LOF={lof_score[400]:.2f}, kNN距離={knn_score[400]:.2f}")
print(f"疎クラスタ正常の平均: kNN距離={knn_score[200:400].mean():.2f}")

出力は次の通りです。

LOF          ROC-AUC = 1.000
kNN距離(大域) ROC-AUC = 0.849
局所異常: LOF=6.67, kNN距離=0.83
疎クラスタ正常の平均: kNN距離=0.74

LOFによる検出

結果は決定的です。LOFのROC-AUCは1.000(完璧)、大域的なk近傍距離は 0.849 にとどまりました。鍵は局所異常のスコアです。局所異常の大域kNN距離は 0.83 で、疎クラスタの正常点の平均 0.74 とほぼ同じ——大域的手法では「普通の点」と見分けがつきません。ところがLOFは 6.67(1をはるかに超える)と、強い異常として検出しています。密クラスタ(密度が高い)のすぐ外にあるため、近傍との密度比が極端に大きくなるからです。絶対距離では埋もれる異常が、局所密度比という視点で浮かび上がる——これがLOFの真骨頂です。

ROC比較

近傍数kの選び方

LOFの主要なパラメータは近傍数 $k$(n_neighbors)です。

近傍数kの効果

$k$ が小さすぎると、局所的なノイズに敏感になり、少数の偶発的な近接で密度推定がぶれます。$k$ が大きすぎると、広範囲を平均してしまい「局所性」という長所が失われ、大域的手法に近づきます。一般には $k=20$ 前後がよく使われ、想定する異常クラスタの最小サイズより大きく取るのが目安です。データに応じて、複数の $k$ で計算して最大のLOFを採用する、といった頑健化も行われます。

長所と短所

LOFの長所と短所

LOFの実務的な特徴をまとめます。

  • 長所:密度が場所ごとに異なるデータに強い。これは他の多くの手法が苦手とする点で、LOF最大の差別化要因です。クラスタごとに密度が違う実データ(地域ごとに人口密度が違う、など)で威力を発揮します。
  • 短所1(計算量):全点間の近傍計算が必要で、計算量は $O(n^2)$。大規模データには重く、近似最近傍探索やサブサンプリングが必要です。
  • 短所2(パラメータ感度):$k$ の選択と特徴量のスケーリングに敏感です。距離ベースなので標準化は必須。
  • 短所3(高次元):高次元では距離が意味を失い(次元の呪い)、密度推定が不安定になります。次元削減との併用が有効です。
  • スコアの扱い:LOF値は1を基準に解釈できますが、データ依存なので絶対的なしきい値は決めにくく、相対順位や検証での調整が現実的です。

「絶対的な距離」ではなく「近傍との相対的な密度」で測るというLOFの発想は、密度が不均一な現実のデータに対して、他の手法にはない頑健性をもたらします。

まとめ

LOF(局所外れ値因子)による異常検知を解説しました。

  • マハラノビス・One-Class SVM・Isolation Forestなどは、密度が場所ごとに異なるデータで局所異常を見逃しやすい。
  • LOFは、点の異常度を近傍との局所密度比で測る。局所到達可能密度(lrd)を求め、近傍のlrdとの比をLOFとする。
  • LOF ≈ 1 は正常、LOF > 1 は局所的に疎=異常。比を取ることで密度の不均一性を吸収する。
  • 実測では、密度差のあるデータでLOFがROC-AUC 1.000、大域的kNN距離は 0.849。局所異常を大域手法は見逃した(距離0.83が疎クラスタ正常0.74と同程度)が、LOFは6.67で明確に検出した。
  • 長所は密度不均一への強さ、短所は$O(n^2)$の計算量・$k$とスケーリングへの感度・高次元での劣化。

これで本シリーズの距離・密度・境界・再構成・時系列にわたる異常検知手法が一通り揃いました。異常検知入門の「手法の地図」と照らし合わせると、各手法が「正常をどう表現するか」で体系的に整理できることが見えてきます。