파이썬 데이터 분석 실무 테크닉 100
03장 _ 고객의 전체 모습을 파악하는 테크닉 [ 머신러닝 ]
1. 데이터 불러오고 확인하기
import pandas as pd
use_log = pd.read_csv("c:/data/use_log.csv")
customer_m = pd.read_csv("c:/data/customer_master.csv")
class_m = pd.read_csv("c:/data/class_master.csv")
campaign_m = pd.read_csv("c:/data/campaign_master.csv")
use_log.head()
customer_m.head()
class_m.head()
campaign_m.head()
2. 고객 데이터 가공하기
# customer_m에 class_m 결합
customer_join = pd.merge(customer_m, class_m, on="class", how="left")
# campaign_m 결합
customer_join = pd.merge(customer_join, campaign_m, on="campaign_id", how="left")
customer_join.head()
print(len(customer_m)) # 4192
print(len(customer_join)) # 4192
데이터 개수도 join 전후로 변화가 없는 것이 확인됩니다.
조인할 때 key가 없거나 join이 잘못되면 자동으로 결측치가 생긴다.
따라서 조인 후 결측치를 확인해야 한다.
# 결측치 확인
customer_join.isnull().sum()
조인하며 추가한 열은 결측치가 0이므로 문제가 없어보입니다.
3. 고객 데이터를 집계하자
데이터 가공을 끝냈으니 고객 데이터를 집계해서 전체 모습을 살펴보자
1. class_name별로 집계
customer_join.groupby("class_name").count()["customer_id"]
- 종일 반이 절반정도를 차지하고, 종일/야간/주간 순으로 회원이 많다.
2. campaign_name별로 집계
customer_join.groupby("campaign_name").count()["customer_id"]
- 캠페인은 일반 입회가 가장 많다.
3. gender별로 집계
customer_join.groupby("gender").count()["customer_id"]
- 여자보다 남자가 더 많다.
4. is_deleted별로 집계
customer_join.groupby("is_deleted").count()["customer_id"]
- 2019년 3월 현재 가입된 회원은 2842명, 탈퇴한 유저는 1350명이다.
# 2018.04.01 ~ 2019.03.31에 가입한 인원은 몇 명일까? #
# 2018.04.01 ~ 2019.03.31 가입 인원 집계해보자
# 궁금한 부분 각자 해보기
customer_join["start_date"] = pd.to_datetime(customer_join["start_date"])
customer_start = customer_join.loc[customer_join["start_date"] > pd.to_datetime("20180401")]
len(customer_start) # 1361
4. 최신 고객 데이터 집계하기
가장 최근 월 (2019년 3월)의 고객 데이터를 파악해보자
# end_date를 datetime형으로 변환
customer_join["end_date"] = pd.to_datetime(customer_join["end_date"])
# 2019.03.31에 탈퇴한 회원 & 재적 중인 고객 추출
customer_newer = customer_join.loc[
(customer_join["end_date"] >= pd.to_datetime("20190331")) |
(customer_join["end_date"].isna())]
print(len(customer_newer))
customer_newer["end_date"].unique()
- 2019.03.31에 탈퇴한 고객, 탈퇴하지 않은 고객은 총 2953명이다.
회원별, 캠페인별, 성별로 전체를 파악해보자
# 회원별
customer_newer.groupby("class_name").count()["customer_id"]
# 캠페인별
customer_newer.groupby("campaign_name").count()["customer_id"]
# 성별
customer_newer.groupby("gender").count()["customer_id"]
- 회원별, 성별은 전체기간과 19년 03월의 비율 차이가 크지 않다.
- 캠페인에서 일반이 차지하는 비율은 전체기간일 때 72%, 19년 03월은 81%이다.
- 입회 캠페인이 회원 비율 변화에 영향을 미친다고 추측할 수 있다.
5. 이용 데이터 집계하기
고객 데이터와 달리 이용 데이터는 시간적인 요소를 분석할 수 있다.
이용 데이터를 이용해 고객을 파악해보자
1. 연월, 고객별 이용 횟수 집계
# usedate를 datetime형으로 바꾸기
use_log["usedate"] = pd.to_datetime(use_log["usedate"])
use_log["연월"] = use_log["usedate"].dt.strftime("%Y%m")
# 연월, id로 그룹화하기
use_log_months= use_log.groupby(["연월", "customer_id"], as_index = False).count()
# 컬럼 이름 바꾸기
use_log_months.rename(columns={"log_id":"count"}, inplace=True)
del use_log_months["usedate"]
use_log_months.head()
2. 고객별 월 이용 횟수 집계 (평균값, 중앙값, 최댓값, 최솟값)
use_log_customer = use_log_months.groupby("customer_id").agg(["mean", "median", "max", "min"])["count"]
use_log_customer = use_log_customer.reset_index(drop=False) # 칼럼 정리
use_log_customer.head()
6. 이용 이력 데이터로부터 정기 이용 플래그 작성하기
정기적으로 센터를 이용하는 고객을 특정해보자 (매주 같은 요일에 왔는지 아닌지로 판단)
1. 고객별 월/요일 집계
# 요일을 숫자로 변환
use_log["weekday"] = use_log["usedate"].dt.weekday
use_log_weekday = use_log.groupby(["customer_id", "연월", "weekday"]
, as_index=False).count()[["customer_id", "연월", "weekday", "log_id"]]
use_log_weekday.rename(columns={"log_id":"count"}, inplace=True)
use_log_weekday.head()
- AS002855 회원은 2018년 4월, 2018년 5월 모두 토요일에 4번 방문한 것으로 보아 매주 토요일에 정기적으로 방문하는 것으로 보입니다.
2. 고객별 최댓값 구하고, 최댓값이 4 이상인 경우 플래그 지정
use_log_weekday = use_log_weekday.groupby("customer_id", as_index=False).max()[["customer_id", "count"]]
# routine_flg 컬럼 만들고 플래그 지정
use_log_weekday["routine_flg"] = 0
use_log_weekday["routine_flg"] = use_log_weekday["routine_flg"].where(use_log_weekday["count"]<4, 1)
use_log_weekday.head()
7. 고객 데이터와 이용 이력 데이터 결합하기
customer_join에 use_log_customer과 use_log_weekday를 결합하자
customer_join = pd.merge(customer_join, use_log_customer, on="customer_id", how="left")
customer_join = pd.merge(customer_join, use_log_weekday[["customer_id", "routine_flg"]],
on="customer_id", how="left")
customer_join.head()
8. 회원 기간 계산하기
이용 이력(시간적인 변화 데이터)를 추가했기 때문에 회원 기가 칼럼을 하나 더 추가해두자
# 날짜 비교 함수 relativedelta 사용하기 위해 import
from dateutil.relativedelta import relativedelta
# 날짜 계산용 칼럼 생성
customer_join["calc_date"] = customer_join["end_date"]
customer_join["calc_date"] = customer_join["calc_date"].fillna(pd.to_datetime("20190430"))
# 기간 컬럼
customer_join["membership_period"] = 0
for i in range(len(customer_join)):
delta = relativedelta(customer_join["calc_date"].iloc[i],
customer_join["start_date"].iloc[i])
customer_join["membership_period"].iloc[i] = delta.years*12 + delta.months
customer_join.head()
회원 기간 칼럼이 잘 추가된 것을 확인할 수 있다.
9. 고객 행동의 각종 통계량 파악하기
1. mean, median, max, min의 통계량 파악하기
customer_join[["mean", "median", "max", "min"]].describe()
2. 정기적/비정기적인 회원수 집계
# 정기적/비정기적인 회원수 집계
customer_join.groupby("routine_flg").count()["customer_id"]
- 정기적으로 이용하는 회원의 수가 훨씬 많다.
3. 회원 기간의 분포 파악
# 회원 기간의 분포 파악
import matplotlib.pyplot as plt
%matplotlib inline
plt.hist(customer_join["membership_period"])
- 회원 기간이 10개월 이내인 고객이 많다.
- 10개월 이상의 회원 수는 거의 일정하다.
10. 탈퇴 회원과 지속 회원의 차이 파악하기
1. 탈퇴 회원
# 탈퇴 회원
customer_end = customer_join.loc[customer_join["is_deleted"]==1]
customer_end.describe()
2. 지속 회원
# 지속 회원
customer_stay = customer_join.loc[customer_join["is_deleted"]==0]
customer_stay.describe()
- 평균, 중앙값, 최댓값, 최솟값 모두 지속 회원보다 탈퇴 회원이 작다.
- 평균값과 중앙값은 1.5배 정도 차이가 난다.
- 지속 회원은 0.98로 정기적으로 이용하는 것을 알 수 있지만, 탈퇴 회원은 0.45로 절반정도는 랜덤하게 이용하고 있다.
# csv로 출력하기
customer_join.to_csv("customer_join.csv", index=False)
'Python > 데이터분석 공부' 카테고리의 다른 글
[Python] 05장_회원 탈퇴를 예측하는 테크닉 (0) | 2022.03.18 |
---|---|
[Python] 04장_고객의 행동을 예측하는 테크닉 (425) | 2022.03.17 |
[Python] 02장 _ 대리점 데이터를 가공하는 테크닉 (401) | 2022.02.14 |
[Python] 01장 _ 웹에서 주문 수를 분석하는 테크닉 (391) | 2022.02.14 |