이번 포스팅은 1차 미니프로젝트 이후, 동일한 데이터로 나만의 실습을 진행했다. 데이터는 2016년 1월 ~ 2017년 3월간의 E-커머스 판매 Data를 활용했다.
1. 문제 정의
1차 미니프로젝트에서는 이탈 고객을 탐색했다. 여기서 단순히 이탈한 고객을 탐색하는 것이 아니라, 이탈 위험이 있는 고객군을 찾아 해당 고객에게 프로모션을 제공하면 이탈 방지가 가능하다고 판단했다. 전체 고객 중 3개월 이상 장기 미구매 이력이 있는 고객을 찾고, 어떤 특징을 가지고 있는지 확인해보자.
2. 코드 리뷰
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%config InlineBackend.figure_format = 'retina'
# 한글 폰트설정
plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['axes.unicode_minus'] = False
customers = pd.read_csv('customers.csv')
sales = pd.read_csv('sales.csv')
product = pd.read_csv('products.csv')
데이터는 2016년 1월 ~ 2017년 3월 사이의 판매 데이터, 고객 정보 데이터, 상품 데이터를 활용했다. 먼저, 고객 중 해당 기간에 구매를 하지않은 고객이 있는지 확인해보자.
cnt_orders = pd.merge(customers, sales, how='left', on ='CustomerID') # 고객 정보와 판매 정보 join
cnt_orders['OrderDate'] = pd.to_datetime(cnt_orders['OrderDate']) # data type 변경
cnt_orders.sort_values(['CustomerID','OrderDate'], inplace=True) # 데이터 정렬
cnt_orders = cnt_orders.reset_index(drop=True)
print(cnt_order.isnull().sum())
print(cnt_orders)
merge 이후 NA 값을 확인해보면 아무것도 없다. 즉, 고객 DB에 있는 모든 고객이 판매 기간에 1회 이상 구매를 진행했다. 고객 정보와 판매 데이터는 1:M의 관계이다. 즉, 한 명의 고객이 여러 번의 주문을 할 수 있기 때문에, 고객 데이터를 기준으로 left join을 진행해야한다.
seq_orders = cnt_orders[['CustomerID','OrderDate']]
seq_orders = seq_orders.drop_duplicates(subset=['CustomerID','OrderDate']).reset_index(drop=True)
seq_orders['DaysDiff'] = seq_orders.groupby('CustomerID')['OrderDate'].diff().dt.days # 이전 구매와 현재 구매일 차이 추출
seq_orders['DaysDiff'].fillna(0, inplace=True) # 결측치가 있는 경우, 고객ID가 바뀐 경우임으로 0으로 처리
more_month_order = seq_orders[seq_orders['DaysDiff'] >= 90] # 90일 이상 주문 이력이 없는 고객 확인
more_month_order = more_month_order.drop_duplicates(['CustomerID'])[['CustomerID']].reset_index(drop=True) # 중복ID 제거
more_month_order
이제 주문 내역에서 고객별로 고유한 주문 날짜를 추출하고, 90일 이상 구매이력이 없는 고객정보를 필터링하는데 활용한다. 전체 고객 중, 36.33%의 고객이 90일 이상 구매하지 않은 이력이 존재함을 확인했다. 이제 해당 고객의 정보를 탐색해보자.
df = pd.merge(customers, more_month_order, how='inner', on = 'CustomerID')
df['Age'] = 2016 - df['BirthYear']
df['Age_Group'] = df['Age'] // 10 * 10 # 연령대
# 등록 기간
df['RegisterDate'] = pd.to_datetime(df['RegisterDate'])
df['Registration_Year'] = 2016 - df['RegisterDate'].dt.year
df.head()

연령대 파생변수를 만들고, 장기 미구매 고객의 성별 / 연령대 / 등록연수 / 주소별 고객 정보를 확인했다. 비교적 최근에 가입한 고객의 비중이 높으며, 주로 30~50대 수도권 거주 여성 고객의 비중이 높음을 알 수 있다. 그럼 이 사람들은 어떤 상품을 주문할까?
long_cust = df[['CustomerID']]
sales = pd.read_csv('sales.csv')
long_cust_product = pd.merge(pd.merge(sales, long_cust, how='inner', on = 'CustomerID'),product, how = 'left', on = 'ProductID')
long_cust_product.head()

채소, 반찬류가 많은 것으로 보아 가정 주부의 구매 비율이 높다고 추측할 수 있다.
3. 결과 해석
장기 미구매 고객을 식별했으므로, 그룹에 대한 세분화를 더 심화시켜서 어떤 세부적인 특성을 가진 고객들이 있는지 확인할 수 있다. 예를 들어, 30~50대 수도권 거주 여성 중에서 주부인지, 직장인인지, 혼자 사는지 등을 파악해서 보다 정밀한 결과를 확인할 수 있다. 아쉽게도 해당 데이터엔 가족 구성원 관련 정보가 없어, 세분화가 불가능하다. 혹은, 해당 고객층이 어떤 마케팅 채널을 언제 이용하는지 파악하여 접근하는 방법도 활용할 수 있다. 예를 들어, 가정 주부의 경우 주중에 쇼핑을 하거나, 오전/오후에 홈쇼핑을 시청하는 경우가 있으므로 주중에 특별한 할인 혹은 무료 배송 혜택을 제공할 수도 있다.
간단한 분석임에도, 장기 미구매 고객 중 가정 주부가 많다고 추측할 수 있었다. 다음 포스팅에서는 오늘 만든 cnt_orders 테이블에서 고객 ID, 구매 날짜, 구매 금액, 구매 상품 column을 활용해 전체 고객을 대상으로 RFM 분석 및 Retention 실습을 진행해보자.
'Aivle > Project' 카테고리의 다른 글
| [에이블스쿨] 구글 플레이 스토어 리뷰 분석 (0) | 2024.05.19 |
|---|---|
| [에이블스쿨] GCP, Naver Cloud, 형태소 분석기 바른 (1) | 2024.04.20 |
| [에이블스쿨] 잡코리아 웹크롤링 (2) | 2024.03.21 |
| [에이블스쿨] RFM, Retention (0) | 2024.03.12 |
| [에이블스쿨] Python에서 WorkBench 연결 (0) | 2024.03.10 |