카테고리 없음

#2 고객 데이터 분석하기 -2 (python)

데이터분석가 소히의 개발일지 2021. 7. 24. 17:11

이용 이력 데이터(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