[이탐] 거리 기반 이상탐지 알고리즘

Posted by Euisuk's Dev Log on May 14, 2024

거리 기반 알고리즘

거리 기반 알고리즘은 데이터 포인트 간의 거리를 기반으로 이상치를 탐지합니다. 데이터 포인트가 다른 포인트와의 거리가 멀다면 이상치로 간주됩니다.

K-Means Clustering 기반 이상탐지

  • 링크: https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html
  • 정의: 데이터를 여러 개의 클러스터로 나누고, 각 클러스터 중심에서의 거리를 기반으로 이상치를 탐지합니다. 클러스터에 속하지 않거나 클러스터 중심에서 멀리 떨어진 데이터 포인트를 이상치로 간주합니다.
  • 적합한 데이터: 데이터의 군집 구조가 명확한 경우에 적합합니다. 데이터가 여러 개의 그룹으로 자연스럽게 나눠지는 경우 효과적입니다.
  • sklearn 함수: sklearn.cluster.KMeans

    • 함수 설명:

      • K-Means 알고리즘은 데이터를 K개의 클러스터로 나누고, 각 클러스터의 중심(센트로이드)을 반복적으로 계산하여 클러스터를 형성합니다. 각 데이터 포인트는 가장 가까운 클러스터 중심에 할당됩니다.
      • 이 알고리즘은 특히 대규모 데이터셋에서도 빠르고 효율적으로 작동하며, 클러스터 내 데이터 포인트의 밀집도를 기반으로 이상치를 탐지할 수 있습니다.
    • 매개변수:

      • n_clusters (int, default=8): 형성할 클러스터의 수입니다.
      • init (str, callable or array-like, default=’k-means++’): 초기 클러스터 중심을 설정하는 방법입니다. ‘k-means++’는 수렴 속도를 높이기 위해 초기 클러스터 중심을 선택하는 방법입니다.
      • n_init (int or str, default=’auto’): 다른 클러스터 중심 시드로 K-Means 알고리즘을 실행할 횟수입니다. 최종 결과는 이 중 가장 좋은 결과입니다.
      • max_iter (int, default=300): 단일 실행에서 K-Means 알고리즘의 최대 반복 횟수입니다.
      • tol (float, default=1e-4): 수렴을 선언하기 위한 클러스터 중심 변화의 허용 오차입니다.
      • verbose (int, default=0): 상세 출력 모드입니다.
      • random_state (int, RandomState instance or None, default=None): 무작위 클러스터 중심 초기화를 위한 난수 생성기 시드입니다.
      • copy_x (bool, default=True): True로 설정하면 원본 데이터를 수정하지 않고, False로 설정하면 데이터를 수정합니다.
      • algorithm (str, default=’lloyd’): K-Means 알고리즘으로 ‘lloyd’와 ‘elkan’ 중 선택할 수 있습니다. ‘elkan’은 삼각부등식을 사용하여 효율성을 높일 수 있습니다.
    • 속성:

      • cluster_centers_: 클러스터 중심의 좌표 배열입니다.
      • labels_: 각 데이터 포인트에 할당된 클러스터 라벨 배열입니다.
      • inertia_: 각 데이터 포인트에서 가장 가까운 클러스터 중심까지의 거리의 합입니다.
      • n_iter_: 알고리즘이 실행된 반복 횟수입니다.
      • n_features_in_: fit 동안 본 특성의 수입니다.
      • feature_names_in_: fit 동안 본 특성 이름 배열입니다.
    • 메서드:

      • fit(X[, y, sample_weight]): K-Means 클러스터링을 수행합니다.
      • fit_predict(X[, y, sample_weight]): 클러스터 중심을 계산하고 각 샘플에 대한 클러스터 인덱스를 예측합니다.
      • fit_transform(X[, y, sample_weight]): 클러스터링을 수행하고 X를 클러스터-거리 공간으로 변환합니다.
      • get_feature_names_out([input_features]): 변환을 위한 출력 특성 이름을 가져옵니다.
      • get_metadata_routing(): 이 객체의 메타데이터 라우팅을 가져옵니다.
      • get_params([deep]): 이 추정기의 파라미터를 가져옵니다.
      • predict(X[, sample_weight]): 각 샘플이 속한 가장 가까운 클러스터를 예측합니다.
      • score(X[, y, sample_weight]): K-Means 목적 함수의 값을 기반으로 데이터를 평가합니다.
      • set_fit_request(*[, sample_weight]): fit 메서드에 전달된 메타데이터 요청을 설정합니다.
      • set_output(*[, transform]): 출력 컨테이너를 설정합니다.
      • set_params(**params): 이 추정기의 파라미터를 설정합니다.
      • set_predict_request(*[, sample_weight]): predict 메서드에 전달된 메타데이터 요청을 설정합니다.
      • set_score_request(*[, sample_weight]): score 메서드에 전달된 메타데이터 요청을 설정합니다.
      • transform(X): X를 클러스터-거리 공간으로 변환합니다.
    • 예시:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      
      from sklearn.cluster import KMeans
      import numpy as np
      
      # 예제 데이터
      X = np.array([[1, 2], [1, 4], [1, 0],
                    [10, 2], [10, 4], [10, 0]])
      
      # K-Means 모델 생성 및 적합
      kmeans = KMeans(n_clusters=2, random_state=0, n_init="auto").fit(X)
      
      # 클러스터 라벨 출력
      print(kmeans.labels_)
      
      # 새로운 데이터에 대한 클러스터 예측
      print(kmeans.predict([[0, 0], [12, 3]]))
      
      # 클러스터 중심 출력
      print(kmeans.cluster_centers_)
      

