2025 내일배움캠프 QAQC_2기

2025 내일배움캠프 QAQC_2기 본캠프 56일차

mingdoremi 2025. 7. 30. 20:42

안녕하세요! 오늘은 본 캠프 56일차입니다!

 

오늘 실전 프로젝트를 시작했습니다!!

저희 팀은 반도체 도메인을 선택했습니다!

시계열 데이터가 없어서 아쉽긴 하지만 시계열 데이터가 아직은 너무 어려워요..

 

<시계열 라이브 세션>

Derivative (기울기, 변화량) 기반 탐지

  • 개념: 값 자체가 아니라, 변화량에 이상 탐지 적용
  • 활용 예시:
    • 5초 내에 온도가 10도 이상 급등 → 이상
    • 전류가 1초에 3A 이상 급격히 상승
import numpy as np
import matplotlib.pyplot as plt

# 예시 시계열: 100 이후 급변
data = np.concatenate([
    np.linspace(0, 1, 100),
    np.linspace(1, 10, 20),
    np.linspace(10, 11, 80)
])

# 변화량(기울기) 계산
gradient = np.diff(data)
threshold = 0.1  # 기울기 임계값

# 이상 지점 감지
anomalies = np.where(np.abs(gradient) > threshold)[0]

# 시각화
plt.figure(figsize=(10, 4))
plt.plot(data, label="Signal")
plt.scatter(anomalies, data[anomalies], color='red', label="Anomalies")
plt.title("Derivative-based Anomaly Detection")
plt.legend()
plt.grid(True)
plt.show()

 

변화량(기울기)을 감시하면 정상 범위 안의 급격한 변화도 잡을 수 있음

 

Moving Average + Change Point Detection

  • 기법: 일정 구간의 평균/분산과 현재 값을 비교 → 급변 시점 감지
  • 도구: ruptures, changefinder, Bayesian Change Point

ruptures는 시계열 데이터에서 변화점(change point) 을 감지하는 데 사용되는 Python 라이브러리, 변화점 감지(change point detection)는 데이터의 통계적 성질(평균, 분산 등)이 변하는 시점을 찾아내는 것이 목적

import numpy as np
import ruptures as rpt
import matplotlib.pyplot as plt

# 시계열 신호 생성
signal = np.concatenate([
    np.random.normal(1, 0.1, 100),
    np.random.normal(5, 0.1, 100),
    np.random.normal(3, 0.1, 100)
])

# 모델 및 알고리즘 선택
model = "rbf"  # 비선형 변화 감지
algo = rpt.Pelt(model=model).fit(signal)
result = algo.predict(pen=10)  # pen 값으로 민감도 조절

# 시각화
rpt.display(signal, result)
plt.title("Ruptures - Change Point Detection")
plt.show()

이동 평균(Moving Average) 기반의 간단한 이상치 탐지(Anomaly Detection)

import numpy as np
import matplotlib.pyplot as plt

# 예시 시계열
data = np.concatenate([
    np.random.normal(0, 0.1, 100),
    np.random.normal(3, 0.1, 100)
])

# 이동 평균
window = 10
moving_avg = np.convolve(data, np.ones(window)/window, mode='same')

# 이동 평균 기준 변화량 계산
diff = np.abs(data - moving_avg)
threshold = 0.5  # 변화량 기준

# 이상 지점
anomalies = np.where(diff > threshold)[0]

# 시각화
plt.figure(figsize=(10, 4))
plt.plot(data, label="Signal")
plt.plot(moving_avg, label="Moving Average", linestyle='--')
plt.scatter(anomalies, data[anomalies], color='red', label="Anomalies")
plt.title("Moving Average + Change Detection")
plt.legend()
plt.grid(True)
plt.show()

ChangeFinder 알고리즘을 사용한 이상 탐지 / 변화 탐지

ruptures 나 moving average 방식과는 다르게, 실시간환경에 적합하고, 통계 기반으로 설계된 알고리즘

import changefinder
import numpy as np
import matplotlib.pyplot as plt

# 시계열 데이터 생성
data = np.concatenate([
    np.random.normal(1, 0.1, 100),
    np.random.normal(5, 0.1, 100),
    np.random.normal(3, 0.1, 100)
])

# ChangeFinder 초기화
cf = changefinder.ChangeFinder(r=0.01, order=1, smooth=5)

# 점수 계산
scores = [cf.update(d) for d in data]

# 시각화
plt.figure(figsize=(10, 4))
plt.plot(data, label="Signal")
plt.plot(scores, label="Anomaly Score")
plt.title("ChangeFinder - Anomaly Detection")
plt.legend()
plt.show()

