부트캠프

멋쟁이사자처럼 부트캠프 그로스마케팅 4기 35일차_260428

Yuuma 2026. 4. 28. 16:22

 

 

Day 19

데이터 분석 모델링
군집분석 · A/B 테스트 · ARIMA 종합 실습

뮤직스트림(MusicStream) 시나리오로 배우는
K-Means 군집분석 → A/B 테스트(t-test) → ARIMA 시계열 예측 파이프라인

K-Means군집분석A/B 테스트 t-testARIMA시계열 예측 scikit-learnstatsmodels

전체 시나리오

상황: 음악 스트리밍 서비스 뮤직스트림(MusicStream)의 그로스 마케터
신규 가입자 증가세가 둔화되고 있고, 팀장의 지시를 받았습니다.
"신규 가입자 증가세가 둔화되고 있어요. 그냥 전체 고객에게 쿠폰 뿌리지 말고, 데이터로 고객을 나눠서 제대로 된 실험을 해보고, 앞으로 어떻게 될지도 예측해봐요."
전체 실습 흐름도
3단계 파이프라인 요약:
1) 고객 행동 데이터 200명 → K-Means 군집분석 → 이탈 위험 고객 식별
2) 이탈 위험 고객 대상 A/B 테스트 → t-test로 쿠폰 효과 통계 검증
3) 검증된 전략 전사 적용 후 → ARIMA로 구독 유지율 미래 예측

1단계 — 군집 분석 (K-Means)

1단계: 군집 분석 (K-Means Clustering)

군집 분석이란?

군집 분석(Clustering)은 비슷한 특성을 가진 고객끼리 자동으로 묶어주는 비지도 학습 방법입니다. 마케터가 "이 고객은 VIP, 저 고객은 이탈 위험"이라고 일일이 판단하지 않아도, 알고리즘이 데이터를 보고 스스로 그룹을 만들어줍니다.

K-Means 알고리즘 작동 원리

K-Means 4단계 반복:
① K개의 중심점(centroid)을 랜덤으로 찍는다
② 각 데이터를 가장 가까운 중심점 그룹에 배정한다
③ 각 그룹의 평균을 새 중심점으로 업데이트한다
④ 더 이상 변화가 없을 때까지 ②~③을 반복 → 안정적인 K개의 그룹 완성

왜 전처리가 필요할까?

① LabelEncoder — 문자를 숫자로 변환

K-Means는 거리 계산을 기반으로 하기 때문에 숫자만 처리할 수 있습니다. 텍스트 값은 반드시 숫자로 바꿔야 합니다.

변환 예시:
'남성' → 0   /   '여성' → 1
'무료' → 0   /   '기본' → 1   /   '프리미엄' → 2

주의: LabelEncoder는 숫자 크기에 순서가 있다고 해석합니다. 순서가 없는 변수(팝, 재즈, 힙합 같은 장르)에 쓰면 알고리즘이 오해할 수 있어요. 이 실습에서는 이진형·순서형 변수에만 사용합니다.

② StandardScaler — 단위 통일

변수 범위 스케일링 없으면
월 청취 시간 10 ~ 420분 이 변수가 결과를 지배
월 접속 횟수 1 ~ 31회 영향력 작아짐
친구 추천 여부 0 또는 1 거의 무시됨
StandardScaler는 모든 변수를 평균 0, 표준편차 1로 맞춰줍니다. 단위가 다른 변수들을 공평하게 비교할 수 있게 됩니다.

③ 엘보우(Elbow) 방법 — 최적 K 찾기

K를 1부터 늘려가며 Inertia(군집 내 거리 합)을 계산합니다.
그래프가 꺾이는 지점(팔꿈치) = 최적 K  →  이 실습에서는 K = 3

데이터셋 1: 고객 행동 데이터 (200명)

컬럼명 설명 타입 전처리
고객ID 고객 고유 번호 텍스트 분석에 사용 안 함
성별 남성 / 여성 범주형 LabelEncoder
연령대 20대 / 30대 / 40대 / 50대이상 범주형 LabelEncoder
구독플랜 무료 / 기본 / 프리미엄 (순서 있음) 범주형 LabelEncoder
선호장르 팝 / 힙합 / 재즈 / 클래식 / 인디 범주형 LabelEncoder
월청취시간 한 달 총 청취 시간 (분) 수치형 StandardScaler
월접속횟수 한 달 앱 접속 횟수 수치형 StandardScaler
구독유지개월 현재까지 구독 유지 개월 수 수치형 StandardScaler
최근접속일수 마지막 앱 접속이 며칠 전인지 수치형 StandardScaler
플레이리스트수 저장한 플레이리스트 수 수치형 StandardScaler
친구추천여부 친구에게 추천했는지 (1=예, 0=아니오) 이진형 StandardScaler

