2편에서 다룬 홀텔링 이론이나 GMM은 정상 데이터가 형성하는 확률분포 하나를 통째로 학습했다. 관측값이 그 분포에서 나올 법한지만 보고 이상 여부를 판정하는 접근이다. 하지만 이 접근은 관측값의 정상 범위 자체가 다른 변수에 따라 달라지는 상황에서는 힘을 잃는다. 이 글은 입력에 대한 출력의 편차로 이상을 정의하는 회귀 기반 접근과, 파라미터의 불확실성까지 반영하는 베이지안 모델링을 다룬다.
회귀 기반 이상탐지를 다루려는 개발자와 데이터 엔지니어를 대상으로 하며, 이 글을 읽고 나면 입력과 출력이 있는 데이터에서 왜 회귀가 필요한지, 최우추정과 베이지안 추정이 무엇이 다른지, MCMC가 언제 필요한지 판단할 수 있다. 예제 코드는 github.com/mimul/anomaly_detection의 series03/에 있다.
입력과 출력이 있는 데이터에서 이상을 정의하기
중고차 매물의 가격이 이상한지 판단하는 문제를 생각해보자. 가격 하나만 놓고 정규분포를 적합해 홀텔링 이론을 적용하면, 연식이 오래되고 주행거리가 긴 차는 가격이 낮다는 이유만으로 무더기로 이상 판정을 받는다. 실제로는 낮은 가격이 그 차의 연식과 주행거리를 감안하면 지극히 정상일 수 있다. 이런 데이터에서는 관측값 자체의 확률이 아니라, 입력(연식, 주행거리, 차종)에 대해 출력(가격)이 예측값에서 얼마나 벗어났는지로 이상을 정의해야 한다. 이때 입력을 설명변수, 출력을 응답변수라 부른다.
이 글에서는 연식·주행거리·차종(판매자는 후반 랜덤효과에서 사용)으로 가격이 정해지는 중고차 데이터셋을 사용한다. 학습 데이터 1100건 중 1000건이 정상 매물이고 100건은 의도적으로 가격을 왜곡해 만든 이상 매물이다(학습에는 정상 매물만 사용한다). 추론 데이터는 500건의 정상 매물과 50건의 이상 매물로 구성된 550건이다. 차종은 세단(sedan), 소형차(compact), SUV 세 종류다. 이런 입출력 구조를 가장 단순하게 모델링하는 방법이 선형회귀다.
선형회귀로 조건부 정상 범위 구하기
설명변수 하나로 응답변수를 예측하는 선형회귀부터 시작한다. 연식(year)만으로 가격(price)을 예측하는 모델을 최소제곱법(OLS)으로 학습하면, 잔차가 정규분포 를 따른다고 가정할 수 있다. 이 가정 위에서 이상 점수는 예측값과 실제값의 차이를 잔차 분산으로 정규화한 값이다.
import statsmodels.api as sm
X_train_intercept = sm.add_constant(x_train)
res = sm.OLS(y_train, X_train_intercept).fit()
slope, intercept = res.params[1], res.params[0]
residual_var = res.scale * res.df_resid / len(y_train)
train_score = (y_train - slope * x_train - intercept) ** 2 / residual_var
anomaly_threshold = np.quantile(train_score, 1 - TARGET_FP_RATE)학습 결과 slope=-121.400, intercept=3890.521, residual_var=323433.58가 나오고, 목표 오탐률 0.27%를 기준으로 한 임계값은 4.9166이다. 이론적으로 정규분포 가정 하에서 ((y-\hat y)^2/\sigma^2)의 3σ에 해당하는 값은 약 9인데, 실제 임계값은 그 절반 수준이다. 학습 데이터의 잔차 분포가 정규분포보다 극단값이 적은 형태이기 때문일 수 있는데, 이 글에서는 그 원인을 따로 확인하지 않고 경험적 분위수(np.quantile)로 실제 잔차 분포에 맞춘 값을 그대로 임계값으로 쓴다.
정상 범위(회색 띠)가 연식에 따라 기울어져 있어, 오래된 차일수록 낮은 가격도 정상으로 받아들인다. 입력 조건을 무시한 채 가격만 보고 판정했다면 불가능했을 결과다. 다만 이 모델은 추론 데이터 550건 중 15건만 이상으로 판정한다. 실제 이상 매물은 50건이므로 35건을 놓친다. 원인은 명확하다. 가격에 영향을 주는 변수가 연식 하나만은 아니기 때문이다.
이렇게 정상 거동을 회귀로 예측하고 잔차를 모니터링하는 접근은 실제 설비 진단에도 쓰인다. 콜롬비아 해군은 훈련함의 디젤 발전기에 이 방식을 적용한 이상탐지 시스템을 개발했다. 운전 조건(부하, 회전수 등)으로 온도 같은 열적 변수의 정상값을 회귀로 예측한 뒤, 실측값과의 잔차를 EWMA(지수가중이동평균)로 완화하고 시간에 따라 변하는 관리한계선과 비교해 이상 징후를 지속시간 기준으로 판정한다.
설명변수를 늘려 다변량 선형회귀로 확장하기
주행거리(odometer)와 차종(model_name)을 함께 넣으면 가격을 더 정확하게 예측할 수 있다. 차종은 범주형 변수이므로 원-핫 인코딩으로 수치화한다.
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(drop="first")
onehot_array = encoder.fit_transform(df_normal[["model_name"]].to_numpy()).toarray()나머지 학습 절차는 1변수 선형회귀와 같다. 다만 계수 w가 벡터가 되어, 이상 점수는 1변수일 때의 식을 그대로 다변량으로 확장한 형태를 갖는다.
학습 결과는 다음과 같다.
coef = [-101.350, -36.108, 461.549, 1382.990] # year, odometer, compact, suv (sedan 대비)
intercept = 3311.344
residual_var = 54771.62
anomaly_threshold = 7.6331가장 눈에 띄는 변화는 잔차 분산이다. 연식만 썼을 때 323433.58이었던 residual_var가 54771.62로 6분의 1 수준으로 줄었다. 그만큼 주행거리와 차종이 가격 변동의 상당 부분을 설명한다. 정상 범위도 훨씬 좁아져, 추론 데이터에서 이상으로 판정되는 건수가 15건에서 46건으로 늘어난다.
차종과 연식 조합마다 정상 범위의 위치와 기울기가 다르게 그려진다. 같은 주행거리라도 세단보다 SUV의 정상 가격대가 높고, 연식이 늘어날수록 정상 범위 자체가 아래로 이동한다. 설명변수 하나를 추가할 때마다 이렇게 정상 범위가 더 정교해진다.
이런 다변량 회귀는 반도체 제조 공정의 가상계측(virtual metrology)에서도 실제로 쓰인다. STMicroelectronics는 유럽 INTEGRATE 프로젝트에서 CMP(화학적 기계 연마) 공정의 웨이퍼 계측값을 설비 센서 데이터로 예측하는 회귀 기반 가상계측 모델을 실제 fab 데이터에 적용했다. 웨이퍼마다 실측을 수행하는 대신 회귀 예측값으로 대체해 계측 비용을 줄이면서, 예측값과 실측값의 차이가 크면 공정이 기준을 벗어났다는 신호로 삼는다.
다중공선성에 대비하는 리지회귀
설명변수가 늘어날수록 문제가 되는 것이 다중공선성(multicollinearity)이다. 설명변수 사이에 강한 상관관계가 있으면 최소제곱법의 계수 추정이 불안정해진다. 대표적인 해결책이 정규화이고, 선형회귀에는 L2 정규화를 적용한 리지회귀(ridge regression)가 흔히 쓰인다. 리지회귀는 최소제곱법의 잔차제곱합에 계수 크기에 대한 페널티를 더해, 그 합을 최소화하는 계수를 구한다.
정규화 강도 가 클수록 계수가 0 쪽으로 더 강하게 수축된다.
LAMBDA = 2.0
alpha = LAMBDA / 2 / len(y_train)
res = mod.fit_regularized(alpha=alpha, L1_wt=0)리지회귀는 계수를 0 쪽으로 수축시키는 대신, 예측 분산이 개별 데이터 지점의 레버리지(leverage)에 따라 달라진다. 레버리지는 그 지점이 설명변수 공간에서 학습 데이터의 중심으로부터 얼마나 떨어져 있는지를 나타내는 값이다.
정확히는 고전적인 지레값(leverage,

