-
1. 이상치
이상치는 데이터셋에서 다른 관측치들과 동떨어진 값이며 잘못된 결과나 오류를 유발할 수 있기 때문에 이상치를 식별하고 적절하게 처리하는 것이 중요하다.
이상치는 예측하기 어려우며 처리하는 과정에서 데이터의 특성을 변경할 수도 있고 주관적인 해석이 이루어질 수 있다. 대용량으로 이상치를 처리하는 것은 더욱 어려우며 이상치를 탐지하는 것은 어려운 일이기 때문에 강력한 알고리즘과 지식이 필요하다.
이러한 이상치를 처리하기 위한 방법이 평활(smoothing)이며 스무딩은 잡음이나 불규칙한 변동을 완화시키기 위해 데이터의 추세나 패턴을 부드럽게 만드는 방법이다. 대표적으로 이동평균과 지수 평활법이 있다.
2. 이동 평균법(moving average)
이동 평균법은 일정 기간별 이동 평균을 계산하고 이동 표준 편차를 통해 추세와 변동성을 파악하여 미래를 예측하는 방법이다.
import pandas as pd import numpy as np import matplotlib.pyplot as plt pd.set_option('display.max_rows',500) np.random.seed(12) dates = pd.date_range(start='2023-01-01',periods=500,freq='d') values = np.random.randn(500) data = pd.DataFrame({'date':dates,'value':values}) window_size = 7 data['movingaverage'] = data['value'].rolling(window=window_size).mean() data['movingstd'] = data['value'].rolling(window=window_size).std()
pandas의 display.max_row 옵션은 정해진 개수를 초과하면 자르기 보기로 전환한다. 500개의 시간 값과 500개의 랜던값을 생성해 주고 데이터 프레임으로 생성한다. rolling 함수 데이터의 크기를 잘라주는 함수이다. value에서 rolling 하수를 적용하고 window 사이즈를 7로 설정하면 7개씩 잘라준다. mean과 std 함수를 각각 적용하여 전의 7개 데이터의 이동평균과 표준편차를 구한다.
thershold = 2 data['threshold'] = data['movingaverage'] + thershold* data['movingstd'] data['outlier'] = data['value'] > data['threshold'] plt.figure(figsize=(10,6)) plt.subplot(2,1,1) plt.plot(data['date'],data['value']) plt.xlabel('date') plt.ylabel('value') plt.title('original data') plt.show() plt.subplot(2,1,1) plt.plot(data['date'],data['value'], label='value') plt.plot(data['date'],data['movingaverage'], label='moving average') plt.plot(data['date'],data['threshold'], label='threshold') plt.scatter(data[data['outlier']]['date'], data[data['outlier']]['value'], color = 'red', label =' outlier') plt.xlabel('date') plt.ylabel('value') plt.title('outlier detection with moving average and mpving sandard deviation') plt.legend() plt.tight_layout() plt.show()
threshold 임계값은 이동평균 + 2 * 이동표준편차를 적용시켜서 구한다. outlier 이상치는 이 기준을 초과할 경우 이상치로 설정한다. 그래프를 기존의 데이터프레임의 데이터만 포함한 시간에 따른 랜덤값의 그래프를 그리고 위에서 설정한 임계값, 이상치 이동평균을 데이터와 같이 출력하여 비교한다.
이동평균 그래프는 7개의 데이터를 평균을 냈기 때문에 그래프의 모양을 전반적으로 따라가는 추세를 확인할 수 있고 ㅇ미계값 공식을 적용한 임계값 그래프는 이상치를 탐지할 수 있다.
3. 지수 평활법(exponential smoothing)
지수 평활법은 최근의 관측값에 더 높은 가중치를 부여하고, 과거의 관측값일수록 작은 가중치를 부여하여 지수적으로 과거의 비중을 줄여 예측을 하는 방법이다.
일반적으로 시계열 자료들은 시간에 흐름에 따라 여러가지 요소로 인해 관측 가중치가 달라질 수 있다. 따라서 과거와 현재에 모두 동일한 가중치를 부여하는 것보다 최근의 관측값에 더 높은 가중치를 부여하여 예측하는 것이 효과적일 수 있다.
from statsmodels.tsa.holtwinters import ExponentialSmoothing dates = pd.date_range(start='2023-01-01',periods=100, freq='d') values = [10,12,11,15,19,13,8,14,10,16]+[10] *90 data = pd.DataFrame({'date':dates , 'value':values}) model = ExponentialSmoothing(data['value'],trend='add') model_fit = model.fit() trend = model_fit.predict(start = 0, end = len(data['value'])-1) deviation = data['value'] - trend
100개의 시간 데이터와 10, 90개의 10과 10개의 랜던값으로 데이터프레임을 생성한다. add 계절성으로 선형적 추세의 지수평활법을 적용시킨다. model_fit.predict 메서드에 전체기간을 입력하여 예측 값을 생성하고 기존 값에 예측 값을 빼서 편차를 계산한다.
threshold = 2 outliers = abs(deviation) > threshold plt.plot(data['date'],data['value'], label='original') plt.plot(data['date'],trend, label='trend') plt.scatter(data[outliers]['date'], data[outliers]['value'], color = 'red', label =' outlier') plt.xlabel('date') plt.ylabel('value') plt.title('outlier detection with moving average and mpving sandard deviation') plt.legend() plt.show()
abs로 편차를 절대값으로 설정하여 음수의 경우에도 임계값을 추출할 수 있도록 설정하고 임계값을 2로 설정하여 편차가 -2 또는 2를 넘어갈 경우 이상치로 설정한다. 그래프로 출력하여 추세와 편차 임계값을 확인한다.
'통계' 카테고리의 다른 글
통계-16 ar, ma, arma, arima, sarima (0) 2023.06.04 통계-15 정규화, 표준화, 변환 (0) 2023.06.04 통계-13 결측치 (0) 2023.06.01 통계-12 시계열 데이터 (0) 2023.05.31