실습 코드

1단계: 데이터 불러오기 + EDA

Python 데이터 로드 + 기초 탐색
# CSV 파일 불러오기
df_고객 = pd.read_csv('dataset1_고객행동.csv')

# 수치형 컬럼 기초 통계 확인
수치형_탐색 = ['월청취시간', '월접속횟수', '구독유지개월', '최근접속일수', '플레이리스트수']
print(df_고객[수치형_탐색].describe().round(1))

# 범주형 컬럼 분포 확인
print(df_고객['구독플랜'].value_counts())
print(df_고객['선호장르'].value_counts())

# 결측치 확인
print(df_고객.isnull().sum())

# 결측치 처리: 수치형 컬럼은 평균값으로 채우기
결측치_컬럼 = ['월청취시간', '월접속횟수', '구독유지개월', '최근접속일수', '플레이리스트수']

for col in 결측치_컬럼:
    평균값 = df_고객[col].mean()
    df_고객[col] = df_고객[col].fillna(round(평균값))
fillna(round(평균값)) — 결측치(NaN)를 해당 컬럼의 평균값으로 채웁니다. round()로 반올림해서 정수로 맞춥니다.

2단계: 전처리 — LabelEncoder + StandardScaler

Python 전처리: 문자→숫자 변환 + 스케일 통일
df_proc = df_고객.copy()  # 원본 보존을 위해 복사본 사용

# ── LabelEncoder: 텍스트 → 숫자 변환 ──────────────────────────
범주형_컬럼 = ['성별', '연령대', '구독플랜', '선호장르']
label_encoders = {}  # 나중에 역변환하고 싶을 때를 위해 저장

for col in 범주형_컬럼:
    le = LabelEncoder()
    df_proc[col] = le.fit_transform(df_proc[col])
    label_encoders[col] = le

# 역변환 예시: label_encoders['성별'].inverse_transform([0, 1])

# ── StandardScaler: 스케일 통일 ───────────────────────────────
feature_cols = [
    '성별', '연령대', '구독플랜', '선호장르',
    '월청취시간', '월접속횟수', '구독유지개월',
    '최근접속일수', '플레이리스트수', '친구추천여부'
]

X = df_proc[feature_cols]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
fit_transform(X) — fit(평균·표준편차 계산) + transform(실제 변환)을 한 번에 수행합니다.
이후 predict 데이터(새 데이터)에는 반드시 transform만 사용해야 합니다. (fit을 다시 하면 기준이 달라져서 틀립니다.)

3단계: 엘보우 방법으로 최적 K 찾기

Python 엘보우 방법 — K=1~10 Inertia 계산
inertia_list = []

for k in range(1, 11):
    # KMeans 객체 생성
    km = KMeans(n_clusters=k, random_state=42, n_init=10)
    # 스케일링된 데이터로 K-Means 학습 (중심점이 수렴할 때까지 반복)
    km.fit(X_scaled)
    # 학습 후 나온 inertia(군집 내 거리 합) 저장
    inertia_list.append(km.inertia_)

# 그래프: K=3 지점에서 꺾임(팔꿈치) 확인
plt.plot(range(1, 11), inertia_list, 'o-', color='#2E86AB')
plt.axvline(x=3, color='#E84855', linestyle='--', label='선택한 K=3')
n_init=10 — 초기 중심점을 10번 다르게 설정해서 가장 좋은 결과를 채택합니다. 결과의 안정성을 높여줍니다.
inertia_ — 군집 내 거리 합. 값이 작을수록 군집이 촘촘합니다. K가 커질수록 줄어들지만, 꺾이는 지점 이후엔 줄어드는 폭이 작아집니다.

4단계: K-Means 모델 학습 + 군집 프로파일링

Python K=3으로 군집 학습 + 클러스터별 평균 분석
K = 3
kmeans = KMeans(n_clusters=K, random_state=42, n_init=10)

# fit_predict = 학습(fit) + 군집 번호 예측(predict) 동시에
df_고객['클러스터'] = kmeans.fit_predict(X_scaled)