✍️ 이 예제는 K-Means를 사용하여 간단한 데이터셋에 대한 클러스터링을 수행하는 방법을 보여줍니다. K-Means는 데이터 포인트를 클러스터로 그룹화하고, 각 클러스터의 중심을 계산하여 데이터를 효과적으로 분류할 수 있습니다.

KNN (K-Nearest Neighbors)

  • 링크 : https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.NearestNeighbors.html
  • 정의: K-Nearest Neighbors(KNN) 알고리즘은 각 데이터 포인트에 대해 가장 가까운 K개의 이웃을 찾고, 이 이웃들 간의 거리 정보를 기반으로 해당 데이터 포인트의 특성을 판단하는 비지도 학습 방법입니다. 주로 이상치 탐지, 데이터 분류, 군집화 등에 사용됩니다.
  • 적합한 데이터: 거리 측정이 의미 있는 결과를 제공하는 데이터셋에서 효과적이며, 데이터 포인트 간의 거리를 계산할 수 있는 구조적인 데이터에 적합합니다. 특히, 이상치 탐지에서는 데이터 포인트의 밀집도를 기반으로 이상치를 탐지할 수 있습니다.
  • sklearn 함수: sklearn.neighbors.NearestNeighbors

    • 함수 설명:

      • NearestNeighbors는 데이터 포인트 간의 거리 정보를 기반으로 가장 가까운 이웃을 찾기 위한 비지도 학습 알고리즘입니다. 이 알고리즘은 다양한 거리 측정 방법과 검색 알고리즘을 지원하며, 주로 K-이웃 탐색 및 반경 이웃 탐색을 수행합니다.
    • 매개변수:

      • n_neighbors (int, default=5): K-이웃 탐색 시 사용할 이웃의 수입니다.
      • radius (float, default=1.0): 반경 이웃 탐색 시 사용할 반경 크기입니다.
      • algorithm (str, default=’auto’): 이웃을 찾기 위해 사용할 알고리즘을 지정합니다. ‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’ 중 선택할 수 있습니다.
      • leaf_size (int, default=30): BallTree 또는 KDTree에서 사용할 리프의 크기입니다. 이는 트리 구축 및 쿼리 속도에 영향을 줍니다.
      • metric (str or callable, default=’minkowski’): 거리 계산에 사용할 메트릭을 지정합니다. ‘minkowski’는 p=2일 때 유클리드 거리와 동일합니다.
      • p (float, default=2): Minkowski 메트릭에서 사용할 파라미터입니다. p=1은 맨해튼 거리, p=2는 유클리드 거리에 해당합니다.
      • metric_params (dict, default=None): 메트릭 함수의 추가 매개변수입니다.
      • n_jobs (int, default=None): 병렬로 실행할 작업의 수를 지정합니다. -1로 설정하면 모든 프로세서를 사용합니다.
    • 속성:

      • effective_metric_: 이웃 검색에 사용된 거리 메트릭입니다.
      • effective_metric_params_: 거리 메트릭에 사용된 매개변수입니다.
      • n_features_in_: fit 동안 본 특성의 수입니다.
      • feature_names_in_: fit 동안 본 특성 이름 배열입니다.
      • n_samples_fit_: 학습 데이터의 샘플 수입니다.
    • 메서드:

      • fit(X[, y]): 훈련 데이터셋에서 최근접 이웃 추정기를 학습시킵니다.
      • get_metadata_routing(): 이 객체의 메타데이터 라우팅을 가져옵니다.
      • get_params([deep]): 이 추정기의 파라미터를 가져옵니다.
      • kneighbors([X, n_neighbors, return_distance]): 특정 포인트의 K-이웃을 찾습니다.
      • kneighbors_graph([X, n_neighbors, mode]): 데이터 포인트에 대한 K-이웃 그래프(가중치 포함)를 계산합니다.
      • radius_neighbors([X, radius, ...]): 특정 반경 내의 이웃을 찾습니다.
      • radius_neighbors_graph([X, radius, mode, ...]): 데이터 포인트에 대한 반경 이웃 그래프(가중치 포함)를 계산합니다.
      • set_params(**params): 이 추정기의 파라미터를 설정합니다.
    • 예시:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      
      from sklearn.neighbors import NearestNeighbors
      import numpy as np
      
      # 예제 데이터
      samples = [[0, 0, 2], [1, 0, 0], [0, 0, 1]]
      
      # NearestNeighbors 모델 생성 및 적합
      neigh = NearestNeighbors(n_neighbors=2, radius=0.4)
      neigh.fit(samples)
      
      # k-이웃 탐색
      print(neigh.kneighbors([[0, 0, 1.3]], 2, return_distance=False))
      
      # 반경 이웃 탐색
      nbrs = neigh.radius_neighbors([[0, 0, 1.3]], 0.4, return_distance=False)
      print(np.asarray(nbrs[0][0]))
      

