본문으로 건너뛰기

067 PyCaret 이상치 탐지 모듈

키워드: 이상치 탐지, 모듈

개요

PyCaret의 이상치 탐지 모듈은 다양한 이상치 탐지 알고리즘을 간편하게 사용할 수 있게 해줍니다. 이 글에서는 PyCaret으로 이상치 탐지를 시작하는 방법을 알아봅니다.

실습 환경

  • Python 버전: 3.11 권장
  • 필요 패키지: pycaret[full]>=3.0

이상치 탐지 모듈 임포트

from pycaret.anomaly import *

샘플 데이터 생성

import pandas as pd
import numpy as np

# 067 정상 데이터 생성
np.random.seed(42)
n_normal = 1000
n_outliers = 50

# 067 정상 데이터 (다변량 정규분포)
normal_data = np.random.multivariate_normal(
mean=[50, 100, 200],
cov=[[25, 5, 10], [5, 100, 20], [10, 20, 400]],
size=n_normal
)

# 067 이상치 데이터
outlier_data = np.random.uniform(
low=[0, 0, 0],
high=[100, 200, 500],
size=(n_outliers, 3)
)

# 067 결합
data = np.vstack([normal_data, outlier_data])
data = pd.DataFrame(data, columns=['Feature1', 'Feature2', 'Feature3'])

# 067 실제 레이블 (평가용)
true_labels = np.array([0] * n_normal + [1] * n_outliers)

print(f"데이터 크기: {len(data)}")
print(f"정상: {n_normal}, 이상치: {n_outliers}")
print(data.describe())

setup() 함수

from pycaret.anomaly import *

# 067 환경 설정
anomaly = setup(
data=data,
session_id=42,
verbose=False
)

print("설정 완료!")

주요 파라미터:

anomaly = setup(
data=data,
normalize=True, # 정규화
normalize_method='zscore', # 정규화 방법
transformation=False, # 분포 변환
pca=False, # PCA 적용
pca_components=None, # PCA 차원
ignore_features=None, # 제외할 특성
session_id=42,
verbose=False
)

지원 알고리즘

from pycaret.anomaly import *

# 067 데이터 설정
anomaly = setup(data, session_id=42, verbose=False)

# 067 지원 모델 확인
models()
모델 ID알고리즘설명
iforestIsolation Forest트리 기반 격리
knnK-Nearest Neighbors거리 기반
lofLocal Outlier Factor지역 밀도 기반
svmOne-Class SVM경계 기반
mcdMinimum Covariance Determinant공분산 기반
pcaPCA AnomalyPCA 재구성 오차
sodSubspace Outlier Detection부분 공간
sosStochastic Outlier Selection확률적

create_model() 함수

from pycaret.anomaly import *

# 067 환경 설정
anomaly = setup(data, session_id=42, verbose=False)

# 067 Isolation Forest (기본 fraction=0.05)
iforest = create_model('iforest')

# 067 이상치 비율 지정
iforest_10 = create_model('iforest', fraction=0.1)

# 067 다른 알고리즘
lof = create_model('lof')
svm = create_model('svm')
knn = create_model('knn')

이상치 레이블 확인

from pycaret.anomaly import *

# 067 환경 설정
anomaly = setup(data, session_id=42, verbose=False)

# 067 모델 생성
iforest = create_model('iforest', fraction=0.05)

# 067 이상치 레이블 할당
result = assign_model(iforest)

print(result.head(10))
print(f"\n탐지된 이상치 수: {(result['Anomaly'] == 1).sum()}")
print(f"정상 데이터 수: {(result['Anomaly'] == 0).sum()}")

이상치 점수 확인

from pycaret.anomaly import *

anomaly = setup(data, session_id=42, verbose=False)

iforest = create_model('iforest', fraction=0.05)
result = assign_model(iforest)

# 067 Anomaly_Score 컬럼: 이상 점수 (높을수록 이상)
print("이상 점수 분포:")
print(result['Anomaly_Score'].describe())

# 067 상위 이상치
top_anomalies = result.sort_values('Anomaly_Score', ascending=False).head(10)
print("\n상위 10개 이상치:")
print(top_anomalies[['Feature1', 'Feature2', 'Feature3', 'Anomaly_Score', 'Anomaly']])

여러 알고리즘 비교

from pycaret.anomaly import *
from sklearn.metrics import precision_score, recall_score, f1_score
import pandas as pd

anomaly = setup(data, session_id=42, verbose=False)

# 067 여러 알고리즘 비교
algorithms = ['iforest', 'lof', 'knn', 'svm']
results = []

for algo in algorithms:
try:
model = create_model(algo, fraction=0.05)
result = assign_model(model)

pred_labels = result['Anomaly'].values

# 평가 (실제 레이블이 있으므로)
precision = precision_score(true_labels, pred_labels)
recall = recall_score(true_labels, pred_labels)
f1 = f1_score(true_labels, pred_labels)