# 클러스터별 수치형 컬럼 평균 확인 (프로파일링)
수치형_cols = ['월청취시간', '월접속횟수', '구독유지개월', '최근접속일수', '플레이리스트수']
print(df_고객.groupby('클러스터')[수치형_cols].mean())

# 클러스터 이름 매핑 (평균 지표 보고 직접 해석해서 지정)
cluster_names = {
    2: '충성 고객 - 높은 청취시간, 지속 유지 필요',
    0: '중간 고객 - 보통 활동, 참여 유도 필요',
    1: '이탈 위험 - 접속 감소, 즉각 리텐션 필요'
}
df_고객['고객등급'] = df_고객['클러스터'].map(cluster_names)
groupby('클러스터').mean() — 클러스터별로 묶어서 각 지표의 평균을 계산합니다. 이 결과를 보고 "어떤 클러스터가 이탈 위험인지"를 사람이 직접 해석해서 이름을 붙입니다.

핵심 해석 포인트:
  최근접속일수가 가장 큰 클러스터 → 오래 안 들어온 것 → 이탈 위험
  월청취시간이 가장 큰 클러스터 → 많이 사용하는 것 → 충성 고객

5단계: PCA 시각화

Python PCA로 10차원 → 2차원 압축 후 산점도
# PCA: 10개 변수를 2개 축으로 압축해서 그래프로 그리기
pca = PCA(n_components=2, random_state=42)
X_2d = pca.fit_transform(X_scaled)

# 설명력 확인: 두 축이 전체 정보의 몇 %를 커버하는지
설명력 = pca.explained_variance_ratio_
# 결과: 주성분1 48.3% + 주성분2 12.5% = 합계 60.9%
PCA(주성분 분석) — 10개 변수를 2개 숫자로 압축하는 기법입니다. 10차원 데이터를 눈으로 볼 수 없으니, 2차원으로 줄여서 시각화합니다.
압축 과정에서 일부 정보는 손실됩니다. 이번 실습에서 2개 축으로 전체 정보의 약 60.9%를 설명했습니다.

군집 분석 결과

군집 분석 결과 — 3개 클러스터 프로파일
클러스터 0 (62명): 월 청취 219분 / 접속 17회 / 최근 접속 7일 전 / 구독 15개월 / 기본 플랜 클러스터 1 (85명): 월 청취 57분 / 접속 5회 / 최근 접속 29일 전 / 구독 4개월 / 무료 플랜 ← 이탈 위험 클러스터 2 (53명): 월 청취 272분 / 접속 22회 / 최근 접속 2일 전 / 구독 18개월 / 프리미엄 ← 충성 고객
마케팅 인사이트
  • 클러스터 1 (이탈 위험, 85명): 최근접속일수 29일 → 한 달 가까이 안 들어온 고객. 즉각 A/B 테스트 대상으로 선정.
  • 클러스터 2 (프리미엄 충성, 53명): 친구 추천 비율 79% → 자발적 바이럴 가능성 높음. 추천 프로그램 강화 고려.
  • 클러스터 0 (기본 충성, 62명): 기본 플랜 + 보통 활동 → 프리미엄 업그레이드 유도 캠페인 대상.

2단계 — A/B 테스트

2단계: A/B 테스트 (t-test)

A/B 테스트란?

두 가지 전략 중 어떤 것이 더 효과적인지 데이터로 비교하는 실험 방법입니다.
"느낌"이 아닌 숫자와 통계로 의사결정합니다.

왜 랜덤 배정이 중요한가?

랜덤으로 나누지 않으면 두 그룹 간 차이가 전략 때문인지, 원래 고객 성향 때문인지 알 수 없습니다.

잘못된 예: A그룹=원래 활발한 고객 / B그룹=원래 조용한 고객
→ 쿠폰 효과 없어도 A그룹 재접속률이 더 높게 나옴 → 잘못된 결론!

올바른 예: A, B 그룹 모두 랜덤으로 섞어서 나누기
→ 두 그룹의 고객 성향이 비슷해짐 → 차이가 있다면 전략 때문!

t-test와 p값 개념

