CustomerID | LastOrderDate | R (기준일:2023-11-01) | OrderCount | F | TotalAmount | M |
C001 | 2023-10-28 | 4 (DAYS("2023-11-01", "2023-10-28")) | 5 | 5 | 500000 | 500000 |
C002 | 2023-08-15 | 78 | 2 | 2 | 100000 | 100000 |
C003 | 2023-10-01 | 31 | 10 | 10 | 1200000 | 1200000 |
RFM 스코어 (예시) | 고객 세그먼트 | 특징 | 마케팅 전략 제안 |
555 | 챔피언 (Champions) | 최근에, 자주, 많이 구매하는 최고의 고객 | VIP 프로그램, 신제품 우선 체험, 로열티 보상, 추천 유도 |
X5X (예: 454, 355) | 충성 고객 (Loyal Customers) | 꾸준히 자주 구매 | 맞춤형 상품 추천, 멤버십 혜택 강화, 후기 요청 |
5XX (예: 511, 522) | 신규 고객 (New Customers) | 최근에 구매했지만 아직 빈도/금액은 낮음 | 환영 메시지, 첫 구매 감사 쿠폰, 재구매 유도 프로그램 |
1XX (예: 155, 144) | 이탈 우려 고객 (At Risk) | 과거에는 자주/많이 구매했으나 최근 구매가 없음 | 할인 쿠폰, 특별 프로모션, 설문조사를 통한 불만 파악 |
111, 121 등 | 이탈 고객 (Lost Customers) | 오랫동안 구매가 없고, 빈도/금액도 낮음 | 마지막 구매 상기, 파격적인 재활성화 오퍼 (필요시 포기) |
34X, 43X 등 | 잠재 충성 고객 (Potential Loyalists) | 최근 구매, 구매 빈도/금액 성장 가능성 높음 | 포인트 제도 안내, 멤버십 가입 유도, 관련 상품 추천 |
XX1 (예: 441, 331) | 저가치 고객 (Low Spenders) | 구매 빈도는 있으나 구매 금액이 작음 | 객단가 상승 유도 (묶음 상품, 추가 구매 혜택) |
import pandas as pd
from datetime import datetime
# 예시 데이터 로드 (실제로는 DB나 CSV에서 로드)
data = {'CustomerID': ['C001', 'C001', 'C002', 'C003', 'C003', 'C001'],
'OrderDate': ['2023-10-01', '2023-10-28', '2023-08-15', '2023-09-10', '2023-10-01', '2023-07-05'],
'OrderAmount': [100000, 50000, 100000, 70000, 80000, 150000]}
df = pd.DataFrame(data)
df['OrderDate'] = pd.to_datetime(df['OrderDate'])
# 기준일 설정
analysis_date = datetime(2023, 11, 1)
# RFM 계산
rfm_df = df.groupby('CustomerID').agg(
Recency_Value=('OrderDate', lambda x: (analysis_date - x.max()).days),
Frequency_Value=('OrderDate', 'count'),
Monetary_Value=('OrderAmount', 'sum')
).reset_index()
# RFM 스코어링 (qcut 활용 - 분위수 기반)
# Recency는 낮을수록 좋으므로, 점수를 반대로 매기거나 별도 처리 필요.
# 여기서는 간단히 qcut 후 레이블 순서를 조정하는 방식으로 처리 가능 (또는 rank 사용)
# labels=[5,4,3,2,1] for recency, labels=[1,2,3,4,5] for frequency/monetary
# Recency 점수 (값이 작을수록 높은 점수)
rfm_df['R_Score'] = pd.qcut(rfm_df['Recency_Value'], 5, labels=[5, 4, 3, 2, 1], duplicates='drop')
# Frequency 점수 (값이 클수록 높은 점수)
rfm_df['F_Score'] = pd.qcut(rfm_df['Frequency_Value'].rank(method='first'), 5, labels=[1, 2, 3, 4, 5], duplicates='drop')
# Monetary 점수 (값이 클수록 높은 점수)
rfm_df['M_Score'] = pd.qcut(rfm_df['Monetary_Value'].rank(method='first'), 5, labels=[1, 2, 3, 4, 5], duplicates='drop')
rfm_df['RFM_Score_Concat'] = rfm_df['R_Score'].astype(str) + rfm_df['F_Score'].astype(str) + rfm_df['M_Score'].astype(str)
print(rfm_df.head())
# 이후 RFM_Score_Concat 또는 개별 점수 조합으로 세그먼트 정의
# 예: champions = rfm_df[rfm_df['RFM_Score_Concat'] == '555']