앞전 포스팅에서 시간의 흐름에 따른 여러 추이에 대해 살펴보았습니다.
이번 내용에서 다룰 내용은 분석 목적 2번인 리텐션 분석입니다.
- 시간의 흐름에 따라 매출, 주문 고객수, 주문 단가의 추이는 어떻게 달라지는가?
- 리텐션 분석: 시간의 흐름에 따라 고객이 얼마나 남고 이탈했는가?
- RFM 분석 : 고객 행동에 따라 고객을 유형화하기
5. 리텐션(Retetion) 분석
리텐션 분석은 고객 유지율을 분석하는 과정으로, 특정 기간 동안 얼마나 많은 고객이 지속적으로 제품이나 서비스를 이용하고 있는지를 측정하는 방법입니다. 본 분석에서는 특정 월에 구매한 고객이 다음 월에도 구매를 했는지에 대해 초점을 두고 분석을 진행해 보겠습니다.
데이터를 다시 살펴보겠습니다.
데이터는 한 영수증 번호에 여러 개의 상품이 존재하는 형태입니다.
우리가 궁금한 건 특정 월에 구매한 고객이 다음 월에도 구매했는지 이기 때문에,
고객이 몇 개의 상품을 구매했는지 어떤 상품을 구매했는지는 현재 관심이 없습니다.
그러기 때문에 고유한 영수증 번호만 남기게 데이터 셋을 한번 정리해 줄 필요가 있습니다.
drop_duplicate 함수를 이용하여 중복된 영수증 번호를 제거해 줍니다.
또한, 우리는 현재 월 단위에 관심이 있기 때문에 date_ym에 대한 변수도 추가 생성해 줍니다.
# 연월 단위로 고객번호, 영수증번호 전처리
retention_base = data[['CustomerID', 'InvoiceNo', 'date_ymd']].drop_duplicates()
retention_base['date_ym'] = retention_base['date_ymd'].dt.to_period('M')
retention_base.head(3)
그리고 분석에 사용된 데이터의 날짜 범위를 수정해 주겠습니다.
raw 데이터의 날짜 범위는 2010-12-01부터 2011-12-09입니다.
데이터 범위가 11년 12월을 모두 포함하는 것이 아니기 때문에,
11년 11월에 구매한 고객이 12월에 다시 구매하는 retetion은 낮을 수밖에 없습니다.
분석 기간의 일관성을 위해 11월까지의 데이터만 사용하는 것으로 날짜 범위를 수정해 줄 필요가 있습니다.
retention_base = retention_base.query("date_ymd < '2011-12-01'") # 2011-11-30일 까지의 데이터
리텐션은 보통 반복문을 사용하여 계산합니다.
하지만 저희는 바로 반복문으로 넘어가기 전에, 2010년 12월에 구매한 고객이 2011년 1월에 구매한 retention을 계산해 보면서 원리를 살펴보겠습니다.
먼저 리텐션 계산을 하기 위해 date_ym에 대한 고유값 리스트를 생성해 줍니다,
date_ym_list = sorted(list(retention_base['date_ym'].unique()))
date_ym_list
2010년 12월에 구매한 고객이 2011년 1월에 구매한 retention을 계산이 현재 목적이기 때문에 date_ym_list의 0,1번째 값을 이용하여 start와 target값을 설정해 줍니다.
period_start = date_ym_list[0] #2010-12
period_target = date_ym_list[1] #2011-01
이제 query 함수를 이용하여 retetion_base 데이터 프레임에서 date_ym 값이 2010-12인 CustomerID를 구해줍니다.
retention_base.query('date_ym == @period_start')['CustomerID']
2010년 12월에 해당 유통회사에서 물품을 구매한 고객을 추출해 보면 총 1400이네요.
date_ym이 period_start, period_target인 고객들을 각 각 period_start_users, period_target_users로 지정했습니다.
이어서 intersection 함수를 이용하여 교집합 유저를 계산하면 12월과 1월 모두 구매한 고객을 추출할 수 있습니다.
period_start_users = set(retention_base.query('date_ym == @period_start')['CustomerID'])
period_target_users = set(retention_base.query('date_ym == @period_target')['CustomerID'])
# 교집합 유저 계산
retained_users = period_start_users.intersection(period_target_users)
이제 리텐션을 구해보겠습니다.
# 리텐션 계산
retention_rate = len(retained_users) /len(period_start_users)
retention_rate
2010년 12월에 구매한 고객이 2011년 1월에 구매한 retention은 0.366이네요
이제 반복문을 통해 계산해 보겠습니다.
동일한 내용의 반복이니 for문을 이해하시는데 무리가 없을 거라 생각됩니다.
# 반복문을 통한 retetion 계산
retention = pd.DataFrame()
for s in date_ym_list:
for t in date_ym_list:
period_start = s
period_target = t
if period_start <= period_target:
period_start_users = set(retention_base.query('date_ym == @period_start')['CustomerID'])
period_target_users = set(retention_base.query('date_ym == @period_target')['CustomerID'])
retained_users = period_start_users.intersection(period_target_users)
retention_rate = len(retained_users) / len(period_start_users)
temp = pd.DataFrame({'cohort': [period_start], 'date_ym': [period_target], 'retention_rate':[retention_rate]})
retention = pd.concat([retention, temp])
드디어 리텐션을 다 구했습니다.
하지만 저희는 여기서 멈추지 않고, 구해진 리텐션을 이용하여 코호트 분석을 수행해 보겠습니다.
그러기 위해선 약간의 추가 작업이 필요합니다.
date_ym에서 cohort를 빼서 몇 달 후인지에 대한 계산을 진행하고 이걸 cohort_size(month)라고 이름 붙이겠습니다.
retention['cohort_size(month)'] = retention.apply(lambda x: (x['date_ym'] - x['cohort']).n, axis=1)
retention.head()
pivot_table을 이용하여 코호트 차트를 생성해 줍니다.
#데이터 타입 변경
retention['cohort'] = retention['cohort'].astype('str')
retention['date_ym'] = retention['date_ym'].astype('str')
retetion_final = pd.pivot_table(data= retention, index = 'cohort', columns= 'cohort_size(month)', values = 'retention_rate')
retetion_final
# 시각화
fig = px.imshow(retetion_final, text_auto= '.2%', color_continuous_scale='Burg')
fig.show()
시각화 결과를 살펴보면,
과거에서 최근으로 올 수록 1_month 리텐션이 35%대에서 40, 45% 대로 증가한 것을 알 수 있습니다.
또한, 맨 끝의 대각선 수치를 보면 색이 진한 것을 알 수 있습니다.
이는 2011년 11월에 많은 유저들이 복귀했음을 알 수 있습니다.
이처럼 리텐션 분석을 진행할 경우,
코호트 사이즈에 따른 리텐션이 시간의 흐름에 따라서 어떻게 변해왔는지에 대해 세로축으로 분석할 수도 있고,
대각선으로 분석을 하게 되면 특정 타켓이 되는 월이 얼마나 효과적인 리텐션 전략이 구사가 되었는지를 확인할 수 있습니다.
이번엔 리텐션 커브를 구해보겠습니다.
# 리텐션 커브 -> 평균을 내는 것
retention_curve = retention.groupby('cohort_size(month)')['retention_rate'].mean().reset_index()
fig = px.line(retention_curve, x = 'cohort_size(month)', y = 'retention_rate')
fig.show()
보통 리텐션은 코호트 사이즈가 커지면 내려가기 마련인데,
해당 이커머스의 경우에는 시간이 흐름에도 일정 리텐션율을 유지하고 있으며 오히려 최근 들어 높아진 것을 확인할 수 있습니다. 이를 통해 해당 유통회사가 리텐션 전략을 잘 구사했다는 것을 알 수 있습니다.
이것으로 리텐션 분석에 대해 마치겠습니다.
나머지 분석은 다음 포스팅에 이어서 진행하겠습니다. 감사합니다.
'데이터 분석 > 프로젝트' 카테고리의 다른 글
[Python] 사용자 행동 로그 데이터를 활용한 퍼널 분석 (5) | 2024.10.02 |
---|---|
[Python] 유통 데이터를 활용한 리텐션과 RFM 분석(4) (0) | 2024.08.25 |
[Python] 유통 데이터를 활용한 리텐션과 RFM 분석(2) (0) | 2024.07.21 |
[Python] 유통 데이터를 활용한 리텐션과 RFM 분석(1) (0) | 2024.07.21 |
[마케팅 데이터 분석] AARRR 실습(1) - Acquisition (2) | 2023.09.09 |