해당 내용은 멋쟁이사자처럼 AI School 오늘코드 박조은 강사의 자료입니다.
중복제거하기
# 중복 데이터 중 첫번째 것만(keep='first') 봅니다.
# keep은 중복 데이터 발견시에 어떤 데이터를 유지하고 제외할지 결정해주는 변수입니다. ('first', 'last','False'로 선택적 입력 가능)
raw_valid[raw_valid.duplicated(keep='first')].sort_values(by=["InvoiceNo","StockCode"])
# 중복데이터 모두 출력(keep = False) 합니다.
# raw_valid[raw_valid.duplicated(keep=False)].sort_values(by=["InvoiceNo","StockCode"])
# drop_duplicates로 중복을 제거합니다.
raw_valid = raw_valid.drop_duplicates()
R => 값이 작을 수록 높은 점수를 줍니다. 왜냐하면 최근에 왔는지를 보기 때문에
F => 값이 높을 수록 높은 점수를 줍니다. 왜냐하면 자주 왔는지를 보기 때문에
M => 값이 높을 수록 높은 점수를 줍니다. 왜냐하면 얼마나 많은 금액을 구매했는지 보기 때문에
그룹바이에 lambda 활용
# RFM 으로 변수의 이름을 변경합니다.
# InvoiceDate 는 Recency
# InvoiceNo 는 Frequency
# TotalPrice 는 MonetaryValue
rfm = df.groupby("CustomerID").agg({"InvoiceDate":lambda x:(last_timestamp-x.max()).days,"InvoiceNo": "count","TotalPrice":"sum"})
rfm.columns = ["Recency","Frequency","Monetary"]
rfm
- 파생변수를 별도로 만들어서 (x.max()) 계산하는 것도 가능
- 또는 lambda를 사용자 지정함수로 선언 후 활용 가능
컬럼 이름 변경 더 많은 컬럼을 한번에 바꾸고 싶을때,(dictionary 활용법)
rfm.rename(columns={"InvoiceDate":"Recency","InvoiceNo": "Frequency","TotalPrice":"MonetaryValue"})
RFM 모형
Scoring 기법: RFM의 요인을 각각 5등급으로 등간격으로 분류하는 방법이다.
현재 개발된 RFM 모형은 크게 4가지로 분류 할 수 있다. 이 문서의 내용들은 정설이 아니며 신뢰하기 어려움을 전제로 참고해야한다.
- 모델1. RFM 각 요소의 20% rule의 적용
- 모델2. 비율 척도에 의한 양적인 정도의 차이에 따른 등간격의 5등급 분류
- 모델3. 상하 20%를 제외한 등간격 척도에 의한 그룹 분류
- 모델4. 군집 분석에 의한 각 요소 별 5개의 그룹 분류
출처 : RFM - 위키백과, 우리 모두의 백과사전
# Recency 는 최근일수록 높은 스코어를 갖도록 합니다.
# list(range(5,0,-1))
# Frequency, MonetaryValue 는 값이 클 수록 높은 스코어를 갖도록 합니다.
r_labels = list(range(5,0,-1))
f_labels = list(range(1,6))
m_labels = list(range(1,6))
cut_size = 5
# 상대평가의 관점으로 스케일링 해주는 효과
r_cut = pd.qcut(rfm["Recency"], q = cut_size, labels =r_labels)
f_cut = pd.qcut(rfm["Frequency"], q = cut_size, labels = f_labels)
m_cut = pd.qcut(rfm["MonetaryValue"], q = cut_size, labels = m_labels)
display(r_cut.head())
display(f_cut.head())
display(m_cut.head())
# assign 을 사용하면 여러 변수를 한 번에 만들 수 있습니다.
rfm = rfm.assign(R=r_cut, F=f_cut, M=m_cut)
rfm.astype(float).hist(bins=50, figsize=(12,6));
rfm.groupby("RFM_score").agg({"Recency":"mean",
"Frequency":"mean",
"MonetaryValue":["mean","sum"]}).style.background_gradient("Oranges").format("{:.0f}")
- .style.background_gradient("Oranges")
- .format("{:.0f}")