본문 바로가기
데이터 분석/SQL 분석

RFM 분석

by chaemj97 2024. 6. 13.
728x90

RFM 분석으로 사용자를 3가지 관점의 그룹으로 나누기

  • RFM
    • Recency : 최근 구매일
      • 최근 무언가를 구매한 사용자를 우량 고객으로 취급
    • Frequency : 구매 횟수
      • 사용자가 구매한 횟수를 세고, 많을수록 우량 고객으로 취급
    • Monetary : 구매 금액 합계
      • 사용자의 구매 금액 합계를 집계하고, 금액이 높을수록 우량 고객으로 취급
    • 즉, 사용자별로 얼마나 최근에, 얼마나 자주, 얼마나 많은 금액을 지출했는지에 따라 사용자들의 분포를 확인하거나 사용자 그룹(또는 등급)을 나누어 분류하는 분석 기법
  • 사용자별로 RFM을 집계하는 쿼리
with purchase_log as (
	select user_id
		, amount
		-- 날짜
		, substring(stamp, 1, 10) as dt
	from action_log
	where action = 'purchase'
)

, user_rfm as (
	select user_id
		-- 가장 최근 구매일
		, max(dt) as recent_date
		-- 가장 최근 구매일이 오늘로부터 며칠 전
		, current_date - max(dt::date) as recency
		-- 얼마나 자주 구매했는지
		, count(dt) as frequency
		-- 구매 금액
		, sum(amount) as monetary
	from purchase_log
	group by user_id
)

select * from user_rfm;
  • RFM 분석에서 3개의 지표를 각각 5개의 그룹으로 나누는 것이 일반적
    • 125개의 그룹으로 사용자를 나눠 파악할 수 있음
  • RFM 랭크 계산
, user_rfm_rank as (
	select user_id
		, recent_date
		, recency
		, frequency
		, monetary
		-- 최근 구매일 랭크
		, case
			when recency < 14 then 5
			when recency < 28 then 4
			when recency < 60 then 3
			when recency < 90 then 2
			else 1
		end as r
		-- 누계 구매 횟수 랭크
		, case 
			when 20 <= frequency then 5
			when 10 <= frequency then 4
			when 5 <= frequency then 3
			when 2 <= frequency then 2
			else 1
		end as f
		-- 누계 구매 금액 랭크
		, case 
			when 300000 <= monetary then 5
			when 100000 <= monetary then 4
			when 30000 <= monetary then 3
			when 50000 <= monetary then 2
			else 1
		end as m
	from user_rfm	
)

select * from user_rfm_rank;
  • 각 그룹의 사람 수 세기
-- 1부터 5까지의 숫자를 가지는 테이블 만들기
, mst_rfm_index as (
			  select 1 as rfm_index
	union all select 2 as rfm_index
	union all select 3 as rfm_index
	union all select 4 as rfm_index
	union all select 5 as rfm_index
)

, rfm_flag as (
	select m.rfm_index
		, case when m.rfm_index = r.r then 1 else 0 end as r_flag
		, case when m.rfm_index = r.f then 1 else 0 end as f_flag
		, case when m.rfm_index = r.m then 1 else 0 end as m_flag
	from mst_rfm_index as m
	cross join user_rfm_rank as r
)

select rfm_index
	, sum(r_flag) as r
	, sum(f_flag) as f
	, sum(m_flag) as m
from rfm_flag
group by rfm_index
order by rfm_index desc;
  • 극단적으로 적은 사용자 수의 그룹이 발생한다면 RFM 랭크 정의 수정하기
  • 125개의 그룹은 관리하기 어렵다
    1. R+F+M 값을 통합 랭크로 계산하는 방법도 있음
    2. RFM 지표 2개를 사용해서 사용자 층을 정의
  • 정의 후 각 사용자 층을 보다 상위 사용자 층으로 어떻게 옮길 수 있을지 고민하기
    • 서비스 개선 검토, 사용자에 따른 메일 최적화 등
728x90
반응형

댓글