LOF (Local Outlier Factor)

이정훈·2025년 12월 16일

1. LOF

  • 밀도 기반 (Density-Based) 이상치 탐지 기법
  • 지역적 밀도(Local Density)를 고려하여 내 주변 대비 얼마나 동떨여 져있는지 판단

2. 알고리즘

[Step 1] 기준 척도 만들기: k-distance(o)

  • 각 데이터 포인트가 속한 "동네의 크기(밀도 수준)"를 측정
  • 정의:oo에서 kk번째로 가까운 이웃까지의 거리
  • 의미:oo 주변의 기본적인 밀도 척도(반경)
상태설명k-distance
Dense (빽빽한 곳)이웃들이 다닥다닥 붙어 있음작음
Sparse (널널한 곳)이웃들이 멀리 떨어져 있음

비유: 서울 강남(oo)에서의 "가까운 이웃" 반경은 10m일 수 있지만, 강원도 산골(oo')에서의 반경은 1km일 수 있습니다. LOF는 이처럼 지역마다 다른 기준을 먼저 잡습니다.

[Step 2] 거리 보정하기: Reachability Distance

  • 두 점 사이의 거리를 잴 때, 단순한 물리적 거리(Euclidean Distance)를 쓰지 않고 밀도를 고려하여 보정한 거리를 사용
  • 밀도가 낮은(널널한) 곳에서 우연히 가까운 두 점 때문에 밀도가 비정상적으로 높게 계산되는 것을 방지(Smoothing)
reach-distk(p,o)=max(k-distance(o),d(p,o))\text{reach-dist}_k(p, o) = \max(\text{k-distance}(o), d(p, o))

작동 방식

  1. ppoo와 아주 가까울 때 (d(p,o)<k-distance(o)d(p, o) < \text{k-distance}(o)):
    • 실제 거리가 너무 작으면 밀도가 무한대로 치솟을 수 있음
    • 이를 막기 위해 실제 거리 대신 oo의 기본 반경인 k-distance(o)\text{k-distance}(o)를 사용
    • 의미: "너네 동네는 원래 널널하니까(거리가 크니까), 우연히 붙어 있어도 최소한 그 동네 기본 거리만큼은 떨어져 있는 셈 치자."
  2. ppoo보다 멀리 있을 때:
    • 실제 거리 d(p,o)d(p, o)를 그대로 사용

[Step 3] 밀도 계산하기: LRD (Local Reachability Density)

  • 보정된 거리(reach-dist)를 사용하여 점 pp진짜 밀도를 계산
  • pp와 그 이웃들 사이의 reach-dist 평균을 구한 뒤, 그 역수를 취함
  • 거리가 짧을수록 밀도는 커짐
    • 평균 거리가 짧다 \rightarrow 분모가 작음 \rightarrow LRDLRD 값(밀도)이 큼 (빽빽함)
    • 평균 거리가 길다 \rightarrow 분모가 큼 \rightarrow LRDLRD 값(밀도)이 작음 (널널함)
      LRDk(p)=1avg(reach-distk(p,neighbors))LRD_k(p) = \frac{1}{\text{avg}(\text{reach-dist}_k(p, \text{neighbors}))}

[Step 4] 비교를 통해 이상치 판별: LOF 점수

  • 마지막으로, "나의 밀도""내 이웃들의 밀도"를 비교
    • 분자: 내 이웃들의 밀도 평균
    • 분모: 나(pp)의 밀도
LOFk(p)=Average LRD of neighborsLRD of pLOF_k(p) = \frac{\text{Average } LRD \text{ of neighbors}}{LRD \text{ of } p}

결과 해석 (직관적 이해)

1. LOF1LOF \approx 1 (정상 데이터)

  • 분자(이웃 밀도)와 분모(내 밀도)가 비슷함
  • 상황: "내 주변 친구들도 빽빽하게 모여 있고, 나도 그 틈에 잘 껴 있다." (혹은 둘 다 널널하다)
  • 같은 클러스터에 속해 있으므로 정상

2. LOF1LOF \gg 1 (이상치, Outlier)

  • 분자(이웃 밀도)는 큰데, 분모(내 밀도)는 작음
  • 상황: "내 친구들(oo)은 자기들끼리 빽빽하게 뭉쳐 있는데(고밀도), 나(pp) 혼자 멀리 떨어져 있어서 밀도가 낮다(저밀도)."
  • 밀집 지역에서 튕겨져 나온 이상치 (보통 1.5 이상이면 주의 깊게 관찰)

3. LOF<1LOF < 1 (인라이어, Inlier)

  • 분자보다 분모(내 밀도)가 더 큼
  • 상황: "주변보다 내가 더 중심부에 빽빽하게 위치해 있다."
  • 아주 건전한 정상 데이터

3. LOF 파라미터

LocalOutlierFactor(
    n_neighbors=20,
    *,
    algorithm='auto',
    leaf_size=30,
    metric='minkowski',
    p=2,
    metric_params=None,
    contamination='auto',
    novelty=False,
    n_jobs=None,
)

n_neighbors

  • 관찰할 주변의 샘플의 수, 위 알고리즘에서 K와 동일

novelty

  • novelty = False → 주어진 데이터셋에 대해서만 이상치 판별 (outlier detection)
  • novelty = True → 학습 데이터로 정상 분포를 학습한 뒤, 새로운 데이터가 이상한지 판단
lof = LocalOutlierFactor(novelty=True)
lof.fit(X_train)             # 정상 데이터로 학습
labels = lof.predict(X_new)  # 새 데이터에 대해 예측
scores = lof.score_samples(X_new)  # LOF 점수 반환
profile
AngDDo

0개의 댓글