Data Science How-To's

Python을 사용한 머신러닝 기반 이상 탐지

Read this post in other languages:

최근 몇 년 사이, 우리가 수집하고 처리할 수 있는 방대한 데이터가 수많은 애플리케이션의 기반이 되고 있습니다. 누군가는 지금을 데이터의 시대라고 표현하기도 합니다. 이러한 대량의 데이터를 처리하는 데 핵심적인 요소 중 하나는 이상 탐지로, 이는 특이값, 즉 예상 범위를 벗어난 데이터를 식별하고 정상에서 벗어난 동작을 입증할 수 있는 프로세스입니다. 과학 연구에서 이상 데이터 포인트는 기술적 문제의 원인이 될 수 있으며 결론을 도출할 때 폐기해야 할 수도 있고, 새로운 발견으로 이어질 수도 있습니다.

이 블로그 게시물에서는 이상 탐지에 머신러닝을 사용하는 것이 왜 도움이 되는지 살펴보고 Python을 사용하여 이상치를 탐지하는 주요 기술을 살펴봅니다. OneClassSVM 및 Isolation Forest와 같이 널리 사용되는 방법을 구현하는 방법을 배우고, 이러한 결과를 시각화하는 방법의 예를 살펴보고, 실제 문제에 적용하는 방법을 살펴보겠습니다.

이상 탐지의 활용 분야

이상 탐지는 현대 비즈니스 인텔리전스의 중요한 요소로 자리 잡고 있으며, 이를 통해 발생할 수 있는 문제에 대한 인사이트를 제공하고 잠재적인 문제를 식별할 수도 있습니다. 다음은 현대 비즈니스에서 이상 탐지를 사용하는 몇 가지 예입니다.

보안 경고

이상 탐지를 통해 탐지할 수 있는 몇몇 사이버 보안 공격이 있습니다. 예를 들어, 요청량이 급증하면 DDoS 공격을 의미할 수 있으며, 여러 번의 로그인 시도 실패와 같은 의심스러운 로그인 동작은 무단 액세스일 수 있습니다. 의심스러운 사용자 동작을 탐지하면 잠재적인 사이버 보안 위협을 나타낼 수 있으며, 기업은 이에 따라 조치를 취하여 피해를 예방하거나 최소화하게 됩니다.

사기 탐지

예를 들어 금융 기관에서는 이상 탐지를 사용하여 자금 세탁이나 신원 도용과 같은 불법 활동의 신호일 수 있는 의심스러운 계정 활동을 강조할 수 있습니다. 의심스러운 거래는 또한 신용카드 사기의 신호일 수도 있습니다.

관찰 가능성

웹 서비스의 일반적인 관행 중 하나는 시스템에 비정상적인 동작이 있을 경우 서비스의 실시간 성능에 대한 메트릭을 수집하는 데 있습니다. 예를 들어 메모리 사용량이 급증하면 시스템의 특정 부분이 제대로 작동하지 않는다는 것을 의미할 수 있으며, 이에 엔지니어는 서비스 중단을 피하기 위해 즉시 문제를 해결해야 할 수 있습니다.

이상 탐지에 머신러닝을 사용하는 이유

기존의 통계적 방법도 특이값을 찾는 데 도움이 되지만, 머신러닝이 이상 탐지에 사용되면서 작업이 혁신적으로 바뀌었습니다. 머신러닝 알고리즘을 사용하면 여러 매개변수가 포함된 복잡한 데이터도 한 번에 분석할 수 있습니다. 또한 머신러닝 기술은 숫자형 데이터에 보다 적합한 기존의 통계 방법으로는 분석하기 어려운 범주형 데이터를 분석할 수 있는 수단을 제공합니다.

대부분의 경우 이러한 이상 탐지 알고리즘은 프로그래밍되어 애플리케이션으로 배포할 수 있으며(머신러닝용 FastAPI 튜토리얼 참조), 요청에 따라 또는 예약된 간격으로 실행하여 이상치를 탐지할 수 있습니다. 즉, 회사 내에서 즉각적인 조치를 취할 수 있으며 비즈니스 인텔리전스 팀에서는 전략을 검토하고 수정하기 위한 보고 도구로도 사용할 수 있습니다.

