오늘은 k-means clustering 에 대해서 설명해드릴까 합니다. Show 이 알고리즘은 너무너무너무너무 간단합니다. 생각을 하면서 잘 따라오세요 ~ 먼저 우리는 임의의 N차원 벡터를 N차원 공간의 한 점으로 나타낼 수 가 있습니다. 예를들면 3차원 벡터는 3차원 공간상의 점 하나입니다.. 우리는 위 그림을 보고 아 대충 보기에 3개의 그룹으로 나눌 수 있겠구나 ~~ 생각할 수 있어요 그런데 컴퓨터는 그렇게 생각할 수 있을까요 ?.. 컴퓨터는 그렇게 생각할 수가 없습니다 그래서 우리는 실제 라벨 없이, 주어진 데이터만으로 컴퓨터가 그룹을 찾게 만들어줘야해요 ... 이 방법 중 하나가 우리가 공부할 k-means clustering이에요. 근데 생각해보니까 트루라벨이 없네..? 우린 주어진 데이터만으로 군집화를 진행해야합니다. 따라서.. clustering 은 비교사학습(Unsupervised Learning)이라고 볼 수 있어요. 어쨌건.. 어떻게 이제 군집화를 시킬것인가..? 우리는 간단하게 유클리디안 거리(Euclidian Distance)를 이용할겁니다. 거리에는 유클리디안뿐만 아니라 마할라노비스(Mahalanobis) 거리 등이 있습니다. 유클리디안 거리는 간단하게 우리가 중학교때인가 배운 수식.. 두 점사이의 거리를 계산하는 공식.. 을 이용하면돼요 공식은 아래와 같습니다. 이 공식을 통해서 우리는 한점 v와 다른 한 점 v_1의 거리를 구할 수 있어요 .. 조금 더 설명해드리자면 d는 점의 차원을 의미하고, k는 차원에 속한 요소들의 인덱스를 의미해요.. 자 그럼 우리는 이제 랜덤으로 k개의 점을 뿌려줍니다. 여기서 k는 우리가 몇개로 군집화 할거냐... 하는 걸 정해주는 부분입니다 ^^ 그러니까 이 알고리즘의 이름을 해석하자면 k개의 평균으로 군집화 !이런게 되겠죠 우리는 여기서는 설명의 편의를 위해 2개로 합시다.. 그런 다음에 2개의 점에대해서 현재 뿌려진 모든 점들의 거리를 구해요 그리고 두 점 중 가까운.. (만약 세점이라면 가장 가까운) 그룹에 속한다고 표시해둡니다. 그러면 우리는 원래 가지고 있던 점들이 두 개의 점에 의해서 두개의 그룹으로 나뉘는 것을 알 수 있어요 그러면 우리는 각 그룹에 대한 평균 벡터를 각각 계산할 수 있어요 . 자 여기가 중요합니다. 그럼 !! 이제 새로운 두개의 점이 생기죠 ~?~~ 그렇다면 다시 이 새로 생긴 두 평균 벡터에 의해서 모든 점과의 거리를 계산할 수 있습니다. 그리고 다시 거리를 비교하여 점들을 두개의 군집으로 나눌 수 있겠죠 .. 그런담에 .. 다시 ~ 평균을 구하고~ 다시 거리를 구하고 군집으로나누고... 이렇게 반복해주면서 어떠한 임계값(threshold)만큼 평균이 이동하지않거나 원하는 횟수만큼 반복이 완료되었을때의 클러스터들을 반환하는것이 k-means clustering 입니다. 끗. 너무 간만에써서 귀차니즘이..장난아니네요 ㅋㅋ 안녕하세요, Everly입니다. 정말 오랫만에 '파이썬 분석 실무 테크닉' 공부한 부분을 리뷰하는데요! (3달 만이군요..) 앞으로는 좀 더 자주 업로드해보도록 하겠습니다 :) 오늘은 지난 포스팅에서 다뤘던 스포츠 센터(편의상 헬스장) 데이터를 바탕으로, 이 헬스장을 사용하는 고객이 어떤 유형이 있고, 고객의 행동을 에측하는 데이터 분석을 공부해봅니다. 이번 포스팅에서는 클러스터링(clustering)을 통해 고객의 유형을 나눠 보고, 바로 다음 포스팅에서는 고객의 과거 데이터를 기반으로 예측하는 머신러닝 모델을 만들어 봅니다. [고객의 소리] 지난번 분석으로 어느 정도 경향을 파악할 수 있었습니다. 아직 전체적인 경향밖에 파악하지 못해서, 이번에는 좀 더 구체적인 분석을 부탁드리려고 합니다. 지난 포스팅에서 사용했던 데이터를 그대로 사용합니다.
지난번 [파이썬 데이터 분석 #3] 포스팅을 통해, 헬스장을 사용하는 고객들의 특징에 대해 몇 가지 인사이트를 도출해 봤었죠. 고객 1인당 월평균 5회 정도를 사용하고 있었고, 지속적으로 이용하는 사람(flag 변수)도 전체의 81%나 있었습니다. 또한 회원 기간의 분포를 살펴보니 10개월을 기점으로 회원 기간 분포가 뚝 끊기는 것을 볼 수 있어, '마의 10개월'을 발견하기도 했습니다. 이러한 인사이트는 전체 고객을 대상으로 본 것이었습니다. 하지만 이번에는 좀 더 구체적으로, 어떤 유형의 고객들이 있는지가 궁금합니다. 자주 이용하는 고객 그룹과, 아닌 그룹이 있지 않을까요? 이를 나누기 위해선 어떤 변수를 사용해서 나눌 수 있을까요? 좀 더 자세히 알아보겠습니다. Tech 31. 데이터 불러오기
use_log 데이터는 'ul', customer_join 데이터는 'c'로 불러옵니다. 결측치를 확인해 보니 ul은 없고, c의 경우 end_date(탈퇴시점)에 2842개의 결측치가 있네요. 아직 탈퇴를 하지 않은 회원은 이렇게 end_date에 결측값이 있습니다. 딱히 이상 없는 데이터입니다. Tech 32. 클러스터링을 활용한 회원 그룹화※ 클러스터링(Clustering) 이란? - 군집 분석이라고도 하며, 정답 데이터가 없기 때문에 '비지도학습' 의 일종입니다. 주로 고객을 그룹화하는 등 공통된 특성을 가진 군집들로 묶는 알고리즘을 의미합니다. 가장 유명한 것은 K-means 클러스터링인데, 이번 장에서도 이를 활용합니다. 클러스터링은 'c' 데이터로 진행합니다. 회원의 이용이력에 따라 고객을 유형화해볼 수 있을 것 같네요. 그래서 회원의 이용이력과 관련한 변수를 사용합니다.
바로 mean, median, max, min, mem_period인데요. 각각 고객별 한달 평균, 중위수, 최대, 최소 이용횟수와 회원 기간(단위: month)입니다. c 데이터는 유일한 고객별 이용이력을 담고 있습니다. 이를테면 c 데이터의 0번 행의 고객은, 한 달 평균 4.83회를 사용하고, 한달 중위수 5회, 한달에 최소 2회~최대 8회까지 사용하네요. 어쨌든 이러한 컬럼들만 따로 떼어 변수 'cc'를 만들어줍니다. 이제 k-means 클러스터링을 실시합니다. 단, 조건이 있습니다. <조건> 2번 조건을 토대로 5개 변수의 값을 평균 0, 표준편차 1을 따르는 정규분포를 따르도록 바꿔줍니다. 이를 '표준화'라고 합니다. 이런 과정을 거치지 않고 그냥 클러스터링을 해버리면 값이 너무 큰 'mem_period' 변수가 가장 중요한 변수로 인식될 수 있고 올바른 클러스터링이 불가능하기 때문에 표준화를 해줍니다.
표준화를 통해 위의 5가지 변수가 이와 같이 바뀌었습니다. 모든 변수의 값이 비슷해졌죠? 이 데이터는 'cc_scaled' 입니다.
위의 코드를 통해 군집이 4개(n_clusters)인 k-means 클러스터링을 수행할 수 있습니다. 어떤 클러스터가 만들어졌는지는 labels_ 메서드를 통해 알 수 있는데요, 더 쉽게 알아보기 위해 초반에 만들어 둔 'cc' 데이터(변수 5개만 있는 데이터프레임)에 'clsuter'라는 새로운 컬럼을 만들어 클러스터 번호를 넣어줍니다. 이렇게 'cluster' 컬럼이 새로 생겼음을 알 수 있죠. unique 메서드를 활용하면 cluster가 0, 1, 2, 3 이렇게 4개가 생성되었음을 알 수 있습니다. 이제, k-means 알고리즘이 자동으로 군집화해준 이 클러스터가 어떤 특징을 띠고 있는지를 분석해봅시다. Tech 33. 클러스터링 결과 분석
groupby를 통해 다양한 통계량을 알아봅니다. count() 메서드를 통해선 각 클러스터(그룹)별로 개수가 몇개인지를 셉니다. 그룹 0이 1334개로 가장 많이 들어있고, 그룹3 > 그룹2 > 그룹 1 순이네요. 다음은 mean() 메서드를 통해 각 클러스터별 평균값을 알아봅니다.
이렇게 그룹의 특징을 파악해보면, 그룹별로 다른 캠페인이나 프로모션을 사용할 수 있겠죠? 여기서는 사용한 변수가 단 5개이지만, 더 특징적인 변수를 포함시킨다면 보다 복잡한 클러스터링도 가능합니다. 이제는 이 클러스터링 결과를 눈으로 보기 쉽도록 그래프로 나타내봅시다. Tech 34. 클러스터링 결과 시각화(차원 축소 활용)하지만 문제가 생깁니다. 보통 우리가 그리는 그래프는 2차원입니다. 그런데 여기서 사용한 변수는 5개로, 5차원 그래프는 그리기도 힘들뿐더러 이해하기도 쉽지 않습니다. 여기서 우리는 5개의 변수를 2개의 변수로 줄이는 작업을 통해, 2차원 그래프로 나타내봅니다. 이것이 바로 '차원 축소'인데요, 대표적인 차원 축소 방법인 PCA(Principal Component Analysis)를 수행합니다. ※ 차원 축소란? - 정보를 되도록 잃지 않게 하면서 새로운 축을 만드는 기법. 여기서 사용하는 차원축소 기법 중 하나인 PCA는 주성분분석이라고도 하며, 5개의 변수를 2개의 주성분(정보를 가장 많이 담고 있는) 으로 만듭니다.
앞서 만들었던 표준화 변수 'cc_scaled'를 copy한 새로운 변수 'X'를 만들어 PCA를 적용했습니다. 결과가 array 형태라 보기가 불편하네요. 보기 쉽게 데이터프레임으로 바꿔봅시다. 클러스터 넘버도 포함해서요!
이와 같이 5개였던 변수가 2개의 주성분으로 바뀌었습니다. 어차피 컬럼만 줄어든 것뿐, 행의 수는 똑같으니까 cc 데이터의 'cluster' 컬럼으로 그대로 가져와도 문제없습니다. 이제는 2개의 주성분 변수를 2차원 그래프로 나타내봅시다. 저는 교재 외의 방법으로 seaborn, matplotlib 라이브러리 2가지를 사용해 만들어 보았습니다. seaborn 라이브러리 사용 matplotlib 라이브러리 사용코드는 seaborn이 더 간단해서 저는 보통 seaborn을 애용하는 편입니다. scatterplot 메서드를 사용해 변수 2개를 넣어주고, 'hue' 옵션을 통해 클러스터별로 색상을 다르게 할 수 있습니다. matplotlib을 사용하려면 for문을 활용해, 각 클러스터별로 scatter plot을 그리고 위에 덧그리는 방식을 활용합니다. 이를테면 클러스터 0번이 파란색으로 칠해지고, 그 다음 클러스터 1번이 주황색으로 그 위에 덧그려집니다. 이를 위해선 클러스터 번호에 해당하는 i 를 for문의 인자로 사용합니다. 참고로 sorted(pca_df['cluster'].unique()) <- 이 코드에서 sorted를 사용하였는데요, 사실 sorted를 쓰지 않아도 그래프는 비슷합니다. sorted는 정렬을 해주는 함수인데, 얘를 쓰지않으면 클러스터 번호가 뒤죽박죽이 되어서 개인적으로 정렬되어 있는 형태를 좋아하는 편이라(ㅎㅎ,,) 사용해주었습니다. 어쨌든, 결과를 보면 두 그래프 모두 아주 깨끗하게 색깔이 나뉘어 있음을 볼 수 있죠? 정보를 보존한 채, 깔끔하게 데이터를 축소했음을 알 수 있습니다. (참고로, 주성분의 개수를 적절치 않게 설정하면 그래프가 겹치게 그려집니다.) 이제 이 결과를 활용하여, 탈퇴 회원의 경향을 파악해봅시다. 이번 포스팅의 마지막 파트입니다. Tech 35. 클러스터별 회원 특징 파악하기(탈퇴, 정기적 이용 여부)앞서 만든 4개의 클러스터에서 지속회원(탈퇴하지 않은 회원)과 탈퇴회원은 얼마나 있을까요? 탈퇴여부를 파악하고 싶으므로, 'cc' 데이터에 원본 데이터인 'c' 데이터를 붙입니다. 'c' 데이터에 'is_deleted(탈퇴여부)' 열이 포함되어 있기 때문입니다. (참고로 is_deleted 값이 1이면 탈퇴, 0이면 지속회원입니다.)
pd.concat 함수를 사용하여 'cc' 데이터에 'c' 데이터가 조인된 'cc_join' 데이터가 만들어졌습니다. 우리가 필요한 것은 클러스터별 탈퇴여부이므로, 이에 대해 groupby를 해서 해당 회원이 몇 명이나 있는지 알아봅시다.
이렇게 결과가 나왔습니다. 교재에서는 여기서 끝냈지만, 저는 클러스터 및 탈퇴여부별 고객 비율이 궁금했습니다. 이를 자동으로 출력해주면 편하지 않을까 싶어 코드를 이렇게 짜봤습니다.
이렇게 데이터프레임의 loc 메서드를 활용하면 쉽게 출력해볼 수 있습니다. (저는 loc 애용자입니다,,) 아무튼 뽑힌 결과를 읽어보면, 클러스터별로 탈퇴회원과 지속회원의 수를 알아볼 수 있네요!
앞서,
였음을 참고하면, 다음과 같이 정리해볼 수 있겠네요! - 클러스터 1: 가장 안좋은 그룹 (가장 짧게 이용하고, 모두 탈퇴함.) 다음으로는 정기적 이용여부(flag 컬럼)을 살펴봅니다. 이 또한 앞에서와 마찬가지로, 클러스터 및 flag 컬럼별 회원 수를 세면 되겠죠? (*flag 열은 '파이썬 데이터 분석 #3' 포스팅에서 자체제작한 컬럼인데, 1이면 정기적으로 이용하고 0이면 비정기적으로 이용함을 의미합니다)
마찬가지로 이렇게는 보기가 좀 힘드니 앞서 만든 for문을 살짝 수정해서 비율을 뽑아봅니다.
결과를 해석해보면 앞서 나타난 결과와 비슷합니다.
만일 제가 이 헬스장의 마케터라면 클러스터 2와 3에 해당하는 회원을 꽉 잡을 마케팅을 해볼 것 같네요! 이렇게 이번 포스팅을 마칩니다. 이번 포스팅에서는 헬스장 고객 데이터에 클러스터링(군집분석)을 활용해, 좀 더 구체적인 데이터 분석을 해보았습니다. 지금까지의 분석을 통해, 회원의 이용 방법(회원의 행동 데이터)가 정말 중요함을 알 수 있었습니다. 다음 포스팅에서는 회원의 "이용 횟수"를 예측하는 모델을 만들어봅니다. 고객의 과거 행동 데이터로부터, 알지 못하는 다음 달 이용횟수를 예측해봅니다. 감사합니다. 궁금한 점이 있으시면 언제든 댓글 주세요 :) |