대시보드 활용 품질관리

Chapter.6 대시보드 활용 품질관리(8)

devjjun 2026. 5. 21. 15:15

TIL(Today I Learned)


1️⃣시계열 분석 정리(1)

시계열 분석이란?

기존의 통계학이 '현상'을 분석했다면, 시계열 분석은 '맥락'을 분석

시계열 데이터의 형태 

  1. 계절성
  2. 추세변동
  3. 계절적 추세변동
  4. 순환변동
  5. 우연변동

시계열 데이터의 특징 

  • 시간 순서의 연속성
  • 이전 값과 현재 값의 상관(자기상관성)
  • 시간 간격이 일정

1)연속된 측정값이지만 비시계열 풀기

Timestamp 압력(압력 lag) 온도(℃) 전류(A) 품질결과
2025-07-01 00:00:00 2.10 55.3 1.10 OK
2025-07-01 00:01:00 2.15 (2.10) 55.5 (55.3) 1.12 OK
2025-07-01 00:02:00 2.00 58.1 1.30 NG
현재 시점의 센서 값만 보고 품질 판별

2)연속된 측정값이지만 시계열 풀기

Timestamp 전압(V) 전류(A) 온도(℃) 자동차 배터리 량 (예측 대상) 자동차 배터리 변화량
2025-07-01 08:00:00 370.2 21.5 34.1 97.5  
2025-07-01 08:01:00 370.2 21.5 34.1 97.4 0.1
2025-07-01 08:02:00 370.2 21.5 34.1 97.3 0.1
2025-07-01 08:03:00 369.5 22.8 34.5 97.1 0.2
선형 회귀의 관점에서 
출력값 자체보다는 이전 상태로부터 얼마나 변화했는지(변화량 Δy)가 중요하다

차분(diff())

  • 이전 시점 값과 현재 값의 차이(변화량)를 계산 
df['diff_1'] = df['기준 컬럼'].diff(1)  # 이전 값과의 차이 계산

 

시계열 데이터 Feature Engineering

  1. 날짜를 년, 월, 일로 나누기 => 주기성, 특정 날짜 같은 세부정보를 모델에 제공 
    1. 날짜형식으로 변환: to_datetime()
    2. 날짜 요소 뽑기: .dt
      • 월별/분기별/계절별 패턴을 모델이 인식
      • 다양한 주기적인 변동 예측 가능
  2. Lag Feature => 과거의 데이터를 새로운 입력으로 추가하는 것
    1. 사용 이유: 과거가 현재에 영향을 줄 수 있기 때문
    2. 사용 방법: df['lag_1'] = df['value'].shift(1)
  3. Rolling Statistics => 지정한 범위(window) 내에서 통계값을 계산하는 방법(평균, 표준편차 등)

  • 📌윈도우(Window): 시계열 데이터에서 과거 일정한 개수만큼 묶은 구간
  • 윈도우 크기 지정: 도메인 지식 + 데이터 주기성
# 3분 이동 평균과 이동 표준편차
df['전류_이동평균'] = df['전류(A)'].rolling(window=3).mean()
df['전류_이동표준편차'] = df['전류(A)'].rolling(window=3).std()

 

 

    4. diff feature(변화량 feature)

  • diff feature 추가 이유
    1. 변화 자체가 의미 있는 경우가 많다. ex) 전류의 증가(이상징후), 특정 센서 상승(공정 이상 가능성)
    2. 추세나 패턴을 모델이 인식 가능. 원본 값은 "상태"만 인식 => 변화량은 "방향, 속도" 파악 가능

관리도(Control Chart)

공정(Process)의 변동을 통제된 상태로 유지하는 것이 생산량을 예측하고 효과적으로 관리하는 방법

목적

  • 공정(Process) 자체를 관리하여 문제가 발생하기 전 사전 예방
  • 이상 요인이 발생하면 즉각 수정하여 불량 억제
  • 공정의 변동을 효율적으로 관리하여 품질 유지 및 향상

평균을 중심으로 양측의 표준편차의 1배(1σ), 2배(2σ), 3배(3σ)의 폭을 기준으로 각 구간내 들어가는 비율은 각각 68.26%, 95.46%, 99.73%

관리도(Control Chart)의 해석

  • Zone C (-1σ ~ +1σ, 초록색 영역)
    • 데이터의 대부분(약 68.26%) → 정상적인 공정 상태
    • 값이 이 영역 내에 머물면 공정이 안정적이라고 판단 가능
  • Zone B (-2σ ~ -1σ, +1σ ~ +2σ, 노란색 영역)
    • 데이터의 약 27.2%가 포함
    • 일부 이상 징후가 나타날 수 있는 경고 영역(Warning Zone)
    • 값이 지속적으로 머문다면, 공정 이상을 의심
  • Zone A (-3σ ~ -2σ, +2σ ~ +3σ, 빨간색 영역)
    • 데이터의 약 4.2%가 포함
    • 이 영역을 초과하면(±3σ 이상) 공정이 이상 상태 의미
    • 즉각적인 원인 분석 및 조치가 필요함

