
이용 이력 데이터(uselog) 추가해서 고개 탐색 --> 고객별 월 이용 횟수 집계
: 이용 이력 데이터는 시간적인 요소를 분석 가능
한 달 이용 횟수의 변화와 회원이 스포츠 센터를 정기적으로 이용하는지, 비정기적으로 이용하는지와 같은 것 파악가능
[월 이용 횟수의 평균값, 중앙값, 최솟값을 고객 데이터에 추가]
uselog_customer = uselog_months.groupby("customer_id").agg(["mean", "median", "max", "min" ])["count"]
# 한번에 통계 함수를 쓰는 agg.함수!
uselog_customer = uselog_customer.reset_index(drop=False)
uselog_customer.head()
[이용이력 데이터]
customer_id mean(평균) median max min
| AS002855 | 4.500000 | 5.0 | 7 | 2 |
| AS008805 | 4.000000 | 4.0 | 8 | 1 |
| AS009013 | 2.000000 | 2.0 | 2 | 2 |
| AS009373 | 5.083333 | 5.0 | 7 | 3 |
| AS015233 | 7.545455 | 7.0 | 11 | 4 |
[이용이력 데이터로부터 정기 이력 플래그 작성]
정기적으로 센터를 이용하는 고객인가? --> (정의하기) : 매주 같은 요일에 왔는가?
월마다 요일마다 몇번 왔는지 집계하고 최댓값이 4이상인 요일이 하나라도 있는 회원은 플래그를 1로 처리한다.
먼저, 고객마다 월/요일별로 집계하기
# 요일을 숫자로 변환. 0에서부터 6까지의 숫자가 각각 월요일부터 일요일에 해당.
uselog["weekday"] = uselog["usedate"].dt.weekday
# 고객, 연월, 요일별로 log_id를 카운트.
uselog_weekday = uselog.groupby(["customer_id","연월","weekday"],
as_index=False).count()[["customer_id","연월", "weekday","log_id"]]
uselog_weekday.rename(columns={"log_id":"count"}, inplace=True)
uselog_weekday.head()
customer_id 연월 weekday count
| AS002855 | 201804 | 5 | 4 |
| AS002855 | 201805 | 2 | 1 |
| AS002855 | 201805 | 5 | 4 |
| AS002855 | 201806 | 5 | 5 |
| AS002855 | 201807 | 1 | 1 |
출력된 결과를 보면, 회원 AS002855는 2018년 4월, weekday 5(토요일)에 4번, 2018년 5월에도 weekday 5(토요일)에 4번 스포츠 센터에 왔으므로 매주 토요일은 체육관에 오는 날로 생각하는 것 같습니다. 그럼 고객별로 최댓값을 계산하고, 그 최댓값이 4이상인 경우에 플래그를 지정해봅시다.
uselog_weekday = uselog_weekday.groupby("customer_id",as_index=False).max()[["customer_id", "count"]]
uselog_weekday["routine_flg"] = 0
uselog_weekday["routine_flg"] = uselog_weekday["routine_flg"].where(uselog_weekday["count"]<4, 1)
uselog_weekday.head()
--> .where(조건, 1) : 조건을 충족하지 않으면 1의 값을 넣어라.
customer_id count routine_flg
0 AS002855 5 1
1 AS008805 4 1
2 AS009013 2 0
3 AS009373 5 1
4 AS015233 5 1
1행에서 고객 단위로 집계하고 최댓값을 구한다. (특정 월, 특정 요일에 가장 많이 이용한 횟수)
이 횟수가 4 또는 5인 사람은 적어도 어떤 달의 매주 특정 요일에 정기적으로 방문한 고객일 것이다.
가령, A고객이 (4월달에 목요일에 ) count=5번 왔다면 이 고객은 목요일 내내 왔다는 뜻
2행에서는 routine_flg라는 열을 만들고 우선 모든 열의 값에 0을 입력
3행에서는 max값이 4이상인 경우에는 1을 대입합니다. (위의 표에서는 4 or 5)
최종 결과를 보면 count가 4이상인 고객은 플래그에 1이 들어 있는 것을 알 수 있다.
이렇게 플래그 작성이 완료!
다음으로, 고객 데이터와 결합해서 최대 이력을 포함한 고객 데이터를 수정하기!!
[고객 데이터와 이용 이력 데이터의 결합]
pd. merge 사용하기!
uselog_customer, uselog_weekday를 customer_join과 결합하기
customer_join = pd.merge(customer_join, uselog_customer, on="customer_id", how="left")
customer_join = pd.merge(customer_join, uselog_weekday[["customer_id", "routine_flg"]], on="customer_id", how="left")
customer_join.head()
기준은(조인키), on="customer_id" 결합방법은 how= left
[회원 기간을 계산해서 열로 추가하기]
"회원 기간은 단순하게 start_date와 end_date의 차이입니다. 다만, 2019년 3월까지 탈퇴하지 않은 회원은 end_date에 결측치가 들어있기 때문에 그 차이를 계산할 수 없습니다. 그래서 탈퇴하지 않은 회원은 2019년 4월 30일로 채워서 회원 기간을 계산합니다."
# 날짜 비교 함수 relativedelta(start_date와 end_date 차이)를 사용하기 위해 라이브러리를 임포트
from dateutil.relativedelta import relativedelta
# 날짜 계산용 열을 end_date를 초기값으로 하여 추가, 그냥 end_date를 calc_date로 복제
customer_join["calc_date"] = customer_join["end_date"]
# 결측치에 2019년 4월 30일을 대입 : .fillna함수!!
customer_join["calc_date"] = customer_join["calc_date"].fillna(pd.to_datetime("20190430"))
# 날짜 비교 함수 relativedelta를 사용.
# cal_date와 start_date의 차이를 계산 후에 membership_period에 회원 기간을 월 단위 추가
customer_join["membership_period"] = 0
# 아,, for문 다시 공부해야겠다. i!
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()
결과!
customer_id name class gender start_date end_date campaign_id is_deleted class_name price campaign_name mean median max min routine_flg calc_date membership_period
0 OA832399 XXXX C01 F 2015-05-01 NaT CA1 0 0_종일 10500 2_일반 4.833333 5.0 8 2 1 2019-04-30 47
1 PL270116 XXXXX C01 M 2015-05-01 NaT CA1 0 0_종일 10500 2_일반 5.083333 5.0 7 3 1 2019-04-30 47
2 OA974876 XXXXX C01 M 2015-05-01 NaT CA1 0 0_종일 10500 2_일반 4.583333 5.0 6 3 1 2019-04-30 47
3 HD024127 XXXXX C01 F 2015-05-01 NaT CA1 0 0_종일 10500 2_일반 4.833333 4.5 7 2 1 2019-04-30 47
4 HD661448 XXXXX C03 F 2015-05-01 NaT CA1 0 2_야간 6000 2_일반 3.916667 4.0 6 1 1 2019-04-30 47