파이썬 데이터 분석 실무 테크닉 100 -머신러닝(2)

2부 머신러닝

4장 고객의 행동을 예측하는 테크닉 10

분석 목표 : 앞에서 사전 분석한 스포츠 센터 회원의 행동 정보를 이용해서 머신러닝으로 예측한다.

 

전제조건

No. 파일 이름 개요
1 use_log.csv 스포츠 센터의 이용 이력 데이터. 기간은 2018년 4월 ~ 2019년 3월
2 customer_master.csv 2019년 3월 말의 회원 데이터
3 class_master.csv 회원 구분 데이터(종일, 주간, 야간)
4 campaign_master.csv 캠페인 구분 데이터(입회비 무료 등)
5 customer_join.csv 3장에서 작성한 이용 이력을 포함한 고객 데이터

 

테크닉031 : 데이터 읽기

 

데이터를 읽으면서 결측치 상황도 확인! end_date 이외에는 결측치가 0인 것을 확인 가능

 


테크닉032 : 클러스터링으로 회원을 그룹화하자

customer 데이터를 사용해서 회원 그룹화를 진행한다. 클러스터링에 이용하는 변수는 고객의 한 달 이용 이력 데이터인 mean, median, max, min, membership_period로 진행

먼저, 필요한 변수를 추출하자.

customer_clustering = customer[['mean', 'median', 'max', 'min', 'membership_period']]
customer_clustering.head()

 

필요한 변수를 추출했고 이제 클러스터링을 진행한다. 사용할 클러스터링 방법은 가장 전통적인 클러스터링 방법으로 변수 간의 거리를 기반으로 그룹화를 진행하는 K-means이다.

from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
customer_clustering_sc = sc.fit_transform(customer_clustering)

kmeans = KMeans(n_clusters = 4, random_state=0)
clusters = kmeans.fit(customer_clustering_sc)
customer_clustering['cluster'] = clusters.labels_
print(customer_clustering['cluster'].unique())
customer_clustering.head()

 

1행에서 K-means를 임포트하고, 2행에서 표준화를 하기 위해 scikit-learn 라이브러리를 임포트한다. 3행과 4행에서 표준화를 실행하고 customer_clustring_sc에 저장한다. 공백을 사이에 두고 클러스터 수를 4로 지정하고 K-means 모델을 정의한다.

위의 결과를 보면 0 ~ 3까지 4개의 그룹이 작성됐고, 각 고객 데이터에 그룹이 할당된 것을 확인할 수 있다.


테크닉033 : 클러스터링 결과 분석

일단 데이터의 수를 파악해둔다. 열의 이름이 혼란스럽게 되어있기 때문에 칼럼 이름을 변경하자.

customer_clustering.columns = ['월평균값', '월중앙값', '월최댓값', '월최솟값', '회원기간', 'cluster']
customer_clustering.groupby('cluster').count()

1행에서 칼럼의 이름을 변경하고 2행에서 클러스터마다 집계한다. count 함수를 이용해 데이터의 개수를 계산하는데, 결과를 보면 그룹 3이 가장 많고, 다음으로 1, 0, 2 순서이다.

그룹의 특징을 파악하기 위해 그룹마다 평균값을 계산한다.

 

결과를 보면 그룹 0은 회원 기간은 짧지만, 이용률이 높은 회원이라는 것을 알 수 있다. 또 그룹 2는 회원 기간도 짧고 이용률이 낮은 회원들이며, 3과 1은 회원 기간이 길다. 


테크닉034 : 클러스터링 결과를 가시화하자

여러 변수를 어떻게 가시화하면 좋을지를 알아야 한다. 클러스터링에 사용한 변수는 5개이다. 5개의 변수를 2차원으로 그리기 위해 차원을 축소한다. 차원 축소란 비지도학습의 일종으로, 정보를 되도록 잃지 않게 하면서 새로운 축을 만드는 것이다. 이렇게 하면 5개의 변수를 2개의 변수로 표현할 수 있고 그래프로도 그릴 수 있다. 여기서는 차원 축소의 대표적인 방법으로 주성분 분석(PCA)를 사용한다.