통계적 시계열 모델 전처리

statsmodels 라이브러리

  • 시계열 데이터를 추세, 계절성, 불규칙성 성분으로 나누어 plot 그리는 작업
더보기
from statsmodels.tsa.seasonal import seasonal_decompose
decomposition = seasonal_decompose(df2['#Passengers'],
 model='multiplicative', period=12)
# model='multiplicative' model='additive'
# 분해된 성분 출력
fig = decomposition.plot()
plt.show()

      1. Additive (덧셈 모델): 추세+계절성+잔차 (변화량이 일정한 크기로 발생하는 데이터에 적합)
      2. multiplicative(곱셈 모델): 추세×계절성×잔차 (분들이 곱해지는 모델로, 변화가 비율적으로 증가 데이터에 적합
      3. 잔차 (Residuals): 원본 데이터에서 추세와 계절성을 제거한 후 남는 변동성 만약, 잔차(Residual)에 특정 패턴이 보이면 추가적인 계절성이나 주기성이 존재할 가능성이 있음

비정상성 데이터란?

  • 시간이 지날수록 데이터의 평균(Trend)이 증가/감소하는 경우 (추세)
  • 계절성(Seasonality) 이 포함되어 특정 주기마다 패턴이 달라지는 경우
  • 시간이 지날수록 데이터의 변동성(Variance)이 증가하는 경우

정상성 데이터란?

정상적이다. (Stationary) = 안정적이다.

  • 추세(Trend)나 계절성이 없고, 데이터의 평균과 분산이 일정한 경우
  • 주어진 시간 간격에서 변동성이 안정적이며 예측 가능한 수준
  • 시계열의 통계적 특징(평균, 분산, 자기 상관)이 변하지 않는다. (일정한 패턴을 유지)
  • 랜덤한 움직임을 가지지만, 시점마다 유사하게 동작하는 특징이 있어 시간에 따라 안정된 분포를 갖는다
정상성 데이터 변환 이유: ARIMA 분석을 통해 미래 시계열 값 예측 가능

정상성 데이터로 변환 방법

1) 차분: 추세를 제거하여 정상성으로 변환 

# 첫 번째 차분 (1st differencing)
df['1st_diff'] = df['value'].diff()
# 두 번째 차분 (2nd differencing)
df['2nd_diff'] = df['1st_diff'].diff()

 

2) 로그 변환: 선형적이고 정규분포에 가까운 형태로 변환

# 로그 변환
df['log_value'] = np.log(df['value'])

 

3) 로그 차분: 추세와 변동성(Variance)을 동시에 안정화하기 위해 사용하는 변환

# 로그 변환
df['log_value'] = np.log(df['value'])
# 로그 차분
df['log_diff'] = df['log_value'].diff()

 

4) 계절 차분: 일정한 주기로 반복되는 계절성(Seasonality)을 제거하는 방법

# 계절 차분 적용 (s=12개월 주기)
df['Seasonal_Diff'] = df['Sales'].diff(periods=12)

ARIMA 모델 

ACF (자기상관 함수): 시계열 데이터의 특정 시점과 이전 시점 간의 상관 관계 나타내는 함수

# ACF (자기상관 함수) 그래프 그리기
plt.figure(figsize=(8, 6))
plot_acf(df, lags=10, ax=plt.gca())
plt.title("ACF (자기상관 함수)")
plt.show()

 

PACF (부분 자기상관 함수): 단순히 이전의 시점 간 상관만을 고려하는 것이 아니라, 특정 시점의 값이 이전의 값들과 어떻게 관계가 있는지를 고려하여 직접적인 상관만을 추출하는 함수

# PACF (부분 자기상관 함수) 그래프 그리기
plt.figure(figsize=(8, 6))
plot_pacf(df, lags=10, ax=plt.gca())
plt.title("PACF (부분 자기상관 함수)")
plt.show()

ARIMA 모델

시계열 데이터의 자기상관성(AR), 차분(D), 이동 평균(MA)을 이용해 미래 값을 예측하는 시계열 통계 모델

더보기
import pandas as pd
from statsmodels.tsa.arima.model import ARIMA,


# ARIMA 모델 정의 (p=1, d=1, q=1 예시)
model = ARIMA(df, order=(1, 1, 1))  # p=1, d=1, q=1
model_fit = model.fit()

# 예측 (5단계 예측)
forecast = model_fit.forecast(steps=5)

2023-06-01 => 7,8 ,9, 10 , 11
# 예측 결과 출력
print("예측 결과:", forecast)

