본문 바로가기
카테고리 없음

효과적으로 ML기반 수요예측하는 방법(feat. data leakage)

by thrcle 2025. 3. 2.

안녕하세요 오니입니다 🍀🐰
이번 포스팅은 효과적으로 ML기반 수요예측을 적용할 때 주의해야할 점에 대해 다뤄보도록 하겠습니다. 
 

수요 예측 방법 및 종류

수요예측을 위한 방법은 크게 3가지로 나눌 수 있습니다.

 통계적 방법규칙 기반 및 휴리스틱머신러닝 및 딥러닝 
예시- 시계열 모델(이동평균, 지수평활, ARIMA)
- 회귀분석
- 비즈니스 룰 기반
- 도메인 전문가의 판단 
- 트리기반 (랜덤포레스트, XGBoost, LightGBM 등)
- LSTM
특징✔ 해석이 쉬움
✔ 비교적 적은 데이터로도 사용 가능
❌ 비선형 패턴(트렌드 변화)에 취약
✔ 데이터가 부족할 때도 적용 가능
✔ 특정 상황(이벤트, 정책 변화 등)에 유연하게 대처 가능
❌ 주관적 판단에 의존 → 객관성이 떨어질 수 있음
✔ 비선형적인 복잡한 패턴 학습 가능
✔ 다수의 피처를 활용 가능 (가격, 날씨, 이벤트 등)
❌ 학습 데이터가 많아야 효과적

 

Q. 효과적인 방법은 무엇일까?

A. 처음에는 현실세계는 매우 복잡하니까 비선형적인 복잡한 패턴을 학습하기 좋은 머신러닝, 딥러닝이 가장 효과적인 방법일 것이라고 생각했었습니다...만! 반만 맞은 생각이었습니다. ( 어떤 문제에 대한 절대적인 규칙이 있는게 아니라. 상황에 따라 접근을 다르게 해야하는게 바로 데이터사이언스의 숙명..🤔)
도메인에 따라, 예측하려는 Y의 값의 특성에 따라 효과적인 방법이 달라집니다. 우선적으로 고려할 기준은 2가지인데요.
 
1. 얼마나 변동성이 심한가? (루틴하게 반복되는 or 시각화했을 때 패턴이 보이는가? )
2. 데이터가 얼마나 있는가? (1. Y값이 얼마나 있는가? 2. 그것을 설명하는 독립변수는 얼마나 확보할 수 있는가?) 
 
💭 만약 편의점 채널 발주량 예측이라면 어떨까요?
도메인의 특성을 우선 고려해보면, 편의점은 변화가 빠릅니다. 
따라서 충분한 데이터양이 확보되지 않을 수 있고, 충분히 있다고 하더라도 그것을 설명하는 독립변수를 충분히 확보하지 못했다면, 이미 트렌드가 바뀌어 현재시점의 예측에 오히려 오차율을 높일 수 있는 요인으로 작용할 수도 있습니다. 그렇다면 이 상황에서는 복잡하고 무거운 딥러닝은 부적절할 수 있는 것이죠.
 
따라서 정리를 해보면 다음과 같습니다.
 

  • 데이터가 적은 경우 → 통계적 기반
  • 현장 판단이 필요한 경우휴리스틱 / 전문가 판단 기반
  • 충분한 데이터가 확보되어 있으며 비선형적이고 다양한 요인이 영향을 미치는 경우ML / DL 기반 

 

Q. 한가지만 선택해야 할까? 