이상 탐지 기법 및 알고리즘의 유형

이상 탐지에는 일반적으로 특이값(Outlier) 탐지와 신규성(Novelty) 탐지의 두 가지 주요 유형이 있습니다.

특이값 탐지

특이값 탐지는 트레이닝 데이터에 탐지되지 않은(이에 따라 라벨이 없는) 이상치가 있다고 가정하고 지도되지 않은 머신러닝 알고리즘을 사용하여 이를 찾아내는 방식으로, 비지도(unsupervised) 이상 탐지라고도 합니다. 이러한 알고리즘 중에는 One-class Support Vector Machine(SVM), Isolation Forest, Local Outlier Factor, Elliptic Envelope 등이 있습니다.

신규성 탐지

반면에 신규성 탐지는 반지도(semi-supervised) 이상 탐지라고도 합니다. 모든 트레이닝 데이터가 이상치만으로 구성되어 있지는 않다고 가정하기 때문에 모두 정상으로 라벨이 지정됩니다. 목표는 새로운 데이터가 이상치인지 여부를 탐지하는 것이며, 이를 신규성이라고도 합니다. 트레이닝 데이터에 이상치가 없다면 특이값 탐지에 사용된 알고리즘은 신규성 탐지에도 사용할 수 있습니다.

앞서 언급한 특이값 탐지 및 신규성 탐지 외에도 시계열 데이터에서 이상 탐지가 필요한 경우도 매우 흔합니다. 그러나 시계열 데이터에 사용되는 접근 방식과 기법은 위에서 언급한 알고리즘과 다른 경우가 많으므로 이에 대해서는 나중에 자세히 설명하겠습니다.

코드 예시: 벌집 데이터 세트에서 이상치 찾기

이 블로그 글에서는 벌집 데이터 세트를 예시로 사용하여 벌집의 이상치를 탐지해 보겠습니다. 이 데이터 세트는 벌집의 온도와 상대 습도 등 여러 시간대에 대한 벌집의 다양한 측정값을 제공합니다.

여기에서는 이상치를 발견하는 굉장히 다른 두 가지 방법을 보여 드리겠습니다. 하나는 의사 결정 경계를 그리는 데 사용할 서포트 벡터 머신 기술을 기반으로 하는 OneClassSVM이고, 다른 하나는 Random Forest와 유사한 앙상블 방법인 Isolation Forest입니다.

예시: OneClassSVM

이 첫 번째 예시에서는 벌이 자신의 사회를 위해 벌집을 항상 쾌적한 환경으로 유지한다고 가정하고 벌집 17의 데이터를 사용하여 이것이 사실인지, 그리고 벌집에 이상 온도와 상대 습도가 발생하는 경우는 어느 때인지 살펴볼 수 있습니다. 데이터에 맞게 OneClassSVM을 사용하여 산점도에서 의사 결정 경계를 살펴보겠습니다.

OneClassSVM의 SVM은 서포트 벡터 머신의 약자로, 분류 및 회귀에 널리 사용되는 머신러닝 알고리즘입니다. 서포트 벡터 머신은 고차원의 데이터 포인트를 분류하는 데 사용할 수 있지만, 커널과 스칼라 매개변수를 선택하여 경계를 정의하면 대부분의 데이터 포인트(정상 데이터)를 포함하는 결정 경계를 만들고 경계 밖에 소수의 이상치를 유지하여 새로운 이상치를 발견하는 확률(nu)을 나타낼 수 있습니다. 서포트 벡터 머신을 이용한 이상 탐지 방법은 논문 Estimating the Support of a High-Dimensional Distribution(Scholkopf 외)에서 다루고 있습니다.

1. Jupyter 프로젝트 시작