ARIMA(p,d,q 선정)

d : 시계열 plot을 보고 정상성 여부를 확인하고, 차분을 진행

차분 후의 plot을 보고 여부를 확인하는 프로세스로 진행 d= 1, d=2

1차 차분으로도 추세가 완전히 제거되지 않는 경우 2차 차분을 적용하여 데이터의 평균과 분산을 일정하게 만듬

 

p: PACF에서 첫 번째 유의미한 지점(즉, 자기상관이 급격히 0으로 떨어지는 시점)을 p 값 1

q: ACF에서 첫 번째 유의미한 지점(즉, 자기상관이 급격히 0으로 떨어지는 시점)을 q 값 0

결론 : ARIMA(1, 2, 0)

ACF와 PACF를 통해서 비정상성 분석이 가능

  • ACF 값이 느리게 감소(서서히 감소)하는 패턴을 보임 ⇒ 트렌드(추세, Trend)나 계절성을 포함하고 있을 가능성 높음
  • 여러 시차(Lag)에서 지속적으로 유의미한 값 → 추세(Trend) 제거 필요 특정 주기마다 강한 피크를 가짐 → 계절성(Seasonality) 제거 필요

AR(p)

현재 값이 과거 값들의 선형 결합으로 표현되는 모델(추세가 강한데이터)

MA(q)

현재 값이 과거 오차(White noise)의 선형 결합으로 표현되는 모델 과거의 오차를 기반으로 미래를 예측

AR(p)+MA(q)

자기회귀(AR) + 이동 평균(MA) 요소를 동시에 반영

SARIMA 모델

ARIMA 모델에 계절성(Seasonality)을 추가한 확장 모델

수식

  • (P, D, Q, s): 계절성 차수
    • P: 계절성 자기회귀(Seasonal AR)
    • D: 계절 차분(Seasonal Differencing)
    • Q: 계절성 이동 평균(Seasonal MA)
    • s: 계절 주기(예: 월별 데이터 → 12, 주별 데이터 → 52)
    (P, D, Q, s) 찾기
    • s (계절 주기) 결정
      • 데이터가 주별이면 s=52, 월별이면 s=12 사용
    • D (계절 차분 차수) 찾기 diff(periods = 12)
      • 계절 주기(s)만큼 차분 수행 후 정상성이 확보되면 D=1
      • 필요하면 추가 차분
    • P, Q 찾기
      • 계절 차분 후, ACF/PACF에서 계절 패턴을 분석하여 결정

특징

  • 계절성이 있는 데이터에 적합
  • 비정상성 + 계절성까지 해결 가능
더보기
from statsmodels.tsa.statespace.sarimax import SARIMAX

# SARIMA 모델 학습 (p, d, q) × (P, D, Q, s)
model = SARIMAX(df['Value'], order=(2, 1, 2), seasonal_order=(1, 1, 1, 12))
result = model.fit()
df['SARIMA_Prediction'] = result.predict()
df[['Value', 'SARIMA_Prediction']].plot()

2️⃣Streamlit 대시보드 완전 정복 4회차

Streamlit 문법 요약

페이지 설정

st.set_page_config(layout="wide")

사이드바

with st.sidebar:
    st.selectbox("라인", ["A", "B"])

컬럼 분할

c1, c2 = st.columns(2)

빈 공간 생성

placeholder = st.empty()

컨테이너

with st.container(border=True):
    st.write("내용")

tab1, tab2 = st.tabs(["요약", "상세"])

펼치기

with st.expander("더보기"):
    st.write("내용")

팝오버

with st.popover("필터"):
    st.checkbox("이상치 제거")

Form

with st.form("form"):
    name = st.text_input("이름")
    submit = st.form_submit_button("저장")

네이티브 차트

st.line_chart(df)
st.bar_chart(df)
st.area_chart(df)
st.scatter_chart(df)
st.map(df)

Plotly

st.plotly_chart(fig)

Matplotlib

st.pyplot(fig)

Altair

st.altair_chart(chart)

데이터 편집기

st.data_editor(df)

column_config

st.column_config.NumberColumn()
st.column_config.ProgressColumn()
st.column_config.CheckboxColumn()
st.column_config.SelectboxColumn()

💡 느낀점

시계열에 대해 요약하며 공부를 진행하다 보니, 제공받은 시계열 관련 문제를 막힘없이 해결할 수 있었다. 또한 모델 이론을 학습할 때 단순 암기보다 어떤 상황에서 어떤 용도로 사용되는지 차이점 위주로 이해하니 훨씬 와닿았다. Streamlit을 학습하며 다양한 함수를 활용해 인터랙티브한 전달을 할 수 있는것이 인상깊었다. 이후에는 Streamlit을 활용해 만든 대시보드를 깃을 통해 배포하는 과정을 진행할 예정이다.