ARIMA 파라미터 + p값 판정 기준
t 통계량: 두 그룹 평균 차이 ÷ 데이터의 변동성. 절댓값이 클수록 두 그룹 차이가 뚜렷합니다.
p값: "귀무가설이 맞는 상황에서 지금과 같은 결과가 우연히 나올 확률". 작을수록 우연이 아닐 가능성이 높습니다.
기준 p < 0.05: "100번 실험하면 5번 이하로만 이런 결과가 우연히 나온다"는 의미. 통계학에서 오랫동안 사용해온 관례적 기준입니다.

데이터셋 2: A/B 테스트 실험 결과 데이터

컬럼명 설명 타입
고객ID 이탈 위험 고객 고유 번호 텍스트
그룹 A (리마인드 이메일) / B (30% 할인 쿠폰) 범주형
발송일 이메일/쿠폰 발송 날짜 날짜
발송채널 email / push / sms 범주형
쿠폰할인율 할인율 (A그룹은 0%) 수치형
재접속여부 7일 이내 앱 재접속 (1=재접속, 0=미접속) 이진형
재접속까지일수 발송 후 재접속까지 걸린 일수 (미접속은 NaN) 수치형
구독갱신여부 실험 후 구독 갱신 여부 (1=갱신, 0=미갱신) 이진형

실습 코드

1단계: 데이터 로드 + 결측치 처리

Python A/B 데이터 로드 + 결측치 처리
df_실험 = pd.read_csv('dataset2_AB테스트결과.csv')

# 결측치 처리: 재접속여부 · 구독갱신여부는 최빈값으로 채우기
# (재접속까지일수의 NaN은 미접속 고객이므로 그대로 둠)
df_실험['재접속여부'] = df_실험['재접속여부'].fillna(df_실험['재접속여부'].mode()[0])
df_실험['구독갱신여부'] = df_실험['구독갱신여부'].fillna(df_실험['구독갱신여부'].mode()[0])
mode()[0] — 최빈값(가장 많이 나오는 값)을 반환합니다. [0]을 붙이는 이유는 mode()가 Series를 반환하기 때문에 첫 번째 값을 꺼내는 것입니다.

2단계: A/B 그룹 분리 + 재접속률 계산

Python 그룹 분리 + 재접속률 계산
A그룹 = df_실험[df_실험['그룹'] == 'A'].copy()
B그룹 = df_실험[df_실험['그룹'] == 'B'].copy()

# 0과 1로 된 컬럼은 .mean()이 곧 비율(퍼센트)이 됩니다
# * 100을 하면 소수가 아닌 퍼센트 숫자로 사용 가능
A재접속률 = A그룹['재접속여부'].mean() * 100
B재접속률 = B그룹['재접속여부'].mean() * 100

A갱신률 = A그룹['구독갱신여부'].mean() * 100
B갱신률 = B그룹['구독갱신여부'].mean() * 100

print(f"재접속률 A:{A재접속률:.1f}%, B:{B재접속률:.1f}%")
print(f"갱신률 A:{A갱신률:.1f}%, B:{B갱신률:.1f}%")
이진형 컬럼(0, 1)의 .mean() = 비율입니다. 예를 들어 80명 중 23명이 1이면 23/80 = 0.288, 즉 28.8%가 됩니다.
여기서는 * 100을 해서 퍼센트 숫자로 변환 후 저장했기 때문에, 출력할 때 :.1f로 포맷팅합니다.

3단계: t-test 통계 검정

Python t-test로 두 그룹 차이 유의성 검정
from scipy import stats

# ttest_ind: 독립된 두 그룹의 평균 차이 검정
# t통계량 = 평균차이 / 데이터의 변동성 → 절댓값이 클수록 차이 뚜렷
# p값 = 두 그룹 차이가 없다고 가정했을 때 지금 결과가 우연히 나올 확률
t통계량, p값 = stats.ttest_ind(A그룹['재접속여부'], B그룹['재접속여부'])

print(f"t-통계량: {t통계량:.3f}")
print(f"p값: {p값:.3f}")

if p값 < 0.05:
    print("판정: p < 0.05 → 귀무가설 기각")
    print("   쿠폰(B그룹) 효과는 통계적으로 유의미합니다.")
    print("   → B그룹 전략(30% 할인 쿠폰)을 전체 이탈위험군에 적용 결정!")
else:
    print("판정: p >= 0.05 → 귀무가설 채택 → 재실험 필요")

A/B 테스트 결과