PyCharm(Professional 2024.2.2)에서 새 프로젝트를 시작할 때, Python 아래 Jupyter를 선택합니다.

PyCharm에서 Jupyter 프로젝트 시작하기

PyCharm에서 Jupyter 프로젝트(구 Scientific 프로젝트)를 사용하면 데이터를 저장하는 폴더와 모든 Jupyter Notebook을 저장하는 폴더를 포함한 파일 구조가 생성되어 모든 실험을 한 곳에 보관할 수 있는 이점이 있습니다. 

PyCharm의 Jupyter 프로젝트

또 다른 큰 장점은 Matplotlib으로 그래프를 매우 쉽게 렌더링할 수 있다는 것입니다. 이는 아래 단계에서 확인할 수 있습니다.

2. 종속성 설치

관련 GitHub 저장소에서 requirements.txt를 다운로드합니다. 이 파일을 프로젝트 디렉터리에 넣고 PyCharm에서 열면 누락된 라이브러리를 설치할지 묻는 메시지가 표시됩니다.

PyCharm에서 종속성 설치

Install requirements(요구 사항 설치)를 클릭하면 모든 요구 사항이 자동으로 설치됩니다. 이 프로젝트에서는 Python 3.11.1을 사용하고 있습니다.

3. 데이터 가져오기 및 검사

Kaggle 또는 이 GitHub 저장소에서 ‘벌집’ 데이터 세트를 다운로드할 수 있습니다. 세 개의 CSV를 모두 Data 폴더에 넣습니다. 그런 다음 main.py에 다음 코드를 입력합니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import pandas as pd
df = pd.read_csv('data/Hive17.csv', sep=";")
df = df.dropna()
print(df.head())
import pandas as pd df = pd.read_csv('data/Hive17.csv', sep=";") df = df.dropna() print(df.head())
import pandas as pd

df = pd.read_csv('data/Hive17.csv', sep=";")
df = df.dropna()
print(df.head())

마지막으로 화면 오른쪽 상단 모서리의 Run(실행) 버튼을 누르면 Python 콘솔에서 코드가 실행되어 데이터가 어떻게 보이는지 알 수 있습니다.

PyCharm에서 데이터 가져오기

4. 데이터 포인트를 맞추고 그래프에서 검사

scikit-learn의 OneClassSVM을 사용할 것이므로, 아래 코드를 사용하여 DecisionBoundaryDisplay 및 Matplotlib와 함께 가져오겠습니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from sklearn.svm import OneClassSVM
from sklearn.inspection import DecisionBoundaryDisplay
import matplotlib.pyplot as plt
from sklearn.svm import OneClassSVM from sklearn.inspection import DecisionBoundaryDisplay import matplotlib.pyplot as plt
from sklearn.svm import OneClassSVM
from sklearn.inspection import DecisionBoundaryDisplay

import matplotlib.pyplot as plt

데이터의 설명에 따르면 열 T17은 벌집의 온도를 나타내고 RH17은 벌집의 상대 습도를 나타냄을 알 수 있습니다. 이 두 열의 값을 입력으로 추출하겠습니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
X = df[["T17", "RH17"]].values
X = df[["T17", "RH17"]].values
X = df[["T17", "RH17"]].values

그런 다음 모델을 생성하고 알맞게 조정합니다. 먼저 기본 설정을 시도해 보겠습니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
estimator = OneClassSVM().fit(X)
estimator = OneClassSVM().fit(X)
estimator = OneClassSVM().fit(X)

다음으로 데이터 포인트와 함께 결정 경계를 표시합니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
disp = DecisionBoundaryDisplay.from_estimator(
estimator,
X,
response_method="decision_function",
plot_method="contour",
xlabel="Temperature", ylabel="Humidity",
levels=[0],
)
disp.ax_.scatter(X[:, 0], X[:, 1])
plt.show()
disp = DecisionBoundaryDisplay.from_estimator( estimator, X, response_method="decision_function", plot_method="contour", xlabel="Temperature", ylabel="Humidity", levels=[0], ) disp.ax_.scatter(X[:, 0], X[:, 1]) plt.show()
disp = DecisionBoundaryDisplay.from_estimator(
    estimator,
    X,
    response_method="decision_function",
    plot_method="contour",
    xlabel="Temperature", ylabel="Humidity",
    levels=[0],
)
disp.ax_.scatter(X[:, 0], X[:, 1])
plt.show()