A. 앞서 3가지로 나누긴 했지만, 실질적으로 효과적인 "수요예측" 시스템을 만들기 위해서는 모두 적용하는 경우도 많습니다.
예를 들어 "A마트의 발주량 예측 시스템"을 만든다고 가정할 때, A마트에 발주하는 상품의 갯수가 몇백개 이상 된다면 어떻게 접근해야할까요? 우선 상품의 특징을 나눠야할 것입니다. 신제품인지? 프로모션 제품인지? 등 여러 기준이 있을 것입니다. 이 때 신제품처럼 과거 주문량이 부족한 경우는 ML기반이 아니라 통계적 접근이 더 효과적일 수 있겠죠. n개월 이상 주문이 있는 경우는 ML을 활용한 예측값을 활용한다고 해도 그 값을 그대로 활용하는 것이 아니라 실제 현장 상황을 고려한 특정한 비즈니스 로직이 있을 수 있습니다. 이러한 특정 규칙을 적용하여 후보정 과정을 거쳐 나온 값을 활용한다면 하나의 예측 시스템에 통계적 접근, 규칙기반, 머신러닝 활용이 모두 사용된 사례가 되는 것입니다.



 

시계열 알고리즘의 한계 및 효과적으로 머신러닝 적용하는 방법 

전통적인 시계열 모델은 정상성(평균과 분산이 일정해야 함)이라는 조건을 만족해야 하는데, 실제 데이터는 그렇지 않은 경우가 많습니다. 또 시간외에도 Y값에 영향을 주는 변수가 있는 경우가 많다는 점을 고려하면 트리기반 모델(random forest, XGBoost, LightGBM 등)로 시도해보는 것도 좋은 선택지가 될 수 있습니다. (딥러닝은 논외로 하겠습니다)

다만 트리계열에서 날짜 변수를 활용할 때 3가지 고려할 점이 있습니다.
1. 적절한 피처 엔지니어링 과정 거치기
만일 자신이 가지고 있는 데이터의 범위가 5년치정도 되고 일단위 예측을 한다면, 월,일,요일,주차,공휴일 여부, 명절전n일,명절후n일 등으로 파생변수 생성이 가능합니다.  
만일 시간 정보도 같이 있다면 시,분,초 등 혹은 적절한 시간범위로 나누어(오전, 오후 등) 파생변수로 생성해줄 수 있습니다.

2. 최근 데이터에 가중치 부여하는 방법
트리모델은 기본적으로 순차적인 정보를 고려할 수 없지만, 고려하도록 만들 수 있습니다.  최근 데이터가 중요한 경우 최근 데이터를 가중치를 주는 파생변수를 추가하거나, XGBoost, LightGBM에서는 다음과 같이 sample_weight를 추가할 수 있습니다.

import lightgbm as lgb
import numpy as np 

weights= np.exp(np.linspace(0,2,len(y_train)))

model= lgb.LGBRegressor()
model.fit(X_train, y_train, sample_weight=weights)


3. 시간 지연 변수(Lag feature) 활용
최근 데이터에 가중치를 부여하는 또 다른 방법으로 과거 주문량을 변수로 활용하는 방법도 있습니다. ‘n일전주문량합’ 또는 ‘n일전주문량평균‘ 혹은 최근이 더 높도록 가중치를  차등하고 싶다면 ’n일전선형가중평균‘, ’n일전지수가중평균‘ 과 같이 파생변수를 만드는 것도 좋습니다.

다만 적용할 때 주의할 점은
1. lag변수를 활용하기 위해서는 데이터를 시간순으로 정렬 후 적용해야 하며
2. 과거의 y값을 독립변수로 활용한다는 개념이기 때문에 *data leakage가 발생하지 않도록 주의해야 합니다. (반드시 ‘과거’의 값만 활용하도록!)


*Data leakage란?

Data leakage란 머신러닝 모델이 미래 데이터를 학습하는 문제를 의미합니다.
미래 데이터를 학습하게 되면 미래정보를 가지고 예측을 하는 것이 되므로 지속 불가한 방법이며 과대적합이 발생하게 됩니다.
이 부분은 모델을 고도화하는 과정에서 의도치 않게 발생할 수 있는 부분이라 주의가 필요한데요.

1. 이상치 제거시 전체 데이터 기준으로 이상치 범위를 잡은 경우 
-> train data 기준으로만 이상치범위를 설정하여 제거해야 합니다.
 
2. 전처리 과정에서 결측값 보완을 위해 전체 데이터의 평균값으로 채운 경우
-> train data set내에서의 평균값을 사용해야 합니다.