파이썬 군집분석 예제 - paisseon gunjibbunseog yeje

K-Means 클러스터링의 파이썬 예제이다. 본 예제에서는 고객 구매 데이터를 분석하여 유의미한 인사이트를 얻어보는 과정을 다룬다. K-Means에 대한 개념적인 설명은 다음 글(클릭)을 참고하면 좋다.

** 연습을 위한 엑셀 데이터와 가이드 노트북 파일은 글 하단에 깃허브 주소에서 확인해주세요. 댓글은 블로그를 운영하는 데 큰 기쁨이 됩니다 🙂

** [2021년 11월 6일 코드 업데이트: Joon님의 제보로 오타 수정하였습니다. 코드 작성하고 블로그에 옮길 때 변수명을 수정했는데 전부 수정되지 않은 실수가 있었습니다. 알려주셔서 감사합니다.

■ K 값이 변하면 클러스터링에 어떤 영향을 미치나?

우선 연습 데이터인 엑셀 파일을 파이썬 주피터 노트북에 pandas 패키지를 이용하여 읽어오도록 한다. 파이썬 기초가 필요하신 분들은 다음 시리즈: 파이썬 첫걸음 을 참고하길 바란다.

# pandas 패키지 임포트
import pandas as pd

# read_excel() 함수를 이용하여 파일 불러오기
data = pd.read_excel('CustomerDataSet.xls')

# 데이터 몇 행만 보기
data.head()

데이터는 5개의 열(Customer ID, ItemsBought, ItemsReturned, ZipCode, Product)로 이뤄져있다. 우리가 알고 싶은 것은 우리의 제품 포트폴리오와 지역의 관계라고 하자. Customer ID는 고객 ID로 각 고객을 구분해주는 유니크한 값이나 본 분석에는 크게 의미가 없으므로 사용하지 않는다. ZipCode와 Product는 군집 분석 결과를 해석할 때 사용한다. 즉,남은 ItemsBought과 ItemsReturned로 클러스터링을 한다.

이제 레코드끼리의 거리를 계산하여 클러스터링을 해야하는데 그 전에 ItemsBought과 ItemsReturned의 측정 단위을 같게하는 작업, 즉 데이터의 정규화(normalization) 작업이 필요하다. 여기서는 MinMaxScaler()를 이용해 정규화를 진행해보기로 한다.

# 필요 패키지 불러오기 (KMeans, matplotlib, preprocessing)
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from sklearn import preprocessing

# 원본 데이터를 복사해서 전처리하기 (원본 데이터를 가지고 바로 전처리하지 않는다)
processed_data = data.copy()

# 데이터 전처리 - 정규화를 위한 작업
scaler = preprocessing.MinMaxScaler()
processed_data[['ItemsBought', 'ItemsReturned']] = scaler.fit_transform(processed_data[['ItemsBought', 'ItemsReturned']])

# 화면(figure) 생성
plt.figure(figsize = (10, 6))
# K 값을 늘려가며 반복 테스트
for i in range(1, 7)
       # 클러스터 생성
       estimator = KMeans(n_clusters = i)
       ids = estimator.fit_predict(processed_data[['ItemsBought', 'ItemsReturned']])
       # 2행 3열을 가진 서브플롯 추가 (인덱스 = i)
        plt.subplot(3, 2, i)
        plt.tight_layout()
        # 서브플롯의 라벨링
        plt.title("K value = {}".format(i))
        plt.xlabel('ItemsBought')
        plt.ylabel('ItemsReturned')
        # 클러스터링 그리기
        plt.scatter(processed_data['ItemsBought'], processed_data['ItemsReturned'], c=ids)  
plt.show()

결과값은 다음과 같다.

파이썬 군집분석 예제 - paisseon gunjibbunseog yeje

해석해보면, K가 3이나 4일때 군집화가 잘 되는 것을 확인할 수 있다. 구분을 하자면 제품을 많이 사고 유지하는 고객군 – 제품을 많이 사나 환불을 조금 하는 고객군 – 제품을 많이 안사고 환불도 많이 하는 고객군 으로 나눌 수 있겠다.

■ 각 군집과 제품 ID의 관계를 살펴보자

이번에는 K를 3으로 잡아 product id를 기준으로 범례를 붙여보자.

# K = 3으로 클러스터링
estimator = KMeans(n_clusters = 3)

# 클러스터링 생성
cluster_ids = estimator.fit_predict(processed_data[['ItemsBought', 'ItemsReturned']])

# create a scatter plot
plt.scatter(processed_data['ItemsBought'], processed_data['ItemsReturned'], c=cluster_ids)

# 제품과 클러스터 id로 데이터에 범례 달기
for index, c_id, bought, returned, zip_code, product in processed_data.itertuples():
    plt.annotate("Clu{}: {}".format(cluster_ids[index], product),(bought, returned))
    
plt.xlabel('ItemsBought')
plt.ylabel('ItemsReturned')
plt.show()

코드를 돌리면 다음과 같은 결과를 얻는다.

파이썬 군집분석 예제 - paisseon gunjibbunseog yeje

그래프를 살펴보면 Clu1인 제품 2435이 많이 안팔릴 뿐만 아니라 환불이 발생하는 것을 알 수 있다. 현재 그래프 상에는 데이터가 정규화되었기 때문에 면밀히 파악하기 어려우니 원래 데이터로 돌아가서 해당 제품을 찾아보자.

# 클러스터 1로 분류된 데이터를 추출해보자
data[ cluster_ids == 1 ]
파이썬 군집분석 예제 - paisseon gunjibbunseog yeje

안좋은 고객으로 할당된 고객 데이터를 보고 이제 문제점을 찾아 개선하면 된다!

■ 각 군집과 지역의 관계를 살펴보자

이번에는 클러스터링을 이용하여 지역마다의 마케팅 활동에 대해 인사이트를 얻어보자. 우편번호이기 때문에 따로 전처리를 할 필요는 없다. 다만, 전처리된 데이터 세트와 원 데이터의 세트의 레코드가 동일한 순서이기 때문에 cluster로는 전처리된 데이터에서 생성된 것을 그대로 사용해도 된다.

# 플로팅하기
plt.scatter(data['ItemsBought'], data['ItemsReturned'], c=cluster_ids)

# 우편번호로 범례달기
for (index, c_id, bought, returned, zip_code, product) in data.itertuples():
    plt.annotate(zip_code,(bought + 0.6, returned + 0.6))
    
plt.xlabel('ItemsBought')
plt.ylabel('ItemsReturned')

plt.show()
파이썬 군집분석 예제 - paisseon gunjibbunseog yeje

결과를 살펴보면, 우편번호가 1과 2인 지역에서 성과가 좋음을 알 수 있다. 1, 2 지역에서 어떤 마케팅을 진행하는지 확인하고 다른 지역에도 적용할 수 있는지 살펴보고, 다른 지역의 성과를 개선할 방안을 찾는다!

파이썬 가이드 자료 공유에 대한 문의가 많아 깃허브를 만들었습니다. 아래 링크로 가이드 파일을 확인해주세요. https://github.com/lucy-the-marketer/k-means-clustering
도움이 되셨다면 댓글 하나 써주시면 감사하겠습니다 🙂