이제 저장하고 Run(실행)을 다시 누르면 별도의 창에 플롯이 표시되어 확인할 수 있습니다.

데이터 포인트를 맞추고 PyCharm의 그래프에서 검사

5. 하이퍼 매개변수 세부 조정

위의 플롯에서 볼 수 있듯이 결정 경계가 데이터 포인트와 잘 맞지 않습니다. 데이터 포인트가 타원형이 아니라 불규칙한 몇몇 형태로 구성되어 있습니다. 모델을 세부 조정하려면 OneClassSVM 모델에 ‘mu’와 ‘gamma’의 특정값을 제공해야 합니다. 직접 시도해 볼 수 있지만 몇 번의 테스트해 보니 ‘nu=0.1, gamma=0.05’일 때 가장 좋은 결과를 제공하는 것으로 보입니다.

PyCharm에서 하이퍼 매개변수 세부 조정

예시: Isolation Forest

Isolation Forest앙상블 기반 방법으로, 더 널리 사용되는 Random Forest 분류 방법과 유사합니다. 분할 특징과 값을 무작위로 선택하면 많은 결정 트리가 생성되고 트리의 루트에서 해당 결정을 내리는 노드까지의 경로 길이가 모든 트리에 걸쳐 평균화됩니다(그래서 ‘Forest’). 평균 경로 길이가 짧으면 이상치를 나타냅니다.

Isolation Forest
짧은 결정 경로는 일반적으로 다른 데이터와 매우 다른 데이터를 표시합니다.

이제 OneClassSVM과 IsolationForest의 결과를 비교해 보겠습니다. 이를 위해 두 알고리즘이 만든 결정 경계를 두 개의 플롯으로 만들어 보겠습니다. 다음 단계에서는 동일한 벌집 17 데이터를 사용하여 위의 스크립트를 기반으로 구축해 보겠습니다.

1. IsolationForest 가져오기

IsolationForest는 Scikit-learn의 앙상블 카테고리에서 가져올 수 있습니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from sklearn.ensemble import IsolationForest
from sklearn.ensemble import IsolationForest
from sklearn.ensemble import IsolationForest

2. 리팩터링 및 새 추정기 추가

이제 두 개의 서로 다른 추정기가 있으므로 이들을 목록에 넣어 보겠습니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
estimators = [
OneClassSVM(nu=0.1, gamma=0.05).fit(X),
IsolationForest(n_estimators=100).fit(X)
]
estimators = [ OneClassSVM(nu=0.1, gamma=0.05).fit(X), IsolationForest(n_estimators=100).fit(X) ]
estimators = [
    OneClassSVM(nu=0.1, gamma=0.05).fit(X),
    IsolationForest(n_estimators=100).fit(X)
]

그 다음에는 for 루프를 사용하여 모든 추정기를 순회합니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
for estimator in estimators:
disp = DecisionBoundaryDisplay.from_estimator(
estimator,
X,
response_method="decision_function",
plot_method="contour",
xlabel="Temperature", ylabel="Humidity",
levels=[0],
)
disp.ax_.scatter(X[:, 0], X[:, 1])
plt.show()
for estimator in estimators: disp = DecisionBoundaryDisplay.from_estimator( estimator, X, response_method="decision_function", plot_method="contour", xlabel="Temperature", ylabel="Humidity", levels=[0], ) disp.ax_.scatter(X[:, 0], X[:, 1]) plt.show()
for estimator in estimators:
    disp = DecisionBoundaryDisplay.from_estimator(
        estimator,
        X,
        response_method="decision_function",
        plot_method="contour",
        xlabel="Temperature", ylabel="Humidity",
        levels=[0],
    )
    disp.ax_.scatter(X[:, 0], X[:, 1])
    plt.show()

