티스토리 뷰

카테고리 없음

RFM 고객 세그멘테이션

루돌푸다요 2024. 3. 31. 00:59

고객 세그멘테이션의 정의 

  • 비지도 학습이 가장 많이 사용되는 분야는 고객 관계 관리 (Customer Relationship Management, CRM) 분야 입니다 .
    이중 고객 세그멘테이션(Custmer Segmentation) 은 다양한 기준으로 고객을 분류하는 기법입니다. 
    주로 타겟 마케팅 이라 불리는 고객 특성에 맞게 세분화 하여 유형에 따라 맞춤형 마케팅 이나 서비스를 제공하는 것을 목표로 둡니다. 

 

  • RFM 의 개념 
    - Recency(R) : 가장 최근 구입 일에서 오늘 까지의 시간 
    - Frequency(F) : 상품 구매 횟수 
    - Monetary value(M) : 총 구매 금액 

https://archive.ics.uci.edu/dataset/352/online+retail

 

UCI Machine Learning Repository

This dataset is licensed under a Creative Commons Attribution 4.0 International (CC BY 4.0) license. This allows for the sharing and adaptation of the datasets for any purpose, provided that the appropriate credit is given.

archive.ics.uci.edu

 

컬럼 정보 

  • invoiceNo : 6자리의 주문 번호 (취소된 주문은 C 로 시작) 
  • StockCode : 5자리의 제품 코드 
  • Description : 제품 이름(설명) 
  • Quantity : 주문 수량 
  • InvoiceDate : 주문 일자, 날짜 자료형 
  • Unitprice : 제품 단가 
  • CustomerID : 5자리의 고객 번호 
  • Country : 국가명 

데이터 전처리 

  • customerID  : 결측치 삭제 
  • InvoiceNo. Uniprice, Qiantity 데이터 확인 및 삭제 
  • 영국 데이터 만 취함 

RFM 기반 데이터 가공 

  • 날짜 데이터 가공 
  • 최종 목표 
!pip install openpyxl

retail_df =pd.read_excel ( 본인의 주소를 넣으세요.  ) 
retail_df.head(3)

retail_df.info()

retail_df.isnull().sum()

#데이터 EDA 및 전처리 
retail_df.describe(include ='all')

cond1 = reteail_df['Quantity']<0
retail_df[cond1]

#데이터 전처리 전략 
customerID 결측치인것은 삭제
Invoice가 C로 시작하거나, quantity가 음수이거나, unitprice가 음수인것은 모두 삭제

cond_cust = (retail_df['CustomerID'].notnull())
retail_df[cond_cust].isnull().sum()


cond_invo = (retail_df['InvoceNo'].astype(str).str[0] != 'C')
retail_df[cond_invo].head(3)

cond_minus = (retail_df['Quantity'] > 0 & (retail_df['Unitprice'] >0 )
retail_df[cond_minus]

retail_df_2 = retail_df[cond_cust & cond_invo & cond_minus]
retail_df_2.info()

retail_df_2['Country'].value_cunts()[:10]

cond_uk = (retail_df_2['Country'] == 'United Kingdom')
retail_df_2 = retail_df_2[cond_uk]
retail_df_2


retail_df_2.describe(include = 'all')

retail_df_2['Amt'] = retail_df_2['Quantity'] * retail_df_2['UnitPrice']
retail_df_2['Amt'] = retail_df_2['Amt'].astype('int')

retail_df_2[['CustomerID']].drop_duplicates()

retail_df_2.pivot_table(index = 'CustomerID', values ='Amt', aggfunc='sum).sort_values('Amt', ascending=False)


imprt datetime as dt
#2011.12.10일 기준으로  9일이 마지막 결제이기 때문에. 각 날짜를 빼고 +1 
추후 CustomerID 기준으로 Priod 의 최소의 Priod를 구하면 그것이 Recency 
1번 사람 100일전, 20일전, 5일전 

retail_df_2['Period'] = (dt.datetime(2011,12,10) - retail_df2['InvoiceDate']).apply(lamda x: x.days+1)
retail_df_2.head(3)

rfm_df = retail_df2.groupby('CustomeriD').agg({
	'Period' : 'min',
    'Invoice : 'count',
    'Amt' : 'sum'
})
rfm_df 

rfm_df.columns = ['Recency', 'Frequency', 'Monetary']

sns.histplot(rfm_df['Recency']

sns.histplot(rfm_df['Frequency']

sns.histplot(rfm_df['Monetary']

#데이터 정규화
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
x_features = sc.fit_transform(rfm_df[['Recency', 'Frequency', 'Monetary']])

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score 

kmeans = KMeans(n_clusters =3, random_state =42)
labels =kmeans.fit_predict(X_features)
rfm_df['label'] = labels 

silhouette_score(X_features, labels)

from kmeans_visaul import visualize_silhouette
visualize_silhouette([2,3,4,5,6], X_Features)

log 스케일을 통한 추가 전처리
import numpy as np



rfm_df['Recency_log'] = np.log1p(rfm_df['Recency']) 
rfm_df['Frequency'_log'] = np.log1p(rfm_df['Frequency']) 
rfm_df[ 'Monetary' = np.log1p(rfm_df[ 'Monetary']) 
x_features =rfm_df[['Recency_log', 'Frequency'_log', 'Monetary']] 
sc2 = standardScaler()
X_features2_sc =sc2.fit_transform(X_features2)

visualize_silhouette([2,3,4,5,6], X_features2_sc)