results.append({
'Algorithm': algo,
'Precision': precision,
'Recall': recall,
'F1': f1,
'Detected': pred_labels.sum()
})
except Exception as e:
print(f"{algo} 오류: {e}")

df_results = pd.DataFrame(results)
print("\n알고리즘 비교:")
print(df_results.round(4))

시각화

from pycaret.anomaly import *
import matplotlib.pyplot as plt

anomaly = setup(data, session_id=42, verbose=False)

iforest = create_model('iforest', fraction=0.05)

# 067 t-SNE 시각화
plot_model(iforest, plot='tsne')

# 067 UMAP 시각화
plot_model(iforest, plot='umap')

수동 시각화

from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
from pycaret.anomaly import *

anomaly = setup(data, session_id=42, verbose=False)

iforest = create_model('iforest', fraction=0.05)
result = assign_model(iforest)

# 067 PCA로 2D 변환
pca = PCA(n_components=2)
X_pca = pca.fit_transform(get_config('X'))

# 067 시각화
plt.figure(figsize=(10, 8))

normal_mask = result['Anomaly'] == 0
anomaly_mask = result['Anomaly'] == 1

plt.scatter(X_pca[normal_mask, 0], X_pca[normal_mask, 1],
c='blue', label='Normal', alpha=0.5)
plt.scatter(X_pca[anomaly_mask, 0], X_pca[anomaly_mask, 1],
c='red', label='Anomaly', s=100, marker='x')

plt.xlabel(f'PC1 ({pca.explained_variance_ratio_[0]*100:.1f}%)')
plt.ylabel(f'PC2 ({pca.explained_variance_ratio_[1]*100:.1f}%)')
plt.title('Anomaly Detection Result')
plt.legend()
plt.grid(True, alpha=0.3)
plt.savefig('anomaly_pca.png', dpi=150)

새로운 데이터 예측

from pycaret.anomaly import *
import pandas as pd
import numpy as np

anomaly = setup(data, session_id=42, verbose=False)

iforest = create_model('iforest', fraction=0.05)

# 067 새로운 데이터
new_data = pd.DataFrame({
'Feature1': [50, 0, 45], # 두 번째는 이상치
'Feature2': [100, 500, 105], # 두 번째는 이상치
'Feature3': [200, 50, 195] # 두 번째는 이상치
})

# 067 예측
predictions = predict_model(iforest, data=new_data)
print("새 데이터 예측:")
print(predictions)

모델 저장 및 로드

from pycaret.anomaly import *

anomaly = setup(data, session_id=42, verbose=False)

iforest = create_model('iforest', fraction=0.05)

# 067 저장
save_model(iforest, 'anomaly_model')

# 067 로드
loaded_model = load_model('anomaly_model')

# 067 예측 테스트
test_result = predict_model(loaded_model, data=data.head())
print(test_result)

fraction 파라미터 튜닝

from pycaret.anomaly import *
from sklearn.metrics import f1_score
import pandas as pd

anomaly = setup(data, session_id=42, verbose=False)

# 067 다양한 fraction 테스트
fractions = [0.01, 0.03, 0.05, 0.07, 0.1, 0.15]
results = []

for frac in fractions:
model = create_model('iforest', fraction=frac)
result = assign_model(model)
pred_labels = result['Anomaly'].values

f1 = f1_score(true_labels, pred_labels)
detected = pred_labels.sum()

results.append({
'Fraction': frac,
'Detected': detected,
'F1': f1
})

df_results = pd.DataFrame(results)
print("Fraction에 따른 성능:")
print(df_results.round(4))

이상치 탐지 워크플로우

from pycaret.anomaly import *

# 1. 데이터 로드
# 067 data = pd.read_csv('data.csv')

# 2. 환경 설정
anomaly = setup(data, normalize=True, session_id=42, verbose=False)

# 3. 여러 모델 테스트
models_to_test = ['iforest', 'lof', 'knn']
best_model = None
best_f1 = 0

for algo in models_to_test:
model = create_model(algo, fraction=0.05)
result = assign_model(model)
# 평가 후 최적 모델 선택
# ...

# 4. 최종 모델로 이상치 탐지
# 067 final_result = assign_model(best_model)

# 5. 저장
# 067 save_model(best_model, 'final_anomaly_model')

정리

  • PyCaret 이상치 탐지 모듈: from pycaret.anomaly import *
  • setup()으로 환경 설정
  • create_model()로 다양한 알고리즘 적용
  • assign_model()로 이상치 레이블 확인
  • fraction 파라미터로 이상치 비율 조절
  • Isolation Forest가 가장 많이 사용됨

다음 글 예고

다음 글에서는 Isolation Forest 상세를 다룹니다.


PyCaret 머신러닝 마스터 시리즈 #067