CUSUM (Cumulative Sum Control Chart) 알고리즘을 이용한 변화 탐지 (Change Detection)

CUSUM은 통계적 공정 관리(SPC)에서도 많이 쓰이며, 평균이 갑자기 변하는 시점을 빠르게 포착할 수 있는 강력한 방법

import numpy as np
import matplotlib.pyplot as plt

# 예제 데이터
data = np.concatenate([
    np.random.normal(0, 1, 100),
    np.random.normal(4, 1, 100)
])

target_mean = np.mean(data[:50])
k = 0.5  # 민감도 조절
h = 5    # 임계값

cusum_pos = [0]
cusum_neg = [0]
anomalies = []

for i in range(1, len(data)):
    s_pos = max(0, cusum_pos[-1] + data[i] - target_mean - k)
    s_neg = max(0, cusum_neg[-1] - data[i] + target_mean - k)
    cusum_pos.append(s_pos)
    cusum_neg.append(s_neg)
    if s_pos > h or s_neg > h:
        anomalies.append(i)

plt.plot(data, label="Signal")
plt.scatter(anomalies, data[anomalies], color="red", label="Change Detected")
plt.title("CUSUM Change Detection")
plt.legend()
plt.show()

Bayesian Online Change Point Detection (BOCPD) 알고리즘을 사용하여 시계열 데이터에서 변화점(분포가 바뀌는 지점) 을 실시간으로 탐지 BOCPD는 변화가 일어날 확률을 베이지안적으로 추론하며, 새로운 관측마다 변화 가능성을 업데이트하여 실시간으로 변화점을 탐지하는 강력한 알고리즘

%matplotlib inline
import numpy as np
np.random.seed(555)
import matplotlib.pyplot as plt
import bocd

test_signal = np.concatenate(
    [np.random.normal(0.7, 0.05, 300), 
     np.random.normal(1.5, 0.05, 300),
     np.random.normal(0.6, 0.05, 300),
     np.random.normal(1.3, 0.05, 300)])
plt.plot(test_signal)


bc = bocd.BayesianOnlineChangePointDetection(bocd.ConstantHazard(10), bocd.StudentT(mu=0, kappa=1, alpha=1, beta=1))


rt_mle = np.empty(test_signal.shape)
for i, d in enumerate(test_signal):
    bc.update(d)
    rt_mle[i] = bc.rt 

plt.plot(test_signal, alpha=0.5, label="observation")
index_changes = np.where(np.diff(rt_mle)<0)[0]
plt.scatter(index_changes, test_signal[index_changes], c='green', label="change point")

 

Variance-based Rule

Variance-based Rule은 일정한 기간(슬라이딩 윈도우 또는 구간) 동안의 분산(혹은 표준편차) 을 계산하고,

그 분산이 사전에 설정한 임계값(threshold)을 초과하면, “여기서 뭔가 변화가 생겼다(또는 이상하다)”

라고 판단하는 방식입니다.

 

왜 분산을 기준으로 삼는가?

  • 정상 구간은 일반적으로 분산이 작고 일정합니다.
  • 이상 구간은 평균이 바뀌거나, 급격한 값의 진동이 생기며 분산이 커집니다.
  • 따라서 분산이 갑자기 튀는 지점을 이상 또는 변화점으로 탐지할 수 있습니다.

Guassian Tail Probability

정규분포(Gaussian distribution) 를 따르는 데이터에서, 평균으로부터 특정 거리 이상 떨어진 값이 나올 확률이 확률은 곧 "이 값이 정상 구간 밖에 있을 가능성" 이며, 일종의 이상치(outlier) 점수로 활용할 수 있어요.

  • 이상치 탐지: 꼬리 확률이 매우 작으면 "이 값은 정상 분포에서 거의 안 나오는 값 → 이상"
  • p-value 계산: 통계 검정에서 유의확률(p-value)을 계산할 때도 tail probability 사용
  • 확률적 스코어링: 확률 기반 이상 탐지에 사용
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

x = np.linspace(-5, 5, 1000)
y = norm.pdf(x, 0, 1)

plt.plot(x, y, label='Gaussian PDF')
plt.fill_between(x, y, where=(x > 2), color='red', alpha=0.3, label='Right Tail (Z > 2)')
plt.fill_between(x, y, where=(x < -2), color='blue', alpha=0.3, label='Left Tail (Z < -2)')
plt.title("Gaussian Tail Probability")
plt.legend()
plt.grid(True)
plt.show()

 

오늘 프로젝트는 데이터를 이해하고 가설을 설정했습니다!

내일부터는 전처리, 분석, 시각화를 차례로 할 것 같아요!

 

오늘도 수고하셨습니다!!