260309 [ Day 42 ] - ML, DL - Part 2 (2)

TaeHyun·2026년 3월 9일

TIL

목록 보기
168/185

시작하며

오늘은 이상탐지에 대해 배웠다. 이상탐지 파트도 내용이 엄청 많고 하나하나 다 어려운 개념들이라 정말 힘들었다. 그래도 기초 통계 이론을 정리해둬서 도움이 되는 부분이 많아 빨리 머신러닝 통계 이론도 정리해야 될 것 같다.

이상 탐지

이상 탐지의 필요성

  • 센서 오작동, 기록/입력 오류로 인해 발생한 이상치는 모델이 잘못된 패턴을 학습하게 만들어 성능을 떨어뜨림
    • 데이터 전처리 단계에서 이상치를 발견하여 제거 또는 보정해야 됨
  • 이상 탐지는 희귀 이벤트의 후보 구간을 좁혀 정밀 조사와 추가 분석 대상을 효율적으로 선정
  • 이상치를 무조건 제거하면 실제로 고장 징후를 나타내는 중요한 신호까지 사라질 수 있음
    • 이상치를 데이터 품질 문제와 의미 있는 비정상 신호로 구분해야 됨
  • 이상 탐지를 통해 조기에 포착하면 고장나기 이전에 경고를 줄 수 있음

통계적 이상 탐지 기법 비교

구분상세 내용공식
표준화 점수 (Z-Score)• 방식 : 표준화 점수를 기준으로 이상치를 판별
• 장점 : 표준화 점수의 절대값이 3 이상이면 이상치로 간주
• 단점 : 단변량 기준이며, 좌우 대칭하는 정규분포를 가정
zi=xiμσz_i = \frac{x_i - \mu}{\sigma}
사분범위 (IQR)• 방식 : 사분범위를 기준으로 이상치를 판별
• 장점 : 사분위수 기반이라 평균/표준편차 대비 로버스트함
• 단점 : 단변량 기준이며, 변수 간 상관관계를 반영할 수 없음
IQR=Q3Q1IQR = Q3 - Q1
Lower Fence=Q11.5×IQRLower\ Fence = Q1 - 1.5 \times IQR
Upper Fence=Q3+1.5×IQRUpper\ Fence = Q3 + 1.5 \times IQR
마할라노비스 거리 (MD)• 방식 : 공분산 구조를 반영한 다변량 거리로 이상치를 판별
• 장점 : 다변량 기준이며, 변수 간 조합으로 이상치를 포착
• 단점 : 공분산 추정에 민감 → 다중공선성, 소표본, 결측값이 많은 데이터에 대해 불안정
MD2=(xμ)TΣ1(xμ)MD^2 = (\mathbf{x} - \boldsymbol{\mu})^T \boldsymbol{\Sigma}^{-1} (\mathbf{x} - \boldsymbol{\mu})
MD2>χp,α2MD^2 > \chi^2_{p, \alpha}
  • 제조업에서 주로 사용하는 기법
구분방식 및 특징주요 공식
Hotelling's T2T^2• 방식 : 주성분 공간에서의 마할라노비스 거리 측정
• 장점 : PCA를 통해 잡음 제거 가능
• 단점 : 정상 데이터 기반의 모델 학습 필요
T2=j=1mtij2λjT^2 = \sum_{j=1}^{m} \frac{t_{ij}^2}{\lambda_j}
Squared Prediction Error (SPE)• 방식 : 실제값과 PCA 복원값의 차이(잔차) 기반
• 장점 : 설비 고장 등 미세한 변화 포착에 강함
• 단점 : 노이즈와 고장 징후의 구분 필요
SPEi=xix^iSPE_i = \|x_i - \hat{x}_i\|

머신러닝, 딥러닝 기반 이상 탐지 기법 비교

구분상세 내용
Isolation Forest• 방식 : 무작위 트리를 반복 생성하고, 적은 분할로 고립되는 관측값을 이상치로 판단
• 장점 : 고차원 데이터에 강하고, 비정규성 및 비선형 패턴을 탐지할 수 있음
• 단점 : 데이터의 밀도나 구조가 매우 복잡하면 성능이 불안정해질 수 있음
One-class SVM• 방식 : 정상 데이터의 경계를 학습해 경계 밖의 관측값을 이상치로 분류
• 장점 : 경계 기반 방법을 사용하므로 매우 미세한 패턴을 포착할 수 있음
• 단점 : 대량 데이터에서는 느리고, 커널 선택에 매우 민감
Autoencoder• 방식 : 입력 → 잠재공간 → 복원 과정에서 재구성 오차가 큰 샘플을 이상치로 판단
• 장점 : 비선형 패턴, 고차원 시계열 및 센서 데이터에서도 강력한 성능을 보임
• 단점 : 학습 비용이 크며, 정상 데이터만으로 충분히 학습되어야 함

이상치 임계값 설정 전략

  • 표준화 점수 : 일반적으로 절대값이 3을 초과하면 이상치로 판단
  • 마할라노비스 거리 : 카이제곱 분포
  • Hotelling's T2T^2 : F 분포를 가정하고 상위 5% 또는 1%에 해당하는 값을 임계값으로 사용
  • 머신러닝, 딥러닝 : 전체 데이터의 일정 비율을 이상치로 가정하여 설정

표준화 점수 기준 이상치 확인