마지막으로 각 그래프에 제목을 추가하여 더 쉽게 확인할 수 있도록 합니다. 이를 위해 disp.ax_.scatter 뒤에 다음을 추가합니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
disp.ax_.set_title(
f"Decision boundary using {estimator.__class__.__name__}"
)
disp.ax_.set_title( f"Decision boundary using {estimator.__class__.__name__}" )
disp.ax_.set_title(
        f"Decision boundary using {estimator.__class__.__name__}"
    )

PyCharm에서 제공하는 자동 완성 제안 기능을 사용하면 매우 쉽게 리팩터링할 수 있습니다.

PyCharm에서 자동 완성을 사용한 리팩터링
PyCharm의 자동 완성

3. 코드 실행

이전과 마찬가지로 오른쪽 상단 모서리의 Run(실행) 버튼을 누르기만 하면 코드를 실행할 수 있습니다. 이번에는 코드를 실행하면 두 개의 그래프가 표시됩니다.

PyCharm에서 코드 실행

오른쪽의 미리보기를 통해 두 그래프를 쉽게 넘겨볼 수 있습니다. 보시다시피 서로 다른 알고리즘을 사용하면 결정 경계가 상당히 달라집니다. 이상 탐지를 수행할 때는 다양한 알고리즘과 매개변수를 실험하여 사용 사례에 가장 적합한 알고리즘을 찾는 것이 좋습니다.

다음 단계: 시계열 데이터의 이상 탐지

데이터가 시계열인 벌집 데이터와 같은 경우, 이상치를 찾아낼 수 있는 또 다른 방법이 있습니다. 시계열에는 추세와 기간이 있기 때문에 이러한 추세와 기간의 패턴을 벗어나는 모든 것을 이상치로 간주할 수 있습니다. 시계열에서 이상치를 탐지하는 데 널리 사용되는 방법에는 STL 분해와 LSTM 예측이 있습니다.

이러한 방법을 사용하여 시계열에서 이상치를 탐지하는 방법은 이 블로그 글에서 알아보세요.

요약

이상 탐지는 비즈니스 인텔리전스의 중요한 측면으로 입증되었으며, 몇몇 비즈니스 분야에서는 이상치를 식별하고 즉각적인 조치를 취할 수 있는 능력이 필수적입니다. 적절한 머신러닝 모델을 사용하여 이상치를 자동으로 탐지하면 복잡하고 많은 양의 데이터를 단기간에 분석하는 데 도움이 될 수 있습니다. 이 블로그 글에서는 OneClassSVM과 같은 통계 모델을 사용하여 이상치를 식별하는 방법을 살펴보았습니다.

머신러닝에 PyCharm을 사용하는 방법에 대해 자세히 알아보려면 ‘PyCharm으로 머신러닝 공부 시작하기‘ 및 ‘PyCharm에서 Jupyter Notebook을 사용하는 방법‘을 참조하세요.

PyCharm을 사용하여 이상 탐지

PyCharm Professional의 Jupyter 프로젝트를 사용하면 많은 데이터 파일과 Notebook으로 이상 탐지 프로젝트를 쉽게 구성할 수 있습니다. 이상치를 검사하기 위해 그래프 출력을 생성할 수 있으며 PyCharm에서 플롯 역시 매우 쉽게 액세스할 수 있습니다. 자동 완성 제안과 같은 다른 기능을 사용하면 모든 Scikit-learn 모델과 Matplotlib 플롯 설정을 아주 쉽게 탐색할 수 있습니다.

PyCharm을 사용하여 데이터 과학 프로젝트를 지원하고, 데이터 과학 워크플로를 간소화하기 위해 제공되는 데이터 과학 기능을 확인하세요.

 
게시물 원문 작성자
Cheuk Ting Ho

Cheuk Ting Ho

image description

Discover more