시계열 데이터 분석 ②
ARIMA로 미래를 예측하다
월별 신규 가입자 수 예측 · 코호트 W1 리텐션율 예측 실습
커머스 앱 그로스 마케터로서 팀장에게 이런 요청을 받았다.
"다음 분기 신규 가입자 수 예측해줄 수 있어요? 채널별 예산 배분 계획 세우려고요."
이번 시간에는 ARIMA 모델로 이 요청에 직접 답해본다.
📊 리텐션(Retention)이란?
리텐션율은 앱이나 서비스를 처음 사용하기 시작한 유저가 일정 기간 후에도 계속 사용하고 있는 비율이다. 신규 유저를 아무리 많이 데려와도 기존 유저가 계속 이탈하면 성장은 멈춘다. 그래서 리텐션은 "버킷에 물을 채우는 것보다 바닥이 새는 걸 먼저 막아야 한다"는 개념과 연결된다.
| 종류 | 측정 기준 | 주로 쓰는 서비스 |
|---|---|---|
| 일간 리텐션 (D1, D7, D30) | 설치 후 1일, 7일, 30일 후 접속 여부 | 모바일 앱, 게임 |
| 주간 리텐션 (W1, W2, W4) | 설치 후 1주, 2주, 4주 후 접속 여부 | SNS, 커머스 |
| 월간 리텐션 | 이번 달 활성 유저가 다음 달에도 활성인 비율 | 구독 서비스, B2B |
| 코호트 리텐션 | 동일 시점에 유입된 그룹(코호트)별 추적 | 정밀 분석 |
예) 1,000명이 설치 → 그 중 620명이 1주 후에도 접속 → W1 리텐션 = 62%
🔮 ARIMA 모델이란?
ARIMA는 시계열 데이터(시간 순서로 나열된 데이터)에서 패턴을 학습해 미래 값을 예측하는 통계 모델이다. 딥러닝처럼 복잡하지 않고, 수십 년간 검증된 고전 통계 모델이지만 실무에서 여전히 빠르고 해석하기 쉬운 예측 도구로 자주 쓰인다.
| 파라미터 | 이름 | 의미 | 이번 실습 값 |
|---|---|---|---|
| p | AR (자기회귀) | 몇 주/개월 전 값을 참조할지 | 1 또는 2 |
| d | I (차분/누적) | 트렌드 제거를 위해 몇 번 차분할지 | 1 |
| q | MA (이동평균) | 과거 예측 오차를 몇 개 반영할지 | 1 |
원본: 65.7, 64.7, 65.7, 66.9 ... → 트렌드 있음
1차분: -1.0, +1.0, +1.2, ... → 트렌드 제거됨 → 0 근처에서 진동
💻 실습 1 — 월별 신규 가입자 수 예측
36개월(3년)간의 월별 신규 가입자 수 데이터를 ARIMA로 학습해 다음 6개월을 예측한다. 데이터 특징: 완만한 우상향 트렌드 + 계절성 없음 → ARIMA(1,1,1) 적합
STEP 1 라이브러리 설치 및 불러오기
# Google Colab에서 처음 한 번만 실행 !pip install statsmodels -q import pandas as pd import matplotlib.pyplot as plt from statsmodels.tsa.arima.model import ARIMA import warnings warnings.filterwarnings('ignore') import matplotlib # Colab 한글 폰트 설정 !apt-get install -y fonts-nanum -qq !fc-cache -fv -q matplotlib.font_manager._load_fontmanager(try_read_cache=False) plt.rcParams['font.family'] = 'NanumGothic' plt.rcParams['axes.unicode_minus'] = False print("준비 완료!")
- statsmodels: 통계 분석 전용 파이썬 라이브러리. ARIMA 모델이 여기에 포함되어 있다.
- warnings.filterwarnings('ignore'): 분석과 무관한 경고 메시지를 숨긴다. 경고가 많아도 코드 실행에는 문제없다.
- plt.rcParams['font.family'] = 'NanumGothic': 그래프에 한글이 깨지지 않도록 나눔고딕 폰트를 설정한다.
STEP 2 데이터 만들기
# 월별 신규 가입자 수 데이터 (단위: 명) 36개월 # 특징: 완만한 우상향 트렌드, 계절성 없음 → ARIMA에 적합 날짜 = [ '2021-01', '2021-02', '2021-03', '2021-04', '2021-05', '2021-06', '2021-07', '2021-08', '2021-09', '2021-10', '2021-11', '2021-12', '2022-01', '2022-02', '2022-03', '2022-04', '2022-05', '2022-06', '2022-07', '2022-08', '2022-09', '2022-10', '2022-11', '2022-12', '2023-01', '2023-02', '2023-03', '2023-04', '2023-05', '2023-06', '2023-07', '2023-08', '2023-09', '2023-10', '2023-11', '2023-12' ] 가입자 = [ 1200, 1280, 1350, 1420, 1390, 1470, # 2021년 1~6월 1510, 1480, 1560, 1600, 1650, 1700, # 2021년 7~12월 1730, 1760, 1800, 1870, 1840, 1920, # 2022년 1~6월 1960, 1940, 2010, 2080, 2120, 2170, # 2022년 7~12월 2200, 2230, 2280, 2350, 2320, 2400, # 2023년 1~6월 2450, 2430, 2500, 2570, 2610, 2650 # 2023년 7~12월 ] # DataFrame 생성: 날짜 + 가입자 두 컬럼으로 표 만들기 df = pd.DataFrame({'날짜': 날짜, '가입자': 가입자}) # '2021-01' 같은 문자열을 파이썬이 날짜로 인식하도록 변환 df['날짜'] = pd.to_datetime(df['날짜']) print(df.head(5))
- pd.DataFrame({'키': 값}): 딕셔너리를 받아서 엑셀처럼 행과 열로 이루어진 표(DataFrame)를 만든다. 각 key가 컬럼명, value가 컬럼 데이터가 된다.
- pd.to_datetime(): "2021-01"처럼 문자열로 된 날짜를 파이썬이 날짜로 인식하는 형식으로 변환한다. 이렇게 해야 나중에 날짜 순서대로 그래프를 그릴 수 있다.
STEP 3 학습 / 테스트 데이터 분리
시험 정답을 미리 외운 학생이 시험을 잘 봐도 진짜 실력이 아니듯, 모델도 보지 않은 데이터(test)에서 얼마나 맞추는지 확인해야 진짜 예측 능력을 평가할 수 있다.
앞 30개월로 학습 → 뒤 6개월로 검증 (정답지를 숨겨놓고 채점하는 방식)
# 앞 30개월 → 모델 학습용 (train) # 뒤 6개월 → 예측 결과 검증용 (test) train = df.iloc[:30] # 0번 행부터 29번 행까지 (처음 30개) test = df.iloc[30:] # 30번 행부터 끝까지 (나머지 6개) print("학습 데이터 (train): 처음 30개월") print(train.tail(3)) print("\n테스트 데이터 (test): 마지막 6개월") print(test)
- df.iloc[시작:끝]: 행 번호로 데이터를 잘라내는 방법. 엑셀에서 특정 행들을 선택하는 것과 같다.
- iloc[:30]: 0~29번 행 (처음 30개), iloc[30:]: 30번부터 끝까지
- df.tail(n): DataFrame의 마지막 n개 행만 출력한다.
STEP 4 시각화 1 — 데이터 탐색
# 데이터를 그래프로 그려서 트렌드와 계절성을 눈으로 확인 plt.figure(figsize=(13, 5)) plt.plot(df['날짜'], df['가입자'], color='steelblue', linewidth=2, marker='o', markersize=4) plt.title('월별 신규 가입자 수 (2021~2023)', fontsize=13, fontweight='bold') plt.xlabel('날짜') plt.ylabel('가입자 수 (명)') plt.grid(True, alpha=0.3) plt.tight_layout() plt.show()
- 전체적으로 우상향하는가? → 성장 트렌드 존재 → d=1 차분 필요
- 매년 같은 시기에 봉우리가 있는가? → 계절성 확인 (없으면 기본 ARIMA 사용)
- 일시적으로 꺾인 달이 있는가? → 해당 시점의 캠페인·채널 변화 이력과 대조
STEP 5 ARIMA 모델 학습
# ARIMA 모델 생성 # order = (p, d, q) = (1, 1, 1) # p=1: 직전 1개월 값을 참조 # d=1: 1번 차분 → 완만한 우상향 트렌드 제거 # q=1: 직전 예측 오차 1개를 보정에 반영 model = ARIMA(train['가입자'], order=(1, 1, 1)) # 모델 학습: "이 데이터로 패턴을 배워라" # 30개월치 데이터를 읽으며 어떤 패턴이 반복되는가를 수식으로 정리 학습된모델 = model.fit() print("ARIMA 모델 학습 완료!") print("사용 파라미터 : ARIMA(1, 1, 1)") print("학습 기간 : 2021-01 ~ 2023-06 (30개월)")
- ARIMA(데이터, order=(p,d,q)): 어떤 데이터를 어떤 파라미터로 분석할지 설정하는 단계. 아직 학습은 시작하지 않은 상태다.
- model.fit(): 실제로 데이터를 읽으며 패턴을 수식으로 정리하는 학습 단계. 사람으로 치면 "30개월치 데이터를 공부하는 단계"다.
STEP 6 예측 & 결과 비교
# 테스트 기간(6개월) 예측 예측결과 = 학습된모델.get_forecast(steps=6) # 예측된 평균값(대표값)만 꺼내기 예측가입자수 = 예측결과.predicted_mean.values # 95% 신뢰구간: "예측값이 이 범위 안에 있을 확률이 95%" 예측범위 = 예측결과.conf_int(alpha=0.05) 예측하한 = 예측범위.iloc[:, 0].values # 하한값 (0번 컬럼) 예측상한 = 예측범위.iloc[:, 1].values # 상한값 (1번 컬럼) # 실제값 가져오기 실제가입자수 = test['가입자'].values # 예측 결과 vs 실제값 비교 출력 print("예측 결과 비교표") print("-" * 60) for i in range(len(test)): 날짜 = test['날짜'].iloc[i].strftime('%Y-%m') 실제 = 실제가입자수[i] 예측 = round(예측가입자수[i]) 하한 = round(예측하한[i]) 상한 = round(예측상한[i]) 오차 = abs(실제 - 예측) 오차율 = round((오차 / 실제) * 100, 1) print(f"날짜: {날짜} | 실제: {실제:,}명 | 예측: {예측:,}명 | 범위: {하한:,}~{상한:,} | 오차율: {오차율}%")
- get_forecast(steps=6): 학습된 모델로 앞으로 6단계(6개월) 예측값을 생성한다.
- predicted_mean.values: 예측 결과 중 대표값(평균 예측값)만 NumPy 배열로 꺼낸다.
- conf_int(alpha=0.05): 신뢰도 95%(=1-0.05)의 예측 범위(하한~상한)를 구한다. 미래는 불확실하므로 하나의 숫자가 아닌 범위로 표현하는 것이 더 정직하다.
- iloc[:, 0] / iloc[:, 1]: 신뢰구간 표에서 0번 컬럼(하한), 1번 컬럼(상한)을 각각 꺼낸다.
- strftime('%Y-%m'): 날짜를 "2023-07" 형식의 문자열로 변환한다.
STEP 7 시각화 2 — 예측 결과 그래프
plt.figure(figsize=(13, 5)) # 실제 가입자 수 전체 (학습+테스트 구간 모두) plt.plot(df['날짜'], df['가입자'], marker='o', label='실제 가입자 수') # 모델이 예측한 가입자 수 (점선) plt.plot(test['날짜'], 예측가입자수, marker='s', linestyle='--', label='예측 가입자 수') # 95% 신뢰구간 (음영 처리) plt.fill_between(test['날짜'], 예측하한, 예측상한, alpha=0.2, label='95% 예측 범위') # 예측이 시작되는 날짜를 세로 점선으로 표시 예측시작일 = test['날짜'].iloc[0] plt.axvline(예측시작일, linestyle=':', label='예측 시작일') plt.title('ARIMA 예측 결과') plt.xlabel('날짜') plt.ylabel('가입자 수') plt.legend() plt.grid(True, alpha=0.3) plt.show()
- 파란 점선이 검정 실선에 가깝게 붙어 있는가? → 붙어 있을수록 신뢰할 수 있는 모델
- 음영(신뢰구간)이 오른쪽으로 갈수록 넓어지는가? → 정상 현상. 먼 미래일수록 불확실성이 커짐
- fill_between(x축, 아래쪽 경계, 위쪽 경계): 두 선 사이의 공간을 색으로 채운다. 95% 신뢰구간 음영 표현에 자주 쓰인다.
- plt.axvline(날짜): 특정 x축 값에서 세로 점선을 그린다. 예측 시작 시점을 명확히 표시하는 데 사용한다.
STEP 8 정확도 평가 (MAE / MAPE)
# 각 달마다 틀린 값(오차) 모으기 오차목록 = [] # 각 달마다 오차를 %로 바꾼 값 모으기 오차율목록 = [] for i in range(len(test)): 실제값 = 실제가입자수[i] 예측값 = 예측가입자수[i] 오차 = abs(실제값 - 예측값) # 절대 오차 (부호 없이) 오차율 = (오차 / 실제값) * 100 # 퍼센트 오차 오차목록.append(오차) 오차율목록.append(오차율) # MAE: 평균적으로 몇 명 빗나갔는가? mae = sum(오차목록) / len(오차목록) # MAPE: 평균적으로 몇 % 빗나갔는가? mape = sum(오차율목록) / len(오차율목록) print(f"MAE (평균 오차) : {mae:,.0f}명") print(f"MAPE (평균 오차율): {mape:.1f}%") if mape < 10: print("판단: 실무 사용 가능 수준입니다.") else: print("판단: 모델 개선이 필요합니다.")
- abs(실제값 - 예측값): 두 값의 차이를 항상 양수로 만든다. 예측이 높든 낮든 "틀린 정도"만 보기 위해 절대값을 사용한다.
- list.append(값): 리스트 끝에 새 값을 하나씩 추가한다. for문과 함께 쓰면 반복 결과를 차곡차곡 쌓을 수 있다.
- MAE (Mean Absolute Error): 평균적으로 몇 명 틀렸나? → ex) MAE=18이면 매달 평균 18명 오차
- MAPE (Mean Absolute Percentage Error): 평균적으로 몇 % 틀렸나? → ex) MAPE=0.7%이면 실무 사용 가능
STEP 9 진짜 미래 예측 — 전체 데이터로 재학습
STEP 5~8은 "이 모델이 믿을 만한가?"를 확인하는 검증 과정이었다. 마지막 6개월을 정답지로 숨겨두고 채점한 것.
채점이 끝났으면 정답지까지 포함해서 다시 학습하는 게 맞다. 학습 데이터가 36개월로 늘어나 더 최근 패턴까지 반영하므로 예측 신뢰도가 올라간다.
# 전체 36개월 데이터로 모델 재학습 model = ARIMA(df['가입자'], order=(1, 1, 1)) 최종모델 = model.fit() # 앞으로 6개월 예측 미래예측결과 = 최종모델.get_forecast(steps=6) 미래예측가입자수 = 미래예측결과.predicted_mean.values 미래예측범위 = 미래예측결과.conf_int(alpha=0.05) 미래예측하한 = 미래예측범위.iloc[:, 0].values 미래예측상한 = 미래예측범위.iloc[:, 1].values # 미래 날짜 직접 입력 (2024년 1~6월) 미래날짜 = pd.to_datetime([ '2024-01', '2024-02', '2024-03', '2024-04', '2024-05', '2024-06' ]) print("미래 가입자 예측 결과") for i in range(6): 날짜 = 미래날짜[i].strftime('%Y-%m') 예측 = round(미래예측가입자수[i]) 하한 = round(미래예측하한[i]) 상한 = round(미래예측상한[i]) print(f"{날짜}: 예측 {예측:,}명 (95% 범위: {하한:,}명 ~ {상한:,}명)") # 시각화: 실측 데이터 + 미래 예측 plt.figure(figsize=(13, 5)) plt.plot(df['날짜'], df['가입자'], marker='o', label='실제 가입자 수') plt.plot(미래날짜, 미래예측가입자수, marker='s', linestyle='--', label='미래 예측 가입자 수') plt.fill_between(미래날짜, 미래예측하한, 미래예측상한, alpha=0.2, label='95% 예측 범위') plt.title('미래 가입자 수 예측') plt.legend() plt.grid(True, alpha=0.3) plt.show()
"ARIMA 모델 기준으로 2024년 상반기 월평균 신규 가입자는 약 X,XXX명으로 예측됩니다. 예측 오차가 평균 0.7% 수준이므로 이 범위 안에서 채널별 목표를 배분할 수 있습니다. 현재 성장 기울기가 유지된다면 상반기 내 월 3,000명 달성이 가능할 것으로 보입니다."
🔁 실습 2 — 코호트 W1 리텐션율 예측
52주간의 코호트별 W1 리텐션율 데이터를 ARIMA로 학습해 다음 8주를 예측한다. 데이터 특징: 완만한 하향 트렌드 + 주간 노이즈 → ARIMA(2,1,1) 적합
d=1인 이유: 리텐션율이 완만하게 우하향하는 트렌드가 있다. 1번 차분으로 이 트렌드를 제거해야 ARIMA가 제대로 학습할 수 있다.
q=1인 이유: 직전 1주의 예측 오차만 보정에 반영한다. 주간 노이즈가 크기 때문에 오차를 너무 많이 반영하면 오히려 과적합이 발생할 수 있다.
STEP 1 데이터 만들기
import pandas as pd from statsmodels.tsa.arima.model import ARIMA # 52주 날짜 목록 (2026년 전체) cohort_weeks = [ '2026-01-05', '2026-01-12', '2026-01-19', '2026-01-26', '2026-02-02', '2026-02-09', '2026-02-16', '2026-02-23', # ... (중략) 총 52주까지 '2026-12-07', '2026-12-14', '2026-12-21', '2026-12-28', ] # W1 리텐션율 (단위: %) # 연초 높은 리텐션 → 완만한 하락 → 여름 캠페인 → 연말 이벤트 w1_retention = [ 65.7, 64.7, 65.7, 66.9, 64.1, 64.0, 66.5, 65.2, # 1~2월 (연초) 63.2, 64.6, 62.9, 62.8, 63.7, 60.3, 60.5, 62.1, # 3~4월 (완만한 하락) 61.3, 63.1, 61.2, 60.3, 64.5, 61.8, 63.9, 61.5, # 5~6월 (여름 캠페인) 62.7, 63.5, 59.7, 61.9, 60.3, 60.6, 60.0, 63.5, # 7~8월 60.6, 58.9, 61.6, 58.4, 60.4, 57.0, 57.8, 59.9, # 9~10월 (지속 하락) 60.6, 59.6, 59.1, 58.6, 56.7, 57.7, 58.0, 60.1, # 10~11월 60.1, 56.8, 59.8, 58.6, # 12월 (연말 이벤트) ] # DataFrame 생성 df = pd.DataFrame({ 'cohort_week': pd.to_datetime(cohort_weeks), 'w1_retention_rate': w1_retention }) print(df.head(5))
STEP 2 학습/테스트 분리 → ARIMA 학습 → 예측
# 44주 학습, 마지막 8주 검증 train = df.iloc[:44] test = df.iloc[44:] # ARIMA(2,1,1) 모델 학습 # p=2: 직전 2주 W1 리텐션 참조 (캠페인 효과가 2주에 걸쳐 나타남) # d=1: 1번 차분 → 완만한 하향 트렌드 제거 # q=1: 직전 예측 오차 1개 보정 반영 model = ARIMA(train['w1_retention_rate'], order=(2, 1, 1)) result = model.fit() # 8주 예측 forecast = result.get_forecast(steps=8) pred_values = forecast.predicted_mean.values pred_ci = forecast.conf_int(alpha=0.05) pred_lower = pred_ci.iloc[:, 0].values pred_upper = pred_ci.iloc[:, 1].values # 실제값과 비교 actual_values = test['w1_retention_rate'].values for i in range(len(test)): 주차값 = test['cohort_week'].iloc[i].strftime('%Y-%m-%d') 실제값 = actual_values[i] 예측값 = round(pred_values[i], 2) 오차율 = round(abs(실제값 - 예측값) / 실제값 * 100, 1) print(f"주차: {주차값} | 실제: {실제값}% | 예측: {예측값}% | 오차율: {오차율}%")
STEP 3 정확도 계산 → 미래 8주 예측
# MAE / MAPE 계산 총오차합 = 0 총오차율합 = 0 for i in range(len(test)): 오차 = abs(actual_values[i] - pred_values[i]) 총오차합 += 오차 총오차율합 += 오차 / actual_values[i] * 100 mae = 총오차합 / len(test) mape = 총오차율합 / len(test) print(f"MAE (평균 오차) : {mae:.2f} %p") print(f"MAPE (평균 오차율): {mape:.1f} %") if mape < 5: print("✅ 매우 우수 — 목표치로 그대로 사용 가능 (MAPE 5% 미만)") elif mape < 10: print("✅ 실무 사용 가능 — 방향성 판단용 (MAPE 10% 미만)") else: print("⚠️ 모델 개선 필요 (MAPE 10% 초과)") # ───────────────────────────────────────────── # 검증 통과 후: 전체 52주 데이터로 재학습 → 진짜 미래 예측 # ───────────────────────────────────────────── model_final = ARIMA(df['w1_retention_rate'], order=(2, 1, 1)) result_final = model_final.fit() # 미래 8주 예측 forecast_future = result_final.get_forecast(steps=8) future_values = forecast_future.predicted_mean.values future_ci = forecast_future.conf_int(alpha=0.05) future_lower = future_ci.iloc[:, 0].values future_upper = future_ci.iloc[:, 1].values # 미래 날짜 생성 (2027년 1~2월, 매주 월요일 기준) future_dates = pd.date_range(start='2027-01-04', periods=8, freq='W-MON') print("\n2027년 1~2월 W1 리텐션율 예측") for i in range(8): 주차 = future_dates[i].strftime('%Y-%m-%d') 예측 = round(future_values[i], 1) 하한 = round(future_lower[i], 1) 상한 = round(future_upper[i], 1) print(f"{주차}: 예측 {예측}% (범위: {하한}% ~ {상한}%)")
- pd.date_range(start, periods, freq='W-MON'): 시작 날짜부터 매주 월요일 기준으로 n개의 날짜를 자동 생성한다. 미래 예측 날짜를 만들 때 편리하다.
- ARIMA는 장기 예측일수록 평균값으로 수렴한다. 예측이 자기 자신을 입력으로 쓰는 구조라 오차가 누적되면서 불확실성(신뢰구간)은 넓어지고 예측 중심선은 평탄해진다.
- 노이즈가 있는 리텐션 데이터에서 MAPE 3~6% 수준이면 충분히 잘 작동하는 것이다.
📈 ARIMA 예측 전체 흐름 정리
② 전체 누적 데이터로 ARIMA 재학습
③ 향후 4~8주 예측값 업데이트
④ 예측값이 임계치(ex: 60%) 아래로 내려오는 주차 확인 → 캠페인 발동 여부 결정
⑤ 실제값 vs 예측값 차이가 ±2%p 초과 시 이상 감지 알림
💡 예측값으로 무엇을 할 수 있나?
예측값 자체보다 예측값과 실제값의 관계에서 마케팅 액션이 나온다.
팀 내에서 W1 리텐션 하한선(예: 60%)을 합의하고, 매주 예측값을 업데이트해 임계치 이하로 떨어지는 시점을 사전에 파악한다. 그 2~3주 전부터 온보딩 캠페인을 가동한다 (Day3 푸시, 사용 가이드 메시지, 첫 구매 쿠폰 등).
기준선: 예측값 ± 2.0%p. 실제값이 예측보다 2%p 이상 낮으면 알림 발송 + 원인 분석 시작. 점검 항목: 앱 업데이트/버그 배포, 유입 채널 믹스 변화(퍼포먼스 광고 비중 급증 → 저품질 유저 유입), 경쟁사 프로모션 기간 겹침. 2%p 이상 높으면 성공 요인을 분석한다.
1년치 리텐션 트렌드가 지속적으로 하락한다면 캠페인이 아닌 온보딩 구조 자체를 바꿔야 한다는 신호다. 단기 캠페인으로 스파이크를 만들어도 구조가 나쁘면 다시 떨어진다.
⚠️ ARIMA의 한계와 실무 대안
| 상황 | ARIMA 한계 | 대안 모델 |
|---|---|---|
| 계절성이 있거나 이벤트 효과 반영 필요 | 외부 변수 반영 불가 | Prophet (Meta 오픈소스) |
| 채널·국가·코호트 등 변수가 많을 때 | 복수 변수 처리 안 됨 | LightGBM / XGBoost |
| 유저 개별 이탈 확률 모델링 필요 | 집계 데이터만 처리 | BG/NBD, Kaplan-Meier |
| 대규모 프로모션 / 앱 업데이트 | 갑작스러운 스파이크 반영 불가 | 외부 변수 포함한 ML 모델 |
예측값은 방향성 참고용이다. 정확한 숫자보다 "이 추세면 언제 위험해지는가"에 집중해야 한다. 모델은 주 1회 재학습을 권장하며, 예측값과 함께 항상 가정과 한계를 같이 공유해야 한다. 광고 채널이 달라지면 코호트 자체의 특성이 바뀌므로 코호트 품질 변화도 주의해서 모니터링해야 한다.
ARIMA는 시계열 데이터에서 패턴을 학습해 미래를 예측하는 통계 모델이다. p(참조 기간), d(차분 횟수), q(오차 보정 수) 3개 파라미터만 이해하면 기본적인 예측이 가능하다. 학습 → 검증(MAE/MAPE) → 미래 예측의 3단계 흐름을 기억하자. 예측값은 숫자 자체보다 "언제 임계치에 도달하는가"를 파악하는 데 써야 진짜 마케팅 액션으로 연결된다.
'부트캠프' 카테고리의 다른 글
| SQLD 자격증 공부 4월 마지막주 (0) | 2026.05.03 |
|---|---|
| 멋쟁이사자처럼 부트캠프 그로스마케팅 4기 35일차_260428 (0) | 2026.04.28 |
| 멋쟁이사자처럼 부트캠프 그로스마케팅 4기 32일차_260423 (0) | 2026.04.23 |
| 멋쟁이사자처럼 부트캠프 그로스마케팅 4기 31일차_260422 (1) | 2026.04.22 |
| 멋쟁이사자처럼 부트캠프 그로스마케팅 4기 30일차_260421 (0) | 2026.04.21 |