프로젝트 주제
카테고리 리스크 노출 기반 이커머스 고객 이탈(Churn) 예측
프로젝트 목적
- 고객 이탈(재구매 중단)을 머신러닝으로 예측
- 왜 이탈하는지 납득시키기 위해 카테고리 리스크 지수와 고객 리스크 노출(Exposure)이라는 설명 가능한 구조를 만듦
- Streamlit으로
- 월별 리스크 급증 카테고리 경보
- 고위험 고객 리스트 / 개별 고객 분석
- 모델 비교(리스크 넣기 전/후 성능 차이)를 보여줌
참고 데이터
이커머스 고객 세분화 분석 아이디어 경진대회
실제 이커머스 환경에서 발생하는 데이터를 이용한 대회
주의
이 데이터에 사용된 csv파일은 절대 깃허브에 업로드하면 안됨
데이터 요약
데이터 기간
테이블
-
Customer_info: 고객ID, 성별, 고객지역, 가입기간
-
Discount_info: 월, 제품카테고리, 쿠폰코드, 할인율
-
Marketing_info: 날짜, 오프라인비용, 온라인비용
-
Onlinesales_info: 고객ID, 거래ID, 거래날짜, 제품ID, 제품카테고리, 수량, 평균금액, 배송료, 쿠폰상태
-
Tax_info: 제품카테고리, GST
쿠폰상태 값
- Clicked / Used / Not Used
카테고리
- Nest-USA, Office, Apparel, Bags, Drinkware, …, Nest(22개)
핵심 개념 : 프로젝트의 예측
라벨 : 맞추고 싶은 정답(목표값)
이 고객이 곧 이탈할까?
Churn(이탈) 정의를 직접하는 이유
참고한 데이터는 이탈 컬럼이 존재하지않아 거래 기록으로 이탈을 정의
Churn(이탈) 라벨 정의
- 단위 : 고객 - 월 (Customer-Month)
- 관측월 m의 '월말' 이후 60일 동안 구매가 0건이면 churn= 1, 있으면 churn = 0
8월의 관측 데이터로 피처를 만들고 9~10월(약 60일)동안 구매가 없을시 churn = 1
60일을 기준으로 잡은 이유 (데이터 기간 제약)
- 이 데이터는 1년동안의 데이터만 존재하므로 11월, 12월은 다음년도로 넘어가기에 1월~10월(10개월만)
- 11,12월은 학습/평가에서 제외하거나 예측만 가능
시간 누수(데이터 누수의 일종)
- 미래 정보를 몰래 보고 예측
11~12월 구매 데이터를 피처에 섞으면 모델이 과하게 좋아지는 데이터 누수가 발생 => 그러한 이유로 평가를 시간순(train -> test)으로
핵심 아이디어 : 카테고리 리스크 지수 & 고객 노출(Exposure)
카테고리 리스크를 만드는 이유
리뷰/ 불만 데이터가 없어 아래를 불만/불편/가성비 악화의 대리 신호(Proxy)로 사용
- 할인율이 줄어듦(가성비 악화)
- 배송비 부담이 커짐
- 쿠폰상태가 누름(Clicked) 하지만 실제 사용(Used)으로 안 이어짐 -> 마찰 / 불만 가능성
- 마케팅을 했는데도 수요(구매자수) 급락 -> 품질/관심 저하가능성
- 세금(GST)이 높은 카테고리(고정 부담)
리스크 지수 구성(실제 계산항목)
월 m, 카테고리 c에서 아래를 구성
A) 수요 급락 리스크(핵심)
- buyers_mc : 구매고객수(고객ID nunique)
- demand_drop_mc : 전월 대비 구매고객수 감소율
B) 배송비 부담 리스크
- ship_ratio_mc : 배송료/매출(또는 주문금액) 비율
C) 할인 축소 리스크
- Discount_info 결합
- disc_rate_mc : 평균 할인율
- disc_drop_mc : 전월 대비 할인율 하락 (할인 줄면 리스크↑)
D) 쿠폰 마찰 리스크
- clicked_share_mc, used_share_mc
- coupon_friction_mc = clicked_share_mc - used_share_mc
- 클릭은 했는데 사용이 안 됨 → 마찰↑ → 리스크↑
E) 세금 리스크(고정)
F) 마케팅 환경(월 단위)
risk_index는 표준화(z-score)를 이용
- 표준화 (z-score) : 표준화된 척도를 사용하여 각 데이터 값이 평균에서 얼마나 떨어져 있는지 측정하는 방법
risk_index_mc = z(demand_drop_mc) + z(ship_ratio_mc) + z(disc_drop_mc) + z(coupon_friction_mc) + z(gst_c)
고객 - 월 데이터셋 생성(모델 입력데이터)
고객 - 월 기본 피처(M0:베이스라인)
Onlinesales_info를 고객ID * 월로 집계하여 생성
구매/활동
배송
- ship_sum, ship_mean
- ship_ratio = ship_sum / revenue_sum
쿠폰
- clicked_share, used_share, not_used_share
- coupon_friction = clicked_share - used_share
카테고리 패턴
- cat_cnt: 구매한 카테고리 수
- top_cat_share: 최상위 카테고리 매출 비중
- cat_entropy: 다양성(선택)
고객정보
고객 리스크 노출 피처(M1/M2의 핵심)
고객 i가 월 m에 구매한 카테고리들의 risk_index[m,c]를 연결 후 고객단위로 요약
- exposure_mean_im: (매출 가중) 평균 리스크 노출
- exposure_max_im: 최대 리스크 노출
- exposure_high_share_im: 리스크 상위 카테고리 매출 비중
- exposure_roll3_im: 최근 3개월 노출 평균(과거만)
노출(Exposure)은 ' 이 고객이 이번달 위험 카테고리를 얼마나 샀나 '를 숫자로 만든 것
머신러닝 실험 설계(결론을 만드는 구조)
Ablation실험
- “특정 피처/아이디어를 넣기 전후로 성능이 얼마나 바뀌는지 비교”하는 실험
- 여기서는 “카테고리 리스크/노출이 진짜 도움이 되는지”를 증명
필수 비교 세트(프로젝트의 핵심 표)
- M0(Baseline): 고객-월 기본 피처만
- M1(Risk Added): M0 + exposure 피처
- M2(Risk + Time): M1 + exposure_roll3 같은 누적/지연 피처
모델 후보(정형데이터 표준)
- Logistic Regression(기준선)
- LightGBM 또는 XGBoost(주력)
- CatBoost(범주형 변수 많으면 유리)
- RandomForest(보조)
검증 방식
- Train: 2019-01 ~ 2019-08
- Val: 2019-09
- Test: 2019-10
지표
- ROC-AUC
- PR-AUC
- Top-K Recall(상위 위험 고객 K%의 적중률)
Streamlit 앱 구성(데모 최소 구성)
-
Overview
- 데이터 범위, churn-60 정의
- 월별 이탈률 트렌드
-
Risk Dashboard
- 월×카테고리 risk_index 히트맵
- 리스크 급증 카테고리 Top-N
- 리스크 분해(배송↑/할인↓/수요↓/마찰↑)
-
Model Leaderboard
- 모델별 성능표
- M0 vs M1 vs M2 성능 비교(리스크가 효과 있었는지)
-
Customer Drilldown
- 고객ID 입력 → 이탈확률
- 최근 구매 카테고리 & 노출 추적 그래프
- “왜 위험한지” (feature importance/SHAP)