4장 고객의 행동을 예측하는테크닉 10¶
앞장에서 사전 분석한 스포츠 센터 회원의 행동 정보를 이용해서 머신러닝으로 예측을 한다. 회원의 행동은 이용 빈도 등에 따라 경향이 달라진다. 그래서 군집화 기법을 이용하여 회원을 그룹화할 수 있고, 각 그룹의 행동 패턴을 파악하여 예측의 정확도를 높이는 것이 가능해진다.
전제조건¶
스포츠 센터의 데이터를 다룬다. 3장에서 이용 이력을 집계한결과에 고객 데이터를 결합한 customer_join.csv
가 추가됐다. 여기서는 5개의 데이터 중에서 use_log.csv
와 customer_join.csv
만 사용한다.
데이터를 읽고 확인하기¶
import pandas as pd
uselog = pd.read_csv('./use_log.csv')
uselog.isnull().sum()
customer = pd.read_csv('./customer_join.csv')
customer.isnull().sum()
end_date
외에는 결측치가 0인 것을 확인할 수 있다. 탈퇴 여부로 분류하는 것이 아니라 이용 이력을 통해 그룹화한다. 진짜 결측인지, 탈퇴를 하지 않은 것인지 부정확하기 때문이다.
클러스터링으로 회원 그룹화¶
customer_clustering = customer[["mean", "median", "max", "min", "membership_period"]]
customer_clustering.head()
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
#각 속성마다 표준화 필요함. membership_period의 value range가 넓기 때문이다.
sc = StandardScaler()
customer_clustering_sc = sc.fit_transform(customer_clustering)
#K-means를 사용하여 클러스터링 진행
kmeans = KMeans(n_clusters=4, random_state=0) #그룹 수 미리 지정해야함. 여기서는 4
clusters = kmeans.fit(customer_clustering_sc)
customer_clustering["cluster"] = clusters.labels_
print(customer_clustering["cluster"].unique())
customer_clustering.head()
클러스터링 결과를 분석하자¶
customer_clustering.columns = ["월평균값", "월중앙값", "월최댓값", "월최솟값", "회원기간", "cluster"]
customer_clustering.groupby("cluster").count()
#각 그룹마다 평균값 구하기
customer_clustering.groupby("cluster").mean()
클러스터링 결과 가시화¶
from sklearn.decomposition import PCA
X = customer_clustering_sc
pca = PCA(n_components=2)
pca.fit(X)
x_pca = pca.transform(X)
pca_df = pd.DataFrame(x_pca)
pca_df["cluster"] = customer_clustering["cluster"]
import matplotlib.pyplot as plt
%matplotlib inline
for i in customer_clustering["cluster"].unique():
tmp = pca_df.loc[pca_df["cluster"]==i]
plt.scatter(tmp[0], tmp[1])
탈퇴회원의 경향 파악하기¶
먼저 지속회원과 탈퇴회원을 집계한다.
customer_clustering = pd.concat([customer_clustering, customer], axis=1)
customer_clustering.groupby(["cluster","is_deleted"], as_index=False).count()[["cluster", "is_deleted", "customer_id"]] #탈퇴, 비탈퇴
정기적으로 이용하는지, 그렇지 않은지도 찾아본다.
customer_clustering.groupby(["cluster", "routine_flg"], as_index=False).count()[["cluster", "routine_flg", "customer_id"]] #정기적이용/비이용
위 데이터에서 cluster 0과 3 그룹에서 정기적 회원(routine_flg==1)이 많이 있다는 것을 알 수 있다.
다음 달의 이용 횟수 예측을 위해 데이터를 준비하기¶
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()
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()
predict_data = predict_data.dropna()
predict_data = predict_data.reset_index(drop=True)
predict_data.head()
predict_data = pd.merge(predict_data, customer[["customer_id", "start_date"]], on="customer_id", how="left")
predict_data.head()
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()
# 달 수로 기간 표시
다음달 이용 횟수 예측하는 모델 구축¶
scikit-learn의 LinearRegression을 사용하여 앞선 데이터의 추세를 통해 다음달 이용 횟수를 예측한다.
predict_data = predict_data.loc[predict_data["start_date"]>=pd.to_datetime("20180401")]
import sklearn
from sklearn import linear_model
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)
print(model.score(X_train, y_train))
print(model.score(X_test, y_test))
위 선형회귀모델의 정확도는 약 60%이다.
모델에 기여하고 있는 변수들이 무엇인지 확인하자.
모델에 기여하는 변수 확인¶
계수의 기여도를 확인했을 때 count_0이 가장 크고 점차 기여도가 작아진다는 것을 확인함.
count_0이 가장 최근 1개월전 데이터이기 때문에 기여도가 높다는 것을 짐작할 수 있음.
coef = pd.DataFrame({"feature_names":X.columns, "coefficient":model.coef_})
coef
다음 달 이용 횟수 예측¶
만약 yang 회원이 6개월 동안 달마다 7, 8, 6, 4, 4, 3번의 방문이 이력이 있고, park 회원이 6, 4, 3, 3, 2, 2번 방문했을 때 다음 달 방문 횟수를 예측해보자.
yang = [3,4,4,6,8,7, 8] # 순서 : 1개월 전부터 6개월전까지
park = [2,2,3,3,4,6, 8] # 마지막 값은 재적 기간 8개월이다.
x_pred = [yang, park]
model.predict(x_pred)
결과를 보면 yang회원은 다음 달에 3.9회, park회원은 1.9회 방문으로 예측한다.
'Machine Learning > Statistics' 카테고리의 다른 글
파이썬 데이터분석 실무 테크닉 100 - 6장 (1) | 2021.07.01 |
---|---|
파이썬 데이터분석 실무 테크닉 100 - 5장 (1) | 2021.03.03 |
파이썬 데이터 분석 실무 테크닉 100 - 3장 (0) | 2020.12.17 |
파이썬 데이터 분석 실무 테크닉 100 - 2장 (0) | 2020.12.07 |
파이썬 데이터분석 실무 테크닉 100 - 1장 (0) | 2020.11.30 |