======================================================= 2단계 A/B 테스트 결과 요약 ======================================================= A그룹 재접속률 : 28.7% (리마인드 이메일) B그룹 재접속률 : 47.5% (30% 할인 쿠폰) 재접속률 향상 : +18.8%p 구독 갱신율 향상: +12.5%p p값 : 0.0145 판정 : 쿠폰 효과 유의미 (p < 0.05) =======================================================
마케팅 인사이트
  • 재접속률뿐 아니라 구독 갱신율도 B그룹이 더 높습니다. 쿠폰이 단순히 앱을 다시 열게 하는 것을 넘어 실제 구독 유지까지 이어졌다는 의미입니다.
  • p = 0.0145 < 0.05 → 우연일 확률 약 1.5%. 통계적으로 유의미한 차이입니다.
  • 이 결과를 바탕으로 매달 이탈 위험 고객에게 쿠폰을 보내는 캠페인을 정기적으로 진행합니다.
p값 오해 바로잡기:
"p < 0.05면 효과가 크다" → 틀림. p값은 효과 크기가 아닌 우연일 확률입니다. 효과 크기는 재접속률 차이(+18.8%p)로 판단합니다.
"p ≥ 0.05면 효과가 없다" → 틀림. 이번 데이터로는 효과를 확신할 수 없다는 의미입니다.
p값과 효과 크기는 함께 봐야 합니다.

3단계 — ARIMA 시계열 예측

3단계: ARIMA 시계열 예측

시계열 데이터란?

시간 순서대로 기록된 데이터입니다. 순서가 의미 있기 때문에 일반 데이터와 다르게 다뤄야 합니다.

일반 데이터: 고객 200명 → 순서 바꿔도 됨
시계열 데이터: 1월 → 2월 → 3월 → ... → 순서가 곧 정보

ARIMA 파라미터 개념

교안에 나온 인포그래픽을 위쪽에서 이미 확인했습니다. 핵심만 다시 정리하면:

파라미터 이름 이 실습에서의 의미
p = 1 자기회귀 (AR) 지난달 구독 유지율이 이번 달 예측에 영향을 준다
d = 1 차분 (I) 우상향 추세를 제거해서 패턴(변화량)만 남긴다
q = 1 이동평균 (MA) 지난달 예측 실수(오차)를 이번 달 예측에 반영한다

train / test 분리 + MAPE

train/test 분리: 모델이 얼마나 정확한지 확인하기 위해 데이터를 나눕니다.
train (학습): 2022-01 ~ 2023-06 (18개월) → 모델이 패턴 학습
test (검증): 2023-07 ~ 2023-12 (6개월) → 예측 후 실제값과 비교
신뢰할 수 있다고 판단되면 → 전체 데이터로 재학습 후 미래 예측

MAPE(평균 절대 오차율): 예측이 실제값에서 평균적으로 몇 % 벗어났는지. 10% 미만이면 실무 사용 가능.

실습 코드

1단계: 시계열 데이터 준비

Python 시계열 데이터 생성 + 인덱스 설정
날짜 = [
    '2022-01', '2022-02', ..., '2023-12'  # 24개월
]
구독유지율 = [
    84.2, 84.5, 84.9, ..., 91.0  # 84~91% 우상향
]

df_ts = pd.DataFrame({'날짜': 날짜, '구독유지율': 구독유지율})
df_ts['날짜'] = pd.to_datetime(df_ts['날짜'])

# ARIMA가 시계열 순서를 올바르게 인식하려면 날짜가 인덱스여야 합니다
df_ts = df_ts.set_index('날짜')
set_index('날짜') — 날짜 컬럼을 인덱스로 설정합니다. ARIMA 모델이 시계열 순서를 올바르게 인식하려면 날짜가 인덱스여야 합니다.

2단계: train/test 분리 + ARIMA 학습

Python train/test 분리 + ARIMA(1,1,1) 학습
# 앞 18개월: 모델 학습용 / 뒤 6개월: 예측 결과 검증용
train = df_ts.iloc[:18]
test  = df_ts.iloc[18:]

# ARIMA(p=1, d=1, q=1) 모델 생성 및 학습
model = ARIMA(train['구독유지율'], order=(1, 1, 1))
학습된모델 = model.fit()
iloc[:18] — 위치 기반 인덱싱으로 0~17번째 행(18개)을 슬라이싱합니다.
ARIMA(order=(1,1,1)) — 파라미터 p, d, q를 순서대로 지정합니다. 튜닝이 필요하면 이 숫자를 바꿔봅니다.