from sklearn.preprocessing import StandardScaler
  • 표준화 객체 생성
scaler = StandardScaler()
  • 열별 표준화
X_scaled = pd.DataFrame(
    data=scaler.fit_transform(X=train_num),
    index=train_num.index,
    columns=train_num.columns
)
  • z-score 기준으로 열별 이상치 개수 확인
X_scaled.abs().apply(func= lambda x: x.ge(3).sum())
# AirTmp        0
# ProcTmp       0
# RotSpd      164
# Torque       25
# ToolWear      0
# dtype: int64

사분범위 기준 이상치 확인

  • 사분범위 기준 이상치 여부 반환 함수 정의
def iqr_outlier_count(x):
    q1, q3 = x.quantile(q=[0.25, 0.75])
    iqr = q3 - q1
    lower = q1 - 1.5 * iqr
    upper = q3 + 1.5 * iqr
    outlier = x.lt(lower) | x.gt(upper)
    return outlier.sum()
  • 열별 이상치 개수 확인
X_scaled.apply(func= iqr_outlier_count)
# AirTmp        0
# ProcTmp       0
# RotSpd      418
# Torque       69
# ToolWear      0
# dtype: int64

마할라노비스 거리 기준 이상치 확인

from scipy.spatial.distance import mahalanobis
  • 열별 평균 벡터 생성
mean_vec = train_num.mean()
# AirTmp       300.00493
# ProcTmp      310.00556
# RotSpd      1538.77610
# Torque        39.98691
# ToolWear     107.95100
# dtype: float64
  • 공분산 행렬 생성
cov_mat = train_num.cov()
  • 공분산 행렬의 역행렬 생성
cov_inv = np.linalg.inv(cov_mat)
  • 마할라노비스 거리 생성
mnd = [mahalanobis(u=x, v=mean_vec, VI=cov_inv) for x in train_num.values]
from scipy import stats
  • 카이제곱 분포의 상위 1%에 해당하는 임계값 설정
mnd_threshold = stats.chi2.ppf(q=0.99, df=train_num.shape[1])
# 15.08627246938899
  • 임계값의 양의 제곱근 확인
np.sqrt(mnd_threshold)
# np.float64(3.884105105347819)
  • 마할라노비스 거리 기준 이상치 여부 생성
mnd_outlier = (mnd > np.sqrt(mnd_threshold))
  • 마할라노비스 거리 기준 이상치 개수 확인
mnd_outlier.sum()
# np.int64(194)
  • 이상치 행 선택 후 Target의 상대도수 확인
df.loc[mnd_outlier, 'Target'].value_counts(normalize=True).sort_index()
# Target
# 0    0.587629
# 1    0.412371
# Name: proportion, dtype: float64

Hotelling’s T2T^2 기준 이상치 확인

  • 관측값이 정상 상태의 중심에서 얼마나 멀리 벗어나 있는지를 측정
    • 각 주성분 방향의 분산을 고려
    • 분산이 큰 방향에는 관대하고 분산이 작은 방향에는 더 민감하게 반응
from sklearn.decomposition import PCA
  • 정상 데이터만 선택
X_normal = X_scaled.loc[df['Target'].eq(0)]
  • 누적 분산 비율이 90%인 PCA 모델 생성
    • n_components : 0~1 범위의 실수 지정 시 누적 분산 비율에 해당하는 주성분 개수 자동 적용
model_pca = PCA(n_components=0.90)
  • 정상 데이터로 PCA 모델 학습
model_pca.fit(X=X_normal)
  • 전체 데이터로 주성분 점수 행렬 생성
pca_score = model_pca.transform(X=X_scaled)
  • PCA 모델의 누적 분산 비율 확인
model_pca.explained_variance_ratio_.cumsum()
# array([0.39825224, 0.74785604, 0.95356962])
  • 각 주성분의 고유값 계산
lambdas = model_pca.explained_variance_
  • 각 관측값별 Hotelling's T2 계산
    • 관측값(행)별 합계
ht2 = (pca_score ** 2 / lambdas).sum(axis=1)
  • 주성분 개수 할당
m = model_pca.n_components_
# np.int64(3)
  • 정상 데이터 개수 할당
n = X_normal.shape[0]
# 9661
  • F 분포의 1%에 해당하는 임계값 계산
f_critical = stats.f.ppf(q=0.99, dfn=m, dfd=n-m)
# np.float64(3.783648204590835)
  • F 분포를 이용해 Hotelling's T2 임계값 계산
ht2_threshold = m * (n - 1) / (n - m) * f_critical
# np.float64(11.353295192487305)
  • Hotelling's T2 기준으로 이상치 여부 생성
ht2_outlier = (ht2 > ht2_threshold)
  • Hotelling's T2 기준으로 이상치 개수 확인
ht2_outlier.sum()
# np.int64(139)
  • 이상치 행 선택 후 Target의 상대도수 확인
df.loc[ht2_outlier, 'Target'].value_counts(normalize=True).sort_index()
# Target
# 0    0.741007
# 1    0.258993
# Name: proportion, dtype: float64

마치며

내일 머신러닝 파트가 마무리된 후 캐글 경진대회 2회차가 시작된다. 수요일은 깃허브 특강이 있고, 이후에는 머신러닝과 CV 파트가 시작될 예정이다.

profile
Hello I'm TaeHyunAn, Currently Studying Data Analysis

0개의 댓글