✍️ 이 예제는 NearestNeighbors를 사용하여 간단한 데이터셋에 대한 K-이웃 탐색 및 반경 이웃 탐색을 수행하는 방법을 보여줍니다. KNN은 데이터 포인트 간의 거리 정보를 기반으로 가까운 이웃을 찾고, 이를 통해 데이터의 특성을 파악하거나 이상치를 탐지할 수 있는 유용한 알고리즘입니다.

K-Means와 KNN의 차이점

K-Means와 K-Nearest Neighbors(KNN)는 모두 거리 기반의 접근 방식을 사용하지만, 그 목적과 사용 방식이 다릅니다. 이 두 알고리즘을 이상탐지 관점에서 비교해 보겠습니다.

  • K-Means: 데이터를 클러스터로 그룹화하여 각 클러스터 내의 밀집도를 기반으로 이상치를 탐지합니다. 주로 군집화를 통해 데이터의 구조를 파악하고 이상치를 탐지합니다.
    • 사용 방식: 데이터 전체를 클러스터로 그룹화하고 클러스터 중심에서의 거리를 기반으로 이상치를 판단합니다.

    • 군집화 여부: 명확한 클러스터를 형성하여 클러스터 내의 거리를 평가합니다.

  • KNN: 각 데이터 포인트의 이웃과의 거리를 기반으로 밀도를 평가하여 이상치를 탐지합니다. 주로 개별 데이터 포인트의 밀도를 평가하여 이상치를 탐지합니다.
    • 사용 방식: 각 데이터 포인트의 이웃과의 거리를 계산하여 밀도를 평가하고, 밀도가 낮은 포인트를 이상치로 판단합니다.

    • 군집화 여부: 클러스터를 형성하지 않고, 각 데이터 포인트의 이웃과의 거리를 직접 평가합니다.

요약하자면, K-Means와 KNN은 모두 거리 기반 이상탐지를 수행할 수 있지만, K-Means는 군집화를 통해 클러스터 중심에서의 거리를 평가하는 반면, KNN은 개별 데이터 포인트의 이웃과의 거리를 평가합니다.