3단계: 테스트 기간 예측 + MAPE 검증

Python 테스트 기간 예측 + MAPE 계산
# 테스트 기간(6개월) 예측
예측결과 = 학습된모델.get_forecast(steps=6)
예측구독유지율 = 예측결과.predicted_mean.values
예측범위 = 예측결과.conf_int(alpha=0.05)  # 95% 신뢰구간
예측하한 = 예측범위.iloc[:, 0].values
예측상한 = 예측범위.iloc[:, 1].values

# MAPE: 평균 오차율 — 실제값과 몇 퍼센트 차이 나는지
오차목록, 오차율목록 = [], []
for i in range(len(test)):
    실제 = test['구독유지율'].values[i]
    예측 = round(예측구독유지율[i], 1)
    오차율 = round((abs(실제 - 예측) / 실제) * 100, 1)
    오차율목록.append(오차율)

mape = sum(오차율목록) / len(오차율목록)
print(f"MAPE: {mape:.2f}%")  # 10% 이내면 신뢰도 있음
get_forecast(steps=6) — 학습된 모델로 미래 6단계를 예측합니다.
conf_int(alpha=0.05) — 95% 신뢰구간을 반환합니다. 미래로 갈수록 구간이 넓어지는 것은 정상입니다 — 불확실성이 커지기 때문이며 모델의 문제가 아닙니다.

4단계: 미래 6개월 예측

Python 전체 데이터로 재학습 후 2024년 상반기 예측
# 신뢰성 확인 완료 → 전체 데이터(24개월)로 재학습
최종모델 = ARIMA(df_ts['구독유지율'], order=(1, 1, 1)).fit()
미래예측결과 = 최종모델.get_forecast(steps=6)
미래예측구독유지율 = 미래예측결과.predicted_mean.values

# 2024년 1월부터 매월 1일 기준 날짜 6개 생성
# freq='MS' = Month Start (매월 1일)
미래날짜 = pd.date_range(start='2024-01', periods=6, freq='MS')
왜 전체 데이터로 재학습하나요? test 기간 예측은 모델 검증 용도입니다. 실제 미래를 예측할 때는 가진 모든 데이터를 학습에 사용해야 더 정확한 예측이 가능합니다.

ARIMA 예측 결과

======================================================= 3단계 ARIMA 예측 결과 요약 ======================================================= 예측 정확도 (MAPE) : 1.0% ← 10% 미만 → 실무 사용 가능 2024년 1월 예측 : 91.3% (95% 범위: 90.5% ~ 92.1%) 2024년 2월 예측 : 91.7% (95% 범위: 90.2% ~ 93.2%) 2024년 3월 예측 : 92.0% (95% 범위: 89.9% ~ 94.1%) 2024년 4월 예측 : 92.3% (95% 범위: 89.7% ~ 94.9%) 2024년 5월 예측 : 92.6% (95% 범위: 89.5% ~ 95.7%) 2024년 6월 예측 : 92.9% (95% 범위: 89.3% ~ 96.5%) 6개월 변화 예측 : +1.6%p =======================================================
마케팅 인사이트
  • MAPE 1.0%로 예측 정확도가 매우 높습니다. 데이터가 이벤트 충격 없이 완만하게 상승하는 구조라 ARIMA가 흐름을 잘 따라갔습니다.
  • 쿠폰 전략이 유지된다면 2024년 상반기까지 구독 유지율 상승세가 지속될 것으로 예측됩니다.
  • 실무 활용법: 매월 실제 구독 유지율을 모니터링하면서 예측값과 비교하고, 차이가 크면 쿠폰 할인율이나 발송 채널을 재조정합니다.

오늘의 핵심 정리

K=3
K-Means 군집
엘보우 방법으로 탐색
+18.8%p
쿠폰 전략으로
재접속률 향상
p=0.014
t-test 결과
통계적으로 유의미
MAPE 1%
ARIMA 예측 정확도
실무 사용 가능
92.9%
2024년 6월
구독 유지율 예측
3단계
군집분석 → A/B테스트
→ ARIMA 파이프라인

오늘의 핵심은 분석 툴 하나하나가 아니라 세 단계가 연결되는 구조입니다. 군집분석으로 대상을 좁히고 → A/B 테스트로 효과를 검증하고 → ARIMA로 미래를 예측하는 것. 그로스 마케터가 데이터로 의사결정하는 실제 파이프라인을 실습한 날이었습니다.