재고를 위한 수요 예측: 손실은 비대칭적이다
요약
재고 관리를 위한 수요 예측 시, 과소 재고와 과잉 재고의 비용이 비대칭적임을 설명합니다. 단순 평균 예측 대신 비용 행렬을 기반으로 최적의 분위수(quantile)를 예측하는 것이 중요함을 강조합니다.
핵심 포인트
- 수요 예측의 목적은 단순 평균값이 아닌 최적의 주문 결정을 위한 입력값 제공임
- 재고 부족 비용과 과잉 재고 비용이 다를 경우 평균 예측은 부적절함
- 비용 비율에 따라 목표 분위수(Critical fractile)를 결정해야 함
- 수요 분포의 중심이 아닌 경제적 비용을 반영한 분위수를 예측해야 함
수요 예측 (Demand forecast)은 최종 결과물이 아닙니다. 그것은 주문 결정 (ordering decision)을 위한 입력값이며, 그 결정은 비대칭적입니다. 즉, 재고가 부족하면 마진 손실 (lost margin)이 발생하고, 너무 많이 주문하면 재고 처분 손실 (markdown)이 발생합니다. 이 두 수치가 다를 때, 최적의 주문량은 기대 수요 (expected demand)가 아니며, 그 둘 사이의 간극은 정확하게 계산할 수 있습니다.
평균은 예측하기에 잘못된 수치이다
거의 모든 예측 튜토리얼은 평균 제곱 오차 (Mean Squared Error, MSE)를 최소화하며, 이 경우 최적의 예측값은 조건부 평균 (conditional mean)입니다. 이는 양방향의 오차 비용이 동일할 때 적절한 목표입니다. 하지만 재고 관리에서는 결코 그렇지 않습니다.
단위당 마진이 £12이고, 팔리지 않은 제품에 대한 재고 처분 손실 (markdown loss)이 £4인 제품을 예로 들어보겠습니다. 재고를 확보하지 못한 모든 단위는 얻을 수 있었던 £12의 마진을 비용으로 치르게 합니다. 과잉 재고가 된 모든 단위는 £4의 비용을 발생시킵니다. 부족한 상황이 남는 상황보다 세 배 더 비싸기 때문에, 평균적으로는 맞더라도 대부분의 시간 동안 잘못된 정책이 되는 예측을 하게 됩니다.
이 교정 작업은 예측값에 단순히 덧붙이는 임의의 계수 (fudge factor)가 아닙니다. 그것은 예측해야 할 대상 자체가 다른 것입니다. 즉, 수요 분포 (demand distribution)의 중심이 아니라 분위수 (quantile)를 예측하는 것입니다. 어떤 분위수를 선택할지는 취향의 문제가 아니며, 이는 비용 행렬 (cost matrix)로부터 결정 임계값 (decision threshold)을 도출하는 것과 동일한 작업입니다. 경제적 요인이 운영 지점 (operating point)을 결정하며, 모델은 단지 경제학이 필요로 하는 수치를 생성하도록 요구받을 뿐입니다.
도출된 임계 분위수 (Critical fractile)
$C_u$를 과소 재고 비용 (underage cost, 부족한 단위당 비용)이라 하고, $C_o$를 과잉 재고 비용 (overage cost, 팔리지 않은 단위당 비용)이라고 합시다. 이미 $Q$만큼 주문하기로 결정했을 때, 한 단위를 더 주문할지 여부를 고려해 보겠습니다.
그 추가 단위는 수요가 $Q$를 초과할 때만 판매되며, 이는
확률 $1 - F(Q)$로 발생합니다. 여기서 $F$는 수요 누적 분포 함수 (demand CDF)입니다.
...
분할점(fractile)이 이론의 핵심입니다. 이는 목표 분위수(target quantile)가 두 비용의 비율에 의해 전적으로 결정된다는 것을 의미하며, 두 가지 극단적인 경우를 정확하게 도출합니다. 즉, 과잉 재고(overstock) 비용이 0이면 분할점은 1(모든 것을 주문)이 되고, 품절(stockout) 비용이 0이면 분할점은 0(아무것도 주문하지 않음)이 됩니다. 평균(mean)은 $C_u$가 $C_o$와 같고 분포가 대칭인 특수한 경우에만 최적입니다.
예제: 무엇을 주문할 것인가
한 기간 동안 한 제품에 대한 이산 수요 분포(discrete demand distribution)입니다. 계산 과정을 처음부터 끝까지 확인할 수 있도록 임의로 설정했습니다.
수요 (demand) 확률 (probability) 누적 분포 (cumulative F)
70 0.15 0.15
90 0.20 0.35
...
이제 각 정책의 비용을 계산합니다. 총 기대 비용(Total expected cost)은 $C_o$에 기대 잔여 재고(expected leftover)를 곱한 값과 $C_u$에 기대 부족분(expected shortfall)을 곱한 값의 합입니다.
Cost(Q) = 4 * E[max(Q - D, 0)] + 12 * E[max(D - Q, 0)]
Q = 100 (대략적인 평균)
...
분할점(fractile)만큼 주문할 때의 비용은 기간당 £110입니다. 평균(mean)만큼 주문할 때의 비용은 £158입니다. 이는 기간당 £48, 즉 총 비용의 30%에 달하는 차이입니다. 이 차이는 더 나은 모델, 더 많은 데이터, 추가적인 피처(feature) 없이 오직 예측값이 보고하는 숫자만을 변경함으로써 얻을 수 있습니다. 천 개의 SKU와 52개 기간에 걸쳐 적용하면 이는 매우 큰 수치이며, 대부분의 예측 프로젝트에서 얻을 수 있는 단일 항목 중 가장 높은 수익률입니다.
30%라는 수치는 위에서 임의로 설정한 분포에 기반한 산술적 결과일 뿐, 특정 기업의 재고 상황에 대한 주장은 아닙니다. 일반화할 수 있는 것은 방법론입니다. 자신만의 $C_u$와 $C_o$를 계산하고, 분할점을 구한 뒤, 자신의 수요 분포에 대해 두 정책의 가격을 비교해 보십시오. 두 비용의 차이가 커질수록 격차는 벌어지며, 두 비용이 같아지면 격차는 사라집니다.
분위수를 예측하기 위한 모델 학습
표(table)가 아닌 모델로부터 75백분위수(75th percentile)를 얻으려면, 구조적으로 과소 예측(under-prediction)과 과대 예측(over-prediction)에 대해 서로 다른 비율로 페널티를 부여하는 핀볼 손실(pinball loss, 분위수 손실)을 사용하여 모델을 학습시키십시오.
분위수 $\tau$에서의 핀볼 손실 (pinball loss):
L(y, f) = \tau * (y - f) y >= f 일 때 (과소 예측, under-forecast)
...
마지막 줄은 유념할 가치가 있습니다. 학습 시 사용하는 분위수 (quantile)는 비용 비율 (cost ratio)을 인코딩하므로, $\tau$를 설정하는 것과 $C_u/C_o$를 설정하는 것은 동일한 행위입니다. 따라서 이 둘 사이에 불일치가 있다면, 누군가가 경제적 논리를 수동으로 무시했다는 것을 의미합니다.
from sklearn.ensemble import GradientBoostingRegressor
CU, CO = 12.0, 4.0
...
분위수 예측 (quantile forecast)은 평균 절대 오차 (MAE)가 아니라 핀볼 손실 (pinball loss)로 평가해야 합니다. 75백분위수 (75th-percentile) 예측은 실제 값보다 높은 위치에 4분의 3의 시간 동안 위치해야 하므로, MAE로 측정하면 결과가 매우 나쁘게 나오고 편향 (bias)이 결함처럼 보일 수 있습니다. 해당 예측이 학습된 손실 함수로 점수를 매기는 것만이 의미 있는 유일한 비교 방법이며, 실제 값이 예측값보다 낮은 비율을 나타내는 커버리지 확인 (coverage check) 결과는 0.75에 근접해야 합니다. 이 커버리지 확인은 신뢰도 표 (reliability table)의 회귀 분석 버전이며, 동일한 이유로 실패할 수 있습니다.
리드 타임 (Lead time), 그리고 예측 지평 (horizon)이 한 주기가 아닌 이유
위의 뉴스벤더 (newsvendor) 모델은 한 번의 주문이 한 주기를 커버한다고 가정합니다. 실제 보충 (replenishment)에는 리드 타임 $L$이 존재합니다. 즉, 오늘 주문한 물품은 $L$일 후에 도착하므로, 주문량은 리드 타임과 검토 주기 (review interval)를 합친 전체 기간 동안의 수요를 커버해야 하며, 관련 분포는 해당 기간 동안의 누적 수요 (cumulative demand) 분포가 됩니다.
일일 수요가 평균 $m$과 표준 편차 $s$를 가진 독립적인 분포라면, $L$일 동안의 수요는:
...
여기서 두 가지 결과가 도출됩니다. 수요의 불확실성은 리드 타임의 제곱근에 비례하여 증가하는 반면, 평균 수요는 선형적으로 증가합니다. 따라서 리드 타임을 절반으로 줄이면 필요한 안전 재고 (safety stock)를 약 29% ($1 - 1/\sqrt{2}$) 절감할 수 있으며, 이는 대개 더 나은 예측 모델을 만드는 것보다 더 나은 투자입니다. 또한 독립성 가정 (independence assumption)은 매우 중요한 역할을 합니다. 일일 수요 간의 상관관계가 있으면 누적 표준 편차가 $\sqrt{L}$보다 더 빠르게 증가하므로, 일주일 동안 지속되는 프로모션이나 날씨 영향 등은 재고 부족 (understocking) 방향으로 공식의 예측을 깨뜨리게 됩니다.
간헐적 수요 (Intermittent demand)는 위의 모든 것을 깨뜨린다
대부분의 실제 SKU (Stock Keeping Unit)는 대부분의 날에 판매량이 0입니다. 느리게 움직이는 예비 부품(Slow-moving spares), 롱테일 카탈로그 품목(long-tail catalogue items), 산업용 부품 등이 이에 해당합니다. 이러한 경우 수요 분포는 0에서의 스파이크(spike)와 작은 연속적인 부분으로 구성되며, 일반적인 메커니즘은 제대로 작동하지 않습니다. 즉, 평균값은 실제로 발생하지 않는 숫자가 되고, MAPE (Mean Absolute Percentage Error)는 수요가 0인 날에는 정의되지 않으며, τ = 0.75에서 학습된 분위수 모델 (quantile model)은 0이 실제로 75번째 백분위수이기 때문에 기꺼이 0을 예측할 것입니다.
- 두 부분을 분리하여 모델링하십시오. 특정 기간에 수요가 발생하는지 여부를 판단하는 모델 하나와, 수요가 발생했을 때 그 양이 얼마인지를 판단하는 모델 하나를 만듭니다. 이는 고전적인 형태의 크로스톤 방법 (Croston’s method)이자, 현대적인 형태의 2단계 분류기 (two-stage classifier) 및 회귀 모델 (regressor)입니다.
- 0이 희소해질 때까지 시간 버킷 (time bucket)을 합산하십시오. 일 단위로는 예측이 불가능한 SKU라도 월 단위로는 완벽하게 예측 가능한 경우가 많으며, 만약 재주문 주기 (reorder cycle)가 월 단위라면 일일 예측은 애초에 필요하지 않았을 것입니다.
- 예측값이 아닌 결정 (decision)을 기준으로 점수를 매기십시오. 이러한 품목에 대해 유의미한 평가는 오직 시뮬레이션뿐입니다. 과거 이력에 대해 주문 정책 (ordering policy)을 재현해 보고, 품절 비용 (stockout cost)과 재고 유지 비용 (holding cost)의 합계를 구하십시오. 대부분이 0인 시계열 데이터에서 모든 점 예측 (point-forecast) 지표는 오해의 소지가 있습니다.
합산되어야 하는 예측값들
예측은 보통 SKU, 카테고리, 지역, 전체 등 여러 수준에서 동시에 필요하며, 각 수준에서 독립적으로 수행된 예측값들은 서로 합산되지 않습니다. 재무 팀의 수치와 창고 수치의 합계가 일치하지 않으며, 양측 모두 자신의 수치가 맞다고 주장하게 됩니다.
간단한 해결책으로는 하향식 (Top-down, 전체를 예측한 뒤 과거 비중에 따라 분할) 방식과 상향식 (Bottom-up, 각 SKU를 예측한 뒤 합산) 방식이 있습니다. 상향식은 말단(leaves) 수준에서는 보통 더 정확하지만 상위 수준에서는 노이즈가 더 많으며, 하향식은 그 반대입니다. 최적의 조정 (Reconciliation) 방법은 모든 수준에서 독립적인 예측을 수행한 뒤 이를 일관된 예측 집합으로 투영 (Project)하는 방식이며, 이는 일반적으로 두 방식 모두보다 뛰어난 성능을 보입니다. 이러한 방식은 예측 문헌에서 해당 명칭으로 잘 발달되어 있으며, 실무적인 요구사항은 각 팀이 저마다의 방식으로 반올림하게 두는 대신 하나의 정책을 선택하여 모든 곳에 적용하는 것뿐입니다.
무엇을 선택하든, 모든 수준에서의 계절성 단순 예측 베이스라인 (Seasonal-naive baseline)과 비교하여 평가하십시오. 일관성 (Coherence)은 개선하지만 실제 비용이 발생하는 수준에서의 정확도를 떨어뜨리는 조정 체계는, 알아차리기 매우 어려운 방식으로 상황을 악화시킨 것입니다.
관련 항목
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기