[python] 스포츠 센터 데이터 분석 ①
- 스포츠 센터에는 센터를 언제든 사용할 수 있는 종일 회원, 낮에만 사용할 수 있는 주간 회원, 밤에만 사용할 수 있는 야간 회원으로 3종류의 회원 구분이 존재
- 일반적으로 입회비가 존재하지만, 비정기적으로 입회비 반액 할인이나 입회비 무료 행사를 해서 신규회원을 늘리고 있음
- 월말까지 신청하면 그 다음 달 말에 탈퇴 처리
취급할 데이터 종류
① use_log.csv
- 센터 이용 이력, 회원이 센터를 이용하면 이용일이 시스템에 자동 입력됨
- 2018년 4월 ~ 2019년 3월까지 1년의 데이터
② customer_master.csv
- 2019년 3월 말 시점의 회원 데이터, 이전에 탈퇴한 회원도 포함되어 있음
③ class_master.csv
- 회원 구분 데이터(종일, 주간, 야간)
④campaign_master.csv
- 가입 시 행사 종류 데이터(입회비 유무 등)
고객 데이터 가공하기
customer 데이터와 class_master, campaign_master 결합한다.
# join 하기
customer_join = pd.merge(customer, class_master, on = 'class', how = 'left')
customer_join = pd.merge(customer_join, campaign_master, on = 'campaign_id', how = 'left')
customer_join.head()
print(len(customer))
print(len(customer_join))
-----------------------------------------------------------
4192
4192
데이터 개수가 조인 전후로 변화가 없는 것을 알 수 있다.
조인할 때 키가 없거나 조인이 잘못되면 자동으로 결측치가 들어가므로 조인 후에는 결측치를 확인해야 한다.
# 결측치 확인
customer_join.isnull().sum()
고객 데이터 집계
캠페인 구분과 성별, 탈퇴 했는지를 집계해서 숫자를 파악해보자.
customer_join.groupby("class_name").count()["customer_id"]
------------------------------------------------------------
class_name
0_종일 2045
1_주간 1019
2_야간 1128
회원 클래스는 종일반이 거의 절반을 차지하고, 야간, 주간 순으로 많다.
customer_join.groupby("campaign_name").count()["customer_id"]
---------------------------------------------------------------
campaign_name
0_입회비반액할인 650
1_입회비무료 492
2_일반 3050
Name: customer_id, dtype: int64
캠페인은 일반 입회가 가장 많고, 입회 캠페인에 의한 가입이 약 20% 이다.
customer_join.groupby("gender").count()["customer_id"]
-----------------------------------------------------------
gender
F 1983
M 2209
Name: customer_id, dtype: int64
남녀 비율은 남자가 여자보다 약간 더 많다.
customer_join.groupby("is_deleted").count()["customer_id"]
-------------------------------------------------------------
is_deleted
0 2842
1 1350
Name: customer_id, dtype: int64
2019년 3월 현재 가입된 회원은 2842명, 탈퇴한 유저는 1350명이다.
start_date가 2018년 4월 1일 이후부터 2019년 3월 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")]
print(len(customer_start))
-------------------------------------------------------------------
1361
이 기간의 가입인원이 1361명인 것을 알 수 있다.
최신 고객 데이터 집계
가장 최근 월인 2019년 3월의 고객 데이터를 파악해보면 현재 고객 데이터에는 이미 탈회한 고객도 포함되어 있기 때문에 월별 집계와 차이가 있다. 가장 최근 월의 고객 데이터를 집계해서 현재 고객의 전체 모습을 파악해보자.
# 가장 최근 월의 고객 추출
customer_join["end_date"] = pd.to_datetime(customer_join["end_date"])
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()
-------------------------------------------------------------------------
2953
array([ 'NaT', '2019-03-31T00:00:00.000000000'],
dtype='datetime64[ns]')
출력 결과, 데이터는 2,953건이고, end_date의 유니크는 NaT로 datetime의 결측치라는 뜻으로, 여기서는 탈퇴하지 않은 고객을 나타낸다.
회원 구분, 캠페인 구분, 성별로 전체를 파악해보면
customer_newer.groupby("class_name").count()["customer_id"]
---------------------------------------------------------------
class_name
0_종일 1444
1_주간 696
2_야간 813
Name: customer_id, dtype: int64
customer_newer.groupby("campaign_name").count()["customer_id"]
----------------------------------------------------------------
campaign_name
0_입회비반액할인 311
1_입회비무료 242
2_일반 2400
Name: customer_id, dtype: int64
customer_newer.groupby("gender").count()["customer_id"]
------------------------------------------------------------
gender
F 1400
M 1553
Name: customer_id, dtype: int64
출력 결과를 보면, 회원 구분 및 성별은 전체를 집계했을 때와 비율이 크게 다르지 않다.
이것은 특정 회원 구분이나 성별이 탈퇴한 것이 아니라고 볼 수 있다.
캠페인 구분은 약간 차이가 있는데, 전체를 집계했을 때는 일반으로 입회한 유저가 72%였는데 비해, 일반 입회 회원 비율이 81%이다. 입회 캠페인은 회원 비율 변화에 영향을 미친다고 추측할 수 있다.