1행에서는 주성분 분석 라이브러리를 임포트하고 3행에서는 모델을 생성하고 4행과 5행에서는 주성분 분석을 실행한다. 2차원으로 축소한 데이터를 pca_df에 저장하고 테크닉 32에서 작성한 클러스터링 결과도 저장한다.

아래쪽 코드에서는 matplotlib을 이용해서 가시화를 진행한다. for문에서는 그룹마다 여러 가지 색깔로 바꿔서 그리고 있다.


테크닉035 : 클러스터링 결과를 바탕으로 탈퇴 회원의 경향 파악하자

클러스터링으로 4개의 그룹으로 분할했는데, 이 그룹에 지속 회원과 탈퇴 회원은 얼마나 있을까? 여기서는 지속 회원과 탈퇴 회원을 집계하자. 

customer_clustering = pd.concat([customer_clustering, customer], axis = 1)
customer_clustering.groupby(['cluster', 'is_deleted'], as_index = False).count()[['cluster', 'is_deleted', 'customer_id']]

1행에서 customer_clustering에 customer를 결합한다. customer_clustering과 customer는 index로 연결되어 있기 때문에 concat으로 결합이 가능하다.

결과를 보면, 그룹 2는 탈퇴회원만 있으며, 그룹 3은 골고루 포함되어 있다. 그룹 0과 1은 지속 회원이 많다.

 

정기적 / 비정기적 이용 여부를 살펴보자.

결과를 보면, 지속 회원이 많은 그룹 1, 3에는 정기적으로 이용하는 회원이 많다는 것을 알 수 있다.

클러스터링을 통한 그룹화를 실시함으로써 고객의 특징을 파악할 수 있다. 또 분석의 목적에 따라 다양한 방식의 분석을 진행하는 것도 좋다. 

이제부터는 이용 횟수 예측 모델을 구축하자.


테크닉036 : 다음 달의 이용 횟수 예측을 위해 데이터를 준비하자.

고객의 과거 행동 데이터로부터 다음 달의 이용 횟수를 예측하는 경우에는 지도학습의 회귀 분석을 이용한다. 지도학습은 미리 정답을 알고 있는 숫자 데이터를 이용해서 예측한다. 여기서는 과거 6개월의 이용 데이터를 사용해 다음 달의 이용 횟수를 예측해보자.

 

2018년 5월 ~ 10월까지 6개월의 이용 데이터와 2018년 11월의 이용 횟수를 정답 데이터로 학습에 사용한다.

먼저 uselog 데이터를 이용해 연월, 회원마다 집계를 해보자.

uselog['usedate'] = pd.to_datetime(uselog['usedate'])
uselog['연월'] = uselog['usedate'].dt.strftime('%Y%m')
uselog_months = uselog.groupby(['연월', 'customer_id'], as_index = False).count()
uselog_months.rename(columns = {'log_id' : 'count'}, inplace = True)
del uselog_months['usedate']
uselog_months.head()

strftime으로 연월 칼럼을 작성하고 연월, 고객별로 log_id를 집계한다. 

year_months = list(uselog_months['연월'].unique())
predict_data = pd.DataFrame()
for i in range(6, len(year_months)):
    tmp = uselog_months.loc[uselog_months['연월'] == year_months[i]]
    tmp.rename(columns = {'count' : 'count_pred'}, inplace = True)
    for j in range(1, 7):
        tmp_before = uselog_months.loc[uselog_months['연월'] == year_months[i - j]]
        del tmp_before['연월']
        tmp_before.rename(columns = {'count' : 'count_{}'.format(j-1)}, inplace = True)
        tmp = pd.merge(tmp, tmp_before, on = 'customer_id', how = 'left')
    predict_data = pd.concat([predict_data, tmp], ignore_index = True)
predict_data.head()

1행에서 연월 데이터를 리스트에 저장한다. 그리고 for문에서 2018년 10월부터 2019년 3월까지 반복하면서 과거 6개월분의 이용 데이터를 취득해서 추가한다.

결과를 보면 count_pred 칼럼이 예측하고 싶은 달의 데이터이고, count_0이 1개월 전으로 과거 6개월의 데이터를 나열한다. count_4와 count_5에 결측치가 포함된 데이터도 있지만, 이것은 아직 가입 기간이 짧아서 데이터가 존재하지 않는 경우이다.

머신러닝을 진행하는 경우 결측치를 처리해야 하므로 dropna로 결측치를 포함하는 데이터를 삭제한 후 index를 초기화하자.

이렇게 되면, 대상 회원은 6개월 이상 재적 중인 회원이 된다.


테크닉037 : 특징이 되는 변수를 추가하자

특징이 되는 데이터를 추가해보자. 여기서는 회원 기간을 추가할 것이다. 회원 기간은 시계열 변화를 볼 수 있기 때문에 이번 데이터처럼 기본 데이터가 시계열 데이터인 경우 유효할 가능성이 있기 때문이다.

결과를 보면 start_date 칼럼이 추가된 것을 확인할 수 있다.

다음으로, 연월과 start_date의 차이를 이용해 회원 기간을 월 단위로 작성해 보자.

predict_data['now_date'] = pd.to_datetime(predict_data['연월'], format = '%Y%m')
predict_data['start_date'] = pd.to_datetime(predict_data['start_date'])
from dateutil.relativedelta import relativedelta
predict_data['period'] = None
for i in range(len(predict_data)):
    delta = relativedelta(predict_data['now_date'][i], predict_data['start_date'][i])
    predict_data['period'][i] = delta.years * 12 + delta.months
predict_data.head()

1행과 2행에서 문자열 데이터인 연월 및 start_date 칼럼을 datetime형으로 변환한다. 그 다음은 relativedelta를 사용해 회원 기간을 계산한다.


테크닉038 : 다음 달 이용 횟수를 예측하는 모델을 구축하자

예측 모델을 구축한다. 여기서는 2018년 4월 이후에 새로 가입한 회원만 이용해 모델을 작성한다. 사용할 회귀 모델은 scikit-learn의 LinearRegression이다. 선형 회귀 모델이라고 부르며, 매우 간단한 식으로 나타낼 수 있다.

predict_data = predict_data.loc[predict_data['start_date'] >= pd.to_datetime('20180401')]
from sklearn import linear_model
import sklearn.model_selection
model = linear_model.LinearRegression()
X = predict_data[['count_0', 'count_1', 'count_2', 'count_3', 'count_4', 'count_5', 'period']]
y = predict_data['count_pred']
X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(X, y)
model.fit(X_train, y_train)

모델을 구축했다. 학습용 데이터와 평가용 데이터로 분할을 했는데 분할 비율은 지정할 수도 있지만, 지정하지 않을 경우 학습용 데이터 75%, 평가용 데이터 25%로 분할이 된다.

이제 정확도를 검증해보자.

모두 60% 정도의 정확도를 나타내고 있다.

이렇게 회귀 예측 모델이 구축되었다.


테크닉039 : 모델에 기여하는 변수를 확인하자

설명 변수마다 기여하는 계수를 출력하자.

★ 결과를 확인하면 count_0이 가장 크고, 과거로 거슬러 올라갈수록 기여도가 작아지는 경향이 있다. 다시 말해 이전 달의 이용 횟수가 다음 달의 이용 횟수에 영향을 미치고 있다는 것이다.

 


테크닉040 : 다음 달의 이용 횟수를 예측하자

임의의 회원 두 명의 이용 데이터를 작성해보자.

x1 = [3, 4, 4, 6, 8, 7, 8]
x2 = [2, 2, 3, 3, 4, 6, 8]
x_pred = [x1, x2]

각각 1개월마다 방문한 값이다. 이 값을 토대로 두 회원의 다을 달 방문 횟수를 예측해 보자.

첫 번째는 3.7회, 두 번째는 1.9회로 예측되었다.

실제로 구축한 모델을 시스템으로 만들고 이번 달이 끝나는 시점에 과거의 데이터로부터 다음 달의 이용 횟수를 한 번에 예측할 수 있다. 이렇게 자동으로 예측하면 다음 달에 다양한 정책을 실시하는 데 활용할 수 있다.

 

TAGS.

Comments