당신은 주제를 찾고 있습니까 “파이썬 군집 분석 – [파이썬 실습] 군집분석“? 다음 카테고리의 웹사이트 https://you.tfvp.org 에서 귀하의 모든 질문에 답변해 드립니다: you.tfvp.org/blog. 바로 아래에서 답을 찾을 수 있습니다. 작성자 김성범[ 소장 / 인공지능공학연구소 ] 이(가) 작성한 기사에는 조회수 5,402회 및 좋아요 29개 개의 좋아요가 있습니다.
파이썬 군집 분석 주제에 대한 동영상 보기
여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!
d여기에서 [파이썬 실습] 군집분석 – 파이썬 군집 분석 주제에 대한 세부정보를 참조하세요
파이썬 군집 분석 주제에 대한 자세한 내용은 여기를 참조하세요.
[Python] 사이킷런(sklearn)을 활용한 K-평균 군집분석(K-Means …
비지도 학습 중 유사한 속성을 가진 데이터끼리 군집을 만들어주는 클러스터링(군집분석)을 학습해 보겠습니다. sklearn에서 제공하는 iris(붓꽃) …
Source: planharry.tistory.com
Date Published: 6/24/2021
View: 4422
고객 유형을 나누기(파이썬 클러스터링, 군집 분석 … – Everly.
고객 유형을 나누기(파이썬 클러스터링, 군집 분석) / 파이썬 데이터 분석 실무 테크닉 100. Everly. 2022. 4. 6. 09:20. 안녕하세요, Everly입니다.
Source: suy379.tistory.com
Date Published: 10/9/2021
View: 152
[Python 머신러닝] 8장. 군집분석 (Cluster Analysis)
군집분석이란? 서로 유사한 정도에 따라 다수의 객체를 군집으로 나누는 작업 또는 이에 기반한 분석을 의미한다. – 유사도가 높은 데이터끼리 그룹화 …
Source: joyfuls.tistory.com
Date Published: 7/10/2021
View: 1960
[ML] 군집분석(K-means, K-means++) – 데이터분석
파이썬 활용하여 K-평균 군집분석 진행하기 # 무작위 데이터셋 생성 from sklearn.datasets import make_blobs X, y = make_blobs(n_samples = 150, …
Source: hyunse0.tistory.com
Date Published: 5/13/2021
View: 7532
K-Means 클러스터링 파이썬 연습 예제 – 고객 구매 데이터 분석
ZipCode와 Product는 군집 분석 결과를 해석할 때 사용한다. 즉,남은 ItemsBought과 ItemsReturned로 클러스터링을 한다.
Source: lucy-the-marketer.kr
Date Published: 6/16/2021
View: 219
[python] 자연어처리(NLP) – Kmeans, K대푯값 군집 분석
이제는 군집분석을 파이썬으로 구현하여 보겠습니다. 우선 데이터를 준비해 주어야 하는데요. 저는 네이버 api를 이용해 뉴스 제목, 요약, …
Source: wonhwa.tistory.com
Date Published: 8/1/2021
View: 3414
14 장 군집분석 | 데이터과학 – Big data Lab.
14 장 군집분석 | 데이터과학. … 군집분석. 모집단 또는 범주에 대한 사전 정보가 없는 경우 주어진 관측값들 사이의 거리(distance) 또는 … 14.3 Python 예제.
Source: bigdata.dongguk.ac.kr
Date Published: 10/10/2021
View: 8825
11. K-Means 클러스터링(Clustering, 군집화)에 대해서 알아 …
K-Means 클러스터링(Clustering, 군집 분석) 파이썬 구현. 먼저 샘플용 데이터를 만들어보자. import numpy as …
Source: zephyrus1111.tistory.com
Date Published: 4/17/2022
View: 7001
주제와 관련된 이미지 파이썬 군집 분석
주제와 관련된 더 많은 사진을 참조하십시오 [파이썬 실습] 군집분석. 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.
주제에 대한 기사 평가 파이썬 군집 분석
- Author: 김성범[ 소장 / 인공지능공학연구소 ]
- Views: 조회수 5,402회
- Likes: 좋아요 29개
- Date Published: 2021. 5. 29.
- Video Url link: https://www.youtube.com/watch?v=_U7AUJqzlJs
[Python] 사이킷런(sklearn)을 활용한 K-평균 군집분석(K-Means Clustering)
비지도 학습 중 유사한 속성을 가진 데이터끼리 군집을 만들어주는 클러스터링(군집분석)을 학습해 보겠습니다.
sklearn에서 제공하는 iris(붓꽃) 데이터를 활용하겠습니다. 분류형 모델에서 많이 사용됩니다~
1. 데이터 불러오기
# 필요한 패키지 설치 import pandas as pd import numpy as np # iris 데이터 불러오기 위한 datasets 설치 from sklearn import datasets
2. 분석에 사용할 학습용 데이터 만들기
# skearn.datasets에 포함된 iris(붓꽃) 데이터 가져오기 iris = datasets.load_iris() # iris 데이터 내 data값들 data= pd.DataFrame(iris.data) ; data # iris데이터의 feature 이름 feature= pd.DataFrame(iris.feature_names) ; feature # data의 컬럼명을 feature이름으로 수정하기 data.columns = feature[0] # 세가지 붓꽃의 종류 target=pd.DataFrame(iris.target) ; target # 컬럼명 바꾸기 target.columns=[‘target’] # data와 target 데이터프레임을 합치기 (axis=1, columns으로 합치기) df= pd.concat([data,target], axis=1) df.head()
3. 데이터 구조 확인(컬럼 타입과 결측치 등)
df.info()
#target 컬럼을 object 타입으로 변경 df = df.astype({‘target’: ‘object’})
# 결측치 없음, 각 속성마다 150개 row씩 있음 df.describe()
# 클러스터 돌리기 전 변수를 생성 df_f = df.copy()
4. 시각화 하기
import seaborn as sns from matplotlib import pyplot as plt from mpl_toolkits.mplot3d import Axes3D from mpl_toolkits.mplot3d import proj3d
sns.pairplot(df_f, hue=”target”) plt.show()
위 그림 3열에 petal length를 가지고도 어느정도 분류가 가능하겠네요.
그래도 4개 속성을 모두 가지고 클러스터링을 해보겠습니다.
원하는 속성을 사용해서 2차원, 3차원 그래프도 자세하게 그려보겠습니다.
# 2차원 그리기 fig = plt.figure(figsize=(5,5)) X = df_f plt.plot( X.iloc[:,0] , X.iloc[:,3] , ‘o’ , markersize=2 , color=’green’ , alpha=0.5 , label=’class1′ ) plt.xlabel(‘x_values’) plt.ylabel(‘y_values’) plt.legend() #범례표시 plt.show()
# 3차원 그리기 fig = plt.figure(figsize=(8, 8)) ax = fig.add_subplot(111, projection=’3d’) X = df_f # 3d scatterplot 그리기 ax.scatter( X.iloc[:,0] , X.iloc[:,1] , X.iloc[:,2] # , c=X.index #마커컬러 , s=10 #사이즈 , cmap=”orange” #컬러맵 , alpha=1 #투명도 , label=’class1′ #범례 ) plt.legend() #범례표시 plt.show()
5. K-Means cluster
from sklearn.cluster import KMeans
# 적절한 군집수 찾기 # Inertia(군집 내 거리제곱합의 합) value (적정 군집수) ks = range(1,10) inertias = [] for k in ks: model = KMeans(n_clusters=k) model.fit(df_f) inertias.append(model.inertia_) # Plot ks vs inertias plt.figure(figsize=(4, 4)) plt.plot(ks, inertias, ‘-o’) plt.xlabel(‘number of clusters, k’) plt.ylabel(‘inertia’) plt.xticks(ks) plt.show()
k개수가 3에서 완만하게 변하기 때문에 군집을 3개로 하면 적당할 것 같습니다.
# K-Means 모델과 군집 예측값을 생성 # 클러스터 모델 생성 파라미터는 원할 경우 추가 clust_model = KMeans(n_clusters = 3 # 클러스터 갯수 # , n_init=10 # initial centroid를 몇번 샘플링한건지, 데이터가 많으면 많이 돌릴수록안정화된 결과가 나옴 # , max_iter=500 # KMeans를 몇번 반복 수행할건지, K가 큰 경우 1000정도로 높여준다 # , random_state = 42 # , algorithm=’auto’ ) # 생성한 모델로 데이터를 학습시킴 clust_model.fit(df_f) # unsupervised learning # 결과 값을 변수에 저장 centers = clust_model.cluster_centers_ # 각 군집의 중심점 pred = clust_model.predict(df_f) # 각 예측군집 print(pd.DataFrame(centers)) print(pred[:10])
[1 1 1 1 1 1 1 1 1 1]# 원래 데이터에 예측된 군집 붙이기 clust_df = df_f.copy() clust_df[‘clust’] = pred clust_df.head()
여기서 target의 번호와 clust의 번호가 다른것은 군집이 잘못나온게 아니라 넘버링된 번호가 다를 뿐입니다.
스케일링 한 후에 아래에서 잘 묶여 나왔는지 확인하겠습니다.
6. 군집분석 결과를 가지고 시각화 하기
# scaling하지 않은 데이터를 학습하고 시각화하기 plt.figure(figsize=(20, 6)) X = clust_df plt.subplot(131) sns.scatterplot(x=X.iloc[:,0], y=X.iloc[:,1], data=df_f, hue=clust_model.labels_, palette=’coolwarm’) plt.scatter(centers[:,0], centers[:,1], c=’black’, alpha=0.8, s=150) plt.subplot(132) sns.scatterplot(x=X.iloc[:,0], y=X.iloc[:,2], data=df_f, hue=clust_model.labels_, palette=’coolwarm’) plt.scatter(centers[:,0], centers[:,2], c=’black’, alpha=0.8, s=150) plt.subplot(133) sns.scatterplot(x=X.iloc[:,0], y=X.iloc[:,3], data=df_f, hue=clust_model.labels_, palette=’coolwarm’) plt.scatter(centers[:,0], centers[:,3], c=’black’, alpha=0.8, s=150) plt.show()
스케일링을 하지 않아도 3가지로 잘 분류된 것 같습니다.
# 3차원으로 시각화하기 fig = plt.figure(figsize=(8, 8)) ax = fig.add_subplot(111, projection=’3d’) X = clust_df # 데이터 scatterplot ax.scatter( X.iloc[:,0] , X.iloc[:,1] , X.iloc[:,2] , c = X.clust , s = 10 , cmap = “rainbow” , alpha = 1 ) # centroid scatterplot ax.scatter(centers[:,0],centers[:,1],centers[:,2] ,c=’black’, s=200, marker=’*’) plt.show()
7. 군집 별 특징 확인하기
cluster_mean= clust_df.groupby(‘clust’).mean() cluster_mean
8. 스케일링 하고 다시 군집분석하기
기존 데이터 값이 각 변수 별 값의 편차가 적어서 스케일링을 하지 않고도 아주 잘 군집이 되었지만,
일반적으로는 변수 별로 편차가 크기 때문에 스케일링이 필요할 수 있습니다.
*스케일링(표준화): 데이터 피처(속성)들을 평균이 0이고 분산이 1인 가우시안 정규 분포를 가진 값으로 변환해주는 것
from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler standard_scaler = StandardScaler() scaled_df = pd.DataFrame(standard_scaler.fit_transform(df_f.iloc[:,0:4]), columns=df_f.iloc[:,0:4].columns) # scaled된 데이터
# create model and prediction # clust_model은 스케일링 전 fit과 동일하게 맞춤 clust_model.fit(scaled_df) # unsupervised learning #애초에 결과를 모르기 때문에 data만 넣어주면 됨 centers_s = clust_model.cluster_centers_ pred_s = clust_model.predict(scaled_df)
# 스케일링 전에 합쳐준 데이터프레임에 스케일한 군집 컬럼 추가하기 clust_df[‘clust_s’] = pred_s clust_df
# scaling 완료한 데이터를 학습하고 시각화하기 plt.figure(figsize=(20, 6)) X = scaled_df plt.subplot(131) sns.scatterplot(x=X.iloc[:,0], y=X.iloc[:,1], data=scaled_df, hue=clust_model.labels_, palette=’coolwarm’) plt.scatter(centers_s[:,0], centers_s[:,1], c=’black’, alpha=0.8, s=150) plt.subplot(132) sns.scatterplot(x=X.iloc[:,0], y=X.iloc[:,2], data=scaled_df, hue=clust_model.labels_, palette=’coolwarm’) plt.scatter(centers_s[:,0], centers_s[:,2], c=’black’, alpha=0.8, s=150) plt.subplot(133) sns.scatterplot(x=X.iloc[:,0], y=X.iloc[:,3], data=scaled_df, hue=clust_model.labels_, palette=’coolwarm’) plt.scatter(centers_s[:,0], centers_s[:,3], c=’black’, alpha=0.8, s=150) plt.show()
스케일링 한 데이터도 잘 시각적으로는 잘 나눠진 듯 합니다.
아래에서 자세한 비교를 해보겠습니다.
9. 스케일링 한 데이터와 안한 데이터의 군집 성능 비교하기
# 스케일링 전 데이터의 군집 pd.crosstab(clust_df[‘target’],clust_df[‘clust’]) # 스케일링 후 데이터의 군집 pd.crosstab(clust_df[‘target’],clust_df[‘clust_s’])
스케일링 전 데이터는 원래 target분류값과 1개만 다르게 나타남
스케일링 후 데이터는 원래 target분류값과 많이 다르게 나타남
스케일하지 않았던 clust컬럼 데이터가 훨씬 정확하게 나왔습니다.
고객 유형을 나누기(파이썬 클러스터링, 군집 분석) / 파이썬 데이터 분석 실무 테크닉 100
안녕하세요, Everly입니다.
정말 오랫만에 ‘파이썬 분석 실무 테크닉’ 공부한 부분을 리뷰하는데요! (3달 만이군요..) 앞으로는 좀 더 자주 업로드해보도록 하겠습니다 🙂
오늘은 지난 포스팅에서 다뤘던 스포츠 센터(편의상 헬스장) 데이터를 바탕으로, 이 헬스장을 사용하는 고객이 어떤 유형이 있고, 고객의 행동을 에측하는 데이터 분석을 공부해봅니다.
이번 포스팅에서는 클러스터링(clustering)을 통해 고객의 유형을 나눠 보고,
바로 다음 포스팅에서는 고객의 과거 데이터를 기반으로 예측하는 머신러닝 모델을 만들어 봅니다.
[고객의 소리] 지난번 분석으로 어느 정도 경향을 파악할 수 있었습니다. 아직 전체적인 경향밖에 파악하지 못해서, 이번에는 좀 더 구체적인 분석을 부탁드리려고 합니다.고객별로 이용 경향이 다르기 때문에 이런 경향을 분석해서 고객별 이용 횟수 같은 것도 예측할 수 있지 않을까라는 생각이 듭니다. 이런 분석도 가능할까요?
지난 포스팅에서 사용했던 데이터를 그대로 사용합니다.
use_log.csv : 헬스장 이용이력 데이터. (기간: 2018.04 ~ 2019.03)
customer_join.csv : 앞서 [파이썬 데이터 분석 #3] 포스팅에서 가공한, 이용 이력을 포함한 고객 데이터.
지난번 [파이썬 데이터 분석 #3] 포스팅을 통해, 헬스장을 사용하는 고객들의 특징에 대해 몇 가지 인사이트를 도출해 봤었죠. 고객 1인당 월평균 5회 정도를 사용하고 있었고, 지속적으로 이용하는 사람(flag 변수)도 전체의 81%나 있었습니다. 또한 회원 기간의 분포를 살펴보니 10개월을 기점으로 회원 기간 분포가 뚝 끊기는 것을 볼 수 있어, ‘마의 10개월’을 발견하기도 했습니다.
이러한 인사이트는 전체 고객을 대상으로 본 것이었습니다. 하지만 이번에는 좀 더 구체적으로, 어떤 유형의 고객들이 있는지가 궁금합니다. 자주 이용하는 고객 그룹과, 아닌 그룹이 있지 않을까요? 이를 나누기 위해선 어떤 변수를 사용해서 나눌 수 있을까요? 좀 더 자세히 알아보겠습니다.
✔Table of Contents
Tech 31. 데이터 불러오기
import pandas as pd ul = pd.read_csv(‘3장/use_log.csv’) c = pd.read_csv(‘customer_join.csv’) ul.isnull().sum() c.isnull().sum()
use_log 데이터는 ‘ul’, customer_join 데이터는 ‘c’로 불러옵니다.
결측치를 확인해 보니 ul은 없고, c의 경우 end_date(탈퇴시점)에 2842개의 결측치가 있네요. 아직 탈퇴를 하지 않은 회원은 이렇게 end_date에 결측값이 있습니다. 딱히 이상 없는 데이터입니다.
Tech 32. 클러스터링을 활용한 회원 그룹화
※ 클러스터링(Clustering) 이란?
– 군집 분석이라고도 하며, 정답 데이터가 없기 때문에 ‘비지도학습’ 의 일종입니다.
주로 고객을 그룹화하는 등 공통된 특성을 가진 군집들로 묶는 알고리즘을 의미합니다. 가장 유명한 것은 K-means 클러스터링인데, 이번 장에서도 이를 활용합니다.
클러스터링은 ‘c’ 데이터로 진행합니다. 회원의 이용이력에 따라 고객을 유형화해볼 수 있을 것 같네요. 그래서 회원의 이용이력과 관련한 변수를 사용합니다.
cc = c[[‘mean’, ‘median’, ‘max’, ‘min’, ‘mem_period’]] cc.head()
바로 mean, median, max, min, mem_period인데요. 각각 고객별 한달 평균, 중위수, 최대, 최소 이용횟수와 회원 기간(단위: month)입니다.
c 데이터는 유일한 고객별 이용이력을 담고 있습니다. 이를테면 c 데이터의 0번 행의 고객은, 한 달 평균 4.83회를 사용하고, 한달 중위수 5회, 한달에 최소 2회~최대 8회까지 사용하네요.
어쨌든 이러한 컬럼들만 따로 떼어 변수 ‘cc’를 만들어줍니다.
이제 k-means 클러스터링을 실시합니다. 단, 조건이 있습니다.
<조건>
#1. 그룹 개수 설정: 4개
#2. mean, median, max, min 변수는 월 이용 횟수와 관련한 변수이므로 1~8 사이값을 갖지만, mem_period는 이에 비해 값이 너무 크다. -> 그러므로 mem_period에는 표준화를 하자.
2번 조건을 토대로 5개 변수의 값을 평균 0, 표준편차 1을 따르는 정규분포를 따르도록 바꿔줍니다. 이를 ‘표준화’라고 합니다.
이런 과정을 거치지 않고 그냥 클러스터링을 해버리면 값이 너무 큰 ‘mem_period’ 변수가 가장 중요한 변수로 인식될 수 있고 올바른 클러스터링이 불가능하기 때문에 표준화를 해줍니다.
from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler #표준화 sc = StandardScaler() cc_scaled = sc.fit_transform(cc) pd.DataFrame(cc_scaled) #mean~min, mem_period 5개 변수가 표준화됨.
표준화를 통해 위의 5가지 변수가 이와 같이 바뀌었습니다. 모든 변수의 값이 비슷해졌죠? 이 데이터는 ‘cc_scaled’ 입니다.
#cc_scaled 데이터를 넣어 클러스터링 kmeans = KMeans(n_clusters=4, random_state=0) clusters = kmeans.fit(cc_scaled) #클러스터링 변수인 clusters 값을 원본 데이터인 ‘cc’내에 넣기 cc[‘cluster’] = clusters.labels_ cc.head()
위의 코드를 통해 군집이 4개(n_clusters)인 k-means 클러스터링을 수행할 수 있습니다.
어떤 클러스터가 만들어졌는지는 labels_ 메서드를 통해 알 수 있는데요, 더 쉽게 알아보기 위해 초반에 만들어 둔 ‘cc’ 데이터(변수 5개만 있는 데이터프레임)에 ‘clsuter’라는 새로운 컬럼을 만들어 클러스터 번호를 넣어줍니다.
이렇게 ‘cluster’ 컬럼이 새로 생겼음을 알 수 있죠.
unique 메서드를 활용하면 cluster가 0, 1, 2, 3 이렇게 4개가 생성되었음을 알 수 있습니다. 이제, k-means 알고리즘이 자동으로 군집화해준 이 클러스터가 어떤 특징을 띠고 있는지를 분석해봅시다.
Tech 33. 클러스터링 결과 분석
#먼저 열 이름을 알아보기 쉽게 한글로 바꾼다. cc.rename(columns = {‘mean’:’월평균값’, ‘median’:’월중앙값’, ‘max’:’월최댓값’, ‘min’:’월최솟값’, ‘mem_period’:’회원기간’}, inplace=True) cc
#cluster를 기준으로 데이터 개수 세기 cc.groupby(‘cluster’).count()
#그룹별 특징을 알아보자! -그룹별 평균값 cc.groupby(‘cluster’).mean()
groupby를 통해 다양한 통계량을 알아봅니다.
count() 메서드를 통해선 각 클러스터(그룹)별로 개수가 몇개인지를 셉니다. 그룹 0이 1334개로 가장 많이 들어있고, 그룹3 > 그룹2 > 그룹 1 순이네요.
다음은 mean() 메서드를 통해 각 클러스터별 평균값을 알아봅니다.
그룹 2는 평균 회원기간은 가장 짧지만(7일), 월평균 이용횟수는 8회로 가장 높네요.
그룹 1은 평균 회원기간도 9일로 짧은데다가 월평균 이용횟수는 3회로 가장 낮습니다.
그룹 0, 그룹 3은 평균 회원기간이 그룹 1, 2보다는 깁니다. 그런데 그룹 3은 그룹 0보다 회원기간은 길지만(36일 > 14일), 월평균 이용횟수는 더 적습니다(4.6회 < 5.5회) 이렇게 그룹의 특징을 파악해보면, 그룹별로 다른 캠페인이나 프로모션을 사용할 수 있겠죠? 여기서는 사용한 변수가 단 5개이지만, 더 특징적인 변수를 포함시킨다면 보다 복잡한 클러스터링도 가능합니다. 이제는 이 클러스터링 결과를 눈으로 보기 쉽도록 그래프로 나타내봅시다. Tech 34. 클러스터링 결과 시각화(차원 축소 활용) 하지만 문제가 생깁니다. 보통 우리가 그리는 그래프는 2차원입니다. 그런데 여기서 사용한 변수는 5개로, 5차원 그래프는 그리기도 힘들뿐더러 이해하기도 쉽지 않습니다. 여기서 우리는 5개의 변수를 2개의 변수로 줄이는 작업을 통해, 2차원 그래프로 나타내봅니다. 이것이 바로 '차원 축소'인데요, 대표적인 차원 축소 방법인 PCA(Principal Component Analysis)를 수행합니다. ※ 차원 축소란? - 정보를 되도록 잃지 않게 하면서 새로운 축을 만드는 기법. 여기서 사용하는 차원축소 기법 중 하나인 PCA는 주성분분석이라고도 하며, 5개의 변수를 2개의 주성분(정보를 가장 많이 담고 있는) 으로 만듭니다. from sklearn.decomposition import PCA X = cc_scaled.copy() #객체 pca = PCA(n_components=2) #적용 pca.fit(X) x_pca = pca.transform(X) x_pca 앞서 만들었던 표준화 변수 'cc_scaled'를 copy한 새로운 변수 'X'를 만들어 PCA를 적용했습니다. 결과가 array 형태라 보기가 불편하네요. 보기 쉽게 데이터프레임으로 바꿔봅시다. 클러스터 넘버도 포함해서요! #x_pca를 보기 쉽게 데이터프레임으로 만들기 pca_df = pd.DataFrame(x_pca) pca_df['cluster'] = cc['cluster'] pca_df.head() 이와 같이 5개였던 변수가 2개의 주성분으로 바뀌었습니다. 어차피 컬럼만 줄어든 것뿐, 행의 수는 똑같으니까 cc 데이터의 'cluster' 컬럼으로 그대로 가져와도 문제없습니다. 이제는 2개의 주성분 변수를 2차원 그래프로 나타내봅시다. 저는 교재 외의 방법으로 seaborn, matplotlib 라이브러리 2가지를 사용해 만들어 보았습니다. import matplotlib.pyplot as plt import seaborn as sns axs = plt.subplots() axs = sns.scatterplot(0, 1, hue='cluster', data=pca_df) seaborn 라이브러리 사용 for i in sorted(pca_df['cluster'].unique()): tmp = pca_df.loc[pca_df['cluster'] == i] #해당하는 클러스터 번호일 때 그림을 그리고, for문 실행하며 위에 덧그림 plt.scatter(tmp[0], tmp[1]) plt.legend(sorted(pca_df['cluster'].unique())) 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이면 지속회원입니다.) #앞서 만든 cc에서 지속/탈퇴회원 여부를 알아야 하므로 'is_deleted' 열을 추가한다. (이 열은 c 데이터에 있으므로 둘을 조인) cc_join= pd.concat([cc, c], axis=1) cc_join.head() pd.concat 함수를 사용하여 'cc' 데이터에 'c' 데이터가 조인된 'cc_join' 데이터가 만들어졌습니다. 우리가 필요한 것은 클러스터별 탈퇴여부이므로, 이에 대해 groupby를 해서 해당 회원이 몇 명이나 있는지 알아봅시다. newdf = cc_join.groupby(['cluster','is_deleted'], as_index=False).count()[['cluster', 'is_deleted', 'customer_id']] newdf 이렇게 결과가 나왔습니다. 교재에서는 여기서 끝냈지만, 저는 클러스터 및 탈퇴여부별 고객 비율이 궁금했습니다. 이를 자동으로 출력해주면 편하지 않을까 싶어 코드를 이렇게 짜봤습니다. #위의 newdf에서 cluster별 탈퇴 및 미탈퇴회원 비율을 for문으로 뽑아보자. de0 = (newdf['is_deleted']==0) #지속회원 de1 = (newdf['is_deleted']==1) #탈퇴회원 for i in range(0, 4): tmp = (newdf['cluster']==i) print('Cluster '+ str(i) + '의 탈퇴회원 비율은 ' + str(round((newdf.loc[(tmp & de1), 'customer_id'].sum() / newdf.loc[tmp, 'customer_id'].sum())*100, 2)) + '%') print('Cluster '+ str(i) + '의 지속회원 비율은 ' + str(round((newdf.loc[(tmp & de0), 'customer_id'].sum() / newdf.loc[tmp, 'customer_id'].sum())*100, 2)) + '%') print(' ') 이렇게 데이터프레임의 loc 메서드를 활용하면 쉽게 출력해볼 수 있습니다. (저는 loc 애용자입니다,,) 아무튼 뽑힌 결과를 읽어보면, 클러스터별로 탈퇴회원과 지속회원의 수를 알아볼 수 있네요! 클러스터 1: 탈퇴회원만 존재 클러스터 2,3: 지속회원 >> 탈퇴회원
클러스터 0: 지속회원과 탈퇴회원 수 비슷
앞서,
클러스터 2는 평균 회원기간은 가장 짧지만, 월 평균 이용횟수는 가장 높았다.
클러스터 1은 평균 회원기간도 짧고 월평균 이용횟수도 적은 그룹이다.
클러스터 0, 3은 평균 회원기간은 클러스터 1,2보다는 길다. 그런데 그룹3은 그룹0보다 회원기간은 길지만, 이용횟수는 더 적은 편이다.
였음을 참고하면, 다음과 같이 정리해볼 수 있겠네요!
– 클러스터 1: 가장 안좋은 그룹 (가장 짧게 이용하고, 모두 탈퇴함.)
– 클러스터 2: 초반에 불타오르는 좋은 그룹 (이용횟수가 많고 지속회원이 많다. 그런데 평균 회원기간이 짧아서 초기에 의욕적으로 이용하는 그룹인 듯)
– 클러스터 3: 안정적인 그룹 (회원기간이 길고, 이용횟수는 적으나 지속회원이 많다.)
– 클러스터 0: 회원기간이 길고, 탈퇴회원과 지속회원이 비등비등한 그룹.
다음으로는 정기적 이용여부(flag 컬럼)을 살펴봅니다. 이 또한 앞에서와 마찬가지로, 클러스터 및 flag 컬럼별 회원 수를 세면 되겠죠? (*flag 열은 ‘파이썬 데이터 분석 #3’ 포스팅에서 자체제작한 컬럼인데, 1이면 정기적으로 이용하고 0이면 비정기적으로 이용함을 의미합니다)
newdf2 = cc_join.groupby([‘cluster’,’flag’], as_index=False).count()[[‘cluster’, ‘flag’, ‘customer_id’]] newdf2
마찬가지로 이렇게는 보기가 좀 힘드니 앞서 만든 for문을 살짝 수정해서 비율을 뽑아봅니다.
#마찬가지로 for문으로 비율을 자동출력해보자. flag0 = (newdf2[‘flag’]==0) #비정기회원 flag1 = (newdf2[‘flag’]==1) #정기회원 for i in range(0, 4): tmp = (newdf2[‘cluster’]==i) print(‘Cluster ‘+ str(i) + ‘의 정기회원 비율은 ‘ + str(round((newdf2.loc[(tmp & flag1), ‘customer_id’].sum() / newdf2.loc[tmp, ‘customer_id’].sum())*100, 2)) + ‘%’) print(‘Cluster ‘+ str(i) + ‘의 비정기회원 비율은 ‘ + str(round((newdf2.loc[(tmp & flag0), ‘customer_id’].sum() / newdf2.loc[tmp, ‘customer_id’].sum())*100, 2)) + ‘%’) print(‘ ‘)
결과를 해석해보면 앞서 나타난 결과와 비슷합니다.
클러스터 1: 가장 이용을 적게하는 그룹 -> 정기 35% < 비정기 65% 클러스터 2: 초반에 불타오르는 좋은 그룹 -> 정기 93% >> 비정기 6%
클러스터 3: 안정적 이용그룹 -> 정기 99% >> 비정기 0.1%
클러스터 0: 지속, 탈퇴 비등한 그룹 -> 정기 83% > 비정기 17% (정기가 조금 더 많다)
만일 제가 이 헬스장의 마케터라면 클러스터 2와 3에 해당하는 회원을 꽉 잡을 마케팅을 해볼 것 같네요!
이렇게 이번 포스팅을 마칩니다. 이번 포스팅에서는 헬스장 고객 데이터에 클러스터링(군집분석)을 활용해, 좀 더 구체적인 데이터 분석을 해보았습니다.
지금까지의 분석을 통해, 회원의 이용 방법(회원의 행동 데이터)가 정말 중요함을 알 수 있었습니다.
다음 포스팅에서는 회원의 “이용 횟수”를 예측하는 모델을 만들어봅니다. 고객의 과거 행동 데이터로부터, 알지 못하는 다음 달 이용횟수를 예측해봅니다.
감사합니다. 궁금한 점이 있으시면 언제든 댓글 주세요 🙂
반응형
[Python 머신러닝] 8장. 군집분석 (Cluster Analysis)
군집분석이란?
서로 유사한 정도에 따라 다수의 객체를 군집으로 나누는 작업 또는 이에 기반한 분석을 의미한다.
– 유사도가 높은 데이터끼리 그룹화 (대표적으로 유클리드 거리식 이용)
– 계층형 클러스터링과 비계층형 클러스터링으로 분류
– 주요 알고리즘 : k-means, hierarchical
> 군집분석의 특징
– 종속변수(y변수)가 없는 데이터 마이닝 기법 (비지도 학습)
– 유클리드 거리 기반 유사 객체 묶음 (유사성 = 유클리드 거리)
– 전체적인 데이터 구조를 파악하는데 이용
– 분석결과에 대한 가설 검정 없음 (타당성 검증 방법 없음)
– 계층적 군집분석(탐색적), 비계층적 군집분석(확인적)
– 고객 DB -> 알고리즘 적용 -> 패턴 추출(rule) -> 근거리 모형으로 군집 형성
– 척도 : 등간, 비율척도 => 명목척도를 만듦
1) 유클리드 거리
– 두 점 사이의 거리를 계산하는 방법
– 이 거리를 이용하여 유클리드 공간 정의
2) 계층적 군집분석 (hierarchical)
– 유클리드 거리를 이용한 군집분석 방법
– 계층적으로 군집 결과 도출
– 탐색적 군집분석
– 계층적 군집분석의 결과
=> 덴드로그램 (Dendrogram) : 표본들이 군을 형성하는 과정을 나타내는 나무 형식의 그림
– 군집 수는 사용자가 정할 수 있음 (2집단, 3집단, … 등)
– 군집화 방식
① 단일기준결합방식 : 각 군집에서 중심으로부터 거리가 가까운 것 1개씩 비교하여 가장 가까운 것끼리 군집화
② 완전기준결합방식 : 각 군집에서 중심으로부터 가장 먼 대상끼리 비교하여 가장 가까운 것끼리 군집화
③ 평균기준결합방식 : 한 군집 안에 속해 있는 모든 대상과 다른 군집에 속해있는 모든 대상의 쌍 집합에 대한 거리를 평균 계산하여 가장 가까운 것끼리 군집화
3) 비계층적 군집분석 (k-Means)
– 계층적 군집분석보다 속도 빠름
– 군집의 수를 알고 있는 경우 이용
– k는 미리 정하는 군집 수
– 확인적 군집분석
– 계층적 군집화의 결과에 의거하여 군집 수 결정
– 변수보다 관측대상 군집화에 많이 이용
– 군집의 중심(Cluster Center)은 사용자가 정함
> k-평균(k-Menas) 군집분석 알고리즘
① k값을 초기값으로, k개의 centroid 선정 (랜덤)
② 각 데이터 포인터를 가장 가까운 centroid에 할당
③ centroid에 할당된 모든 데이터 포인트의 중심 위치 계산 (centroid 재조정)
④ 재조정된 centroid와 가장 가까운 데이터 포인트 할당
⑤ centroid 재조정이 발생되지 않을 때까지 ③, ④단계 반복
<실습한 내용>
1. hierachical (hierarchy)
2. kMeans 실습(1)
3. kMeans 실습(2)
1. hierachical (hierarchy)
“””
계층적 군집분석
– 유클리드 거리계산식 이용
– 상향식(Bottom-up)으로 군집을 형성
“””
import pandas as pd # dataset load
from sklearn.datasets import load_iris
# 계층적 군집 model
from scipy.cluster.hierarchy import linkage, dendrogram
# 1. dataset load
iris.csv 0.00MB
iris = pd.read_csv(“../data/iris.csv”)
iris.info()
cols = list(iris.columns)
iris_x = iris[cols[:4]]
iris_x.head()
iris[‘Species’].value_counts() # ‘Species’ : y변수
”’
versicolor 50
virginica 50
setosa 50
”’
# 2. y변수 수치화
X, y = load_iris(return_X_y=True)
# 사이킷런 라이브러리에서 제공하는 데이터셋을 불러오면 범주값을 숫자로 받을 수 있음
y # 0,1,2로 구성됨
labels = pd.DataFrame(y, columns = [‘labels’])
# df = df + df
irisDF = pd.concat([iris_x, labels], axis = 1)
irisDF.head()
irisDF.tail() # x변수들과 수치화된 y변수(labels)로 데이터프레임 만들어진 것을 확인
# 3. 계층적 군집분석 model
clusters = linkage(y=irisDF, method=’complete’, metric=’euclidean’)
clusters
clusters.shape # (149, 4)
”’
연결방식
1. 단순연결방식(single)
2. 완전연결방식(complete)
3. 평균연결방식(average)
”’
# 4. 덴드로그램 시각화 : 군집수 결정
import matplotlib.pyplot as plt
plt.figure( figsize = (25, 10) )
dendrogram(clusters, leaf_rotation=90, leaf_font_size=12,)
# leaf_rotation=90 : 글자 각도
# leaf_font_size=20 : 글자 사이즈
plt.show()
# 5. 클러스터링(군집) 결과
from scipy.cluster.hierarchy import fcluster # 지정한 클러스터 자르기
cut_tree = fcluster(clusters, t=3, criterion=’distance’)
cut_tree # prediction
labels = irisDF[‘labels’] # 정답
df = pd.DataFrame({‘pred’:cut_tree, ‘labels’:labels})
con_mat = pd.crosstab(df[‘pred’], df[‘labels’])
con_mat
”’
labels 0 1 2
pred
1 50 0 0
2 0 0 34
3 0 50 16
”’
# irisDF에 군집 예측치 추가
irisDF.head()
irisDF[‘cluster’] = cut_tree
irisDF.head()
# 클러스터 단위 산점도 시각화
plt.scatter(x=irisDF[‘Sepal.Length’], y=irisDF[‘Petal.Length’], c=irisDF[‘cluster’])
# 클러스터 빈도수
irisDF[‘cluster’].value_counts()
”’
3 66
1 50
2 34
”’
# 각 클러스터별 통계(평균)
cluster_g = irisDF.groupby(‘cluster’)
cluster_g.mean()
”’
Sepal.Length Sepal.Width Petal.Length Petal.Width labels
cluster
1 5.006000 3.428000 1.462000 0.246000 0.000000
2 6.888235 3.100000 5.805882 2.123529 2.000000
3 5.939394 2.754545 4.442424 1.445455 1.242424
”’
2. kMeans 실습(1)
“””
kMeans 알고리즘
– 확인적인 군집분석
– 군집 수 k를 알고 있는 경우 이용
“””
import pandas as pd # dataset load
from sklearn.cluster import KMeans # model
import matplotlib.pyplot as plt # 시각화
# 1. dataset load
# 위와 똑같은 iris.csv 파일 이용
iris.csv 0.00MB
iris = pd.read_csv(“../data/iris.csv”)
iris.info()
irisDF = iris[[‘Sepal.Length’, ‘Petal.Length’]] # 두 개의 칼럼만 이용
irisDF.head()
# 2. 비계층적 군집 분석 model
model = KMeans(n_clusters=3, random_state=0, algorithm=’auto’)
# n_clusters=3 : 군집의 개수 (k) (이미 알고 있음)
# random_state=0 : seed 역할 (모델을 일정하게 생성 = 랜덤X)
model.fit(irisDF)
# 3. 클러스터링(군집) 결과
pred = model.predict(irisDF)
pred
len(pred) # 150 (관측치 개수만큼 예측치 생성됨)
# 4. 군집결과 시각화
plt.scatter(x=irisDF[‘Sepal.Length’], y=irisDF[‘Petal.Length’], c=pred)
# 군집별 중앙값
centers = model.cluster_centers_
centers
”’
array([[5.00784314, 1.49215686],
[5.87413793, 4.39310345], [6.83902439, 5.67804878]])”’
# 군집별 중앙값 시각화
plt.scatter(x=centers[:,0], y=centers[:,1], marker=’D’, c=’r’)
# marker=’D’, c=’r’ : 마커 모양은 Diamond, 색깔은 red
plt.show()
# 군집결과와 중앙값 함께 시각화
plt.scatter(x=irisDF[‘Sepal.Length’], y=irisDF[‘Petal.Length’], c=pred)
plt.scatter(x=centers[:,0], y=centers[:,1], marker=’D’, c=’r’)
plt.show()
# 블럭 실행
3. kMeans 실습(2)
“””
kMeans 알고리즘
– testSet.txt 파일 데이터셋 이용
“””
testSet.txt 0.00MB
import pandas as pd
from sklearn.cluster import KMeans # model
import matplotlib.pyplot as plt # 시각화
import numpy as np # dataset
# testSet 데이터는 다음과 같은 형태로 입력되어 있음
# dataset 생성 함수
def loadDataSet(fileName) :
rows = [] # 전체 행(80개)
f = open(fileName, mode=’r’)
lines = f.readlines() # 줄단위 전체 행 읽기
for row in lines : # 줄 단위 읽기 : 1.658985 4.285136
line = row.split(‘\t’) # ‘1.658985’ ‘4.285136’
row = [] # 1줄 행
for l in line :
row.append( float(l) ) # [‘1.658985’, ‘4.285136’]
rows.append(row) # [[‘1.658985’, ‘4.285136’], …. ]
return np.array(rows) # 2차원(80, 2) 행렬 구조로 return
# 1. 함수 호출
dataset = loadDataSet(“../data/testSet.txt”)
dataset.shape # (80, 2)
type(dataset) # numpy.ndarray
dataset
dataset[:10, :] # 10행
plt.plot(dataset[:,0], dataset[:,1], ‘go’) # 0번째 열은 x값, 1번째 열은 y값, ‘go’ : green 색깔의 o 모양 마커
plt.show()
# 2. df 생성
dataDF = pd.DataFrame(dataset, columns = [‘x’, ‘y’])
dataDF.info()
# 3. kMeans model
model = KMeans(n_clusters=4, algorithm=’auto’) # k = 4
model.fit(dataDF)
# kMeans 예측치
pred = model.predict(dataDF)
pred # 0~3, 총 4개의 도메인으로 군집 형성
plt.scatter(x=dataDF[‘x’], y=dataDF[‘y’], c=pred)
# 각 군집의 중앙값
centers = model.cluster_centers_
centers
plt.scatter(x=centers[:,0], y=centers[:,1], marker=’D’, c=’r’)
plt.show()
# 예측치부터 블럭실행
# 4. 원형 데이터에 군집 예측치 추가
dataDF[‘cluster’] = pred
dataDF.head()
Example
exam01.py 0.00MB exam02.py 0.00MB bodycheck.csv 0.00MB product_sales.csv 0.00MB
[ML] 군집분석(K-means, K-means++)
728×90
– 정답이 없는 문제를 해결하기 위한 알고리즘 → 비지도학습 ‘군집분석’
– 군집분석(Clustering Analysis)
ex) 쇼핑몰에서 페이지 체류 시간, 구매 금액대 등을 토대로 소비자 유형 그룹을 나누고(군집 설정), 새로운 소비자가 쇼핑몰에 들어왔을 때 행동을 바탕으로 앞서 설정해놓은 그룹으로 할당, 비슷한 소비자가 구매한 상품 노출하여 제품 구매율을 높힘
군집은 정답을 모르는 데이터 안에서 숨겨진 구조를 찾는 것
클래스 레이블이 없는 데이터를 특정 군집으로 묶고자 할 때 활용
계층 군집, 밀집도 기반 군집(클러스터 모양이 원형이 아닐 때 사용)
– K-평균(K-means)
매우 쉬운 구현성, 높은 계산 효율성 → 학계와 산업현장을 가리지 않고 활약
프로토타입 기반 군집 : 각 클러스터가 하나의 프로토타입으로 표현됨 프로토타입(Prototype) 연속적인 특성에서는 비슷한 데이터 포인트의 센트로이드(centroid – 평균) 범주형 특성에서는 메도이드(medoid – 가장 자주 등장하는 포인트)
원형 클러스터 구분에 뛰어남
사전에 몇 개의 클러스터를 만들 것인지 직접 지정해줘야함 → 주관적인 사람의 판단 개입
적절한 K값을 선택했다면 높은 성능, 부적합한 K값은 모델의 성능을 보장할 수 없음
– 파이썬 활용하여 K-평균 군집분석 진행하기
# 무작위 데이터셋 생성 from sklearn.datasets import make_blobs X, y = make_blobs(n_samples = 150, # 150개 n_features = 2, # 2차원 centers = 3, # 3개의 클러스터 혹은 중심 cluster_std = 0.5, # 클러스터의 표준편차 값 shuffle = True, # 무작위로 섞을 지 여부 random_state = 0) # 시드 값 #시각화 : 2차원 산점도 그리기 import matplotlib.pyplot as plt plt.scatter(X[:, 0], X[:, 1], c = ‘white’, marker = ‘o’, edgecolor = ‘black’, s= 50) plt.grid() plt.tight_layout() plt.show()
목표 : 특성의 유사도에 기초하여 데이터들을 그룹으로 모으는 것
K-평균 4단계 알고리즘 데이터 포인트에서 랜덤하게 K개의 센트로이드를 초기 클러스터 중심으로 선택 각 데이터를 가장 가까운 센트로이드에 할당 할당된 샘플들을 중심으로 센트로이드를 이동 클러스터 할당이 변하지 않거나, 사용자가 지정한 허용오차나 최대 반복횟수에 도달할 때 까지 2/3 과정 반복
유사도 측정 방법 임의의 차원 공간에 있는 두 데이터 포인트 x와 y사이의 유클리디안 거리 혹은 유클리디안 거리 제곱 지표 기반 → 최적화 문제 클러스터 내의 제곱 오차합(SSE)을 반복적으로 최소화 각 데이터를 센트로이드에 할당할 때마다, 센트로이드는 이동 → 센트로이드가 변화할 때마다 오차 제곱합을 반복적으로 계산하면서 변화량에 대한 허용 오차값이 일정 수준내 로 들어온다면 더 이상 클러스터가 변화하지 않는다는 것이고, 최적화가 완료 되었다는 것
첫 번째 줄은 μ, 두 번째 줄은 w에 관한 설명
각 점들간의 거리를 측정할 때, 점들간의 단위와 변동폭이 크다면 왜곡 발생 → 거리 산출 시 불필요한 항목간의 특성을 제거하고 단위를 일치시키는 ‘표준화’과정으로 왜곡을 줄일 수 있음
from sklearn.cluster import KMeans km = KMeans(n_clusters = 3, # 클러스터 개수 3개 init = ‘random’, # K평균 알고리즘 설정, 초기 중심 좌표를 무작위로 선정하여 random n_init = 10, # 각기 다른 랜덤한 센트로이드에서 독립적으로 몇 번 실행하여 가장 낮은 제곱오차합을 만들 것인지 설정 max_iter = 300, # 최대 몇 번을 반복할 것인지 tol = 1e-04, # 허용 오차값 random_state = 0) # 군집분석 알고리즘에 의한 예측 클래스 레이블 y_km = km.fit_predict(X) # 시각화 import matplotlib.pyplot as plt plt.scatter(X[y_km == 0, 0], X[y_km == 0, 1], s = 50, c = ‘lightgreen’, marker = ‘s’, edgecolor = ‘black’, label = ‘cluster 1’) plt.scatter(X[y_km == 1, 0], X[y_km == 1, 1], s = 50, c = ‘orange’, marker = ‘o’, edgecolor = ‘black’, label = ‘cluster 2’) plt.scatter(X[y_km == 2, 0], X[y_km == 2, 1], s = 50, c = ‘lightblue’, marker = ‘v’, edgecolor = ‘black’, label = ‘cluster 3’) plt.scatter(km.cluster_centers_[:, 0], km.cluster_centers_[:,1], s = 250, marker = ‘*’, c = ‘red’, edgecolor = ‘black’, label = ‘centroids’) plt.legend(scatterpoints = 1) plt.grid() plt.tight_layout() plt.show()
초기 센트로이드를 설정할 때, 랜덤으로 위치를 선정하기 때문에 애초에 잘못 선정된 곳에서 시작한 경우 (여기에 더불어 데이터가 적은 악조건이 붙게 된다면) 클러스터의 성능이 매우 불안정해짐
따라서 초기 클러스터 센트로이드를 좀 더 똑똑하게 할당할 수 있는 기법 등장 → K-means++
K-means 알고리즘에서 클러스터는 중첩되지 않고 계층적이지 않음, 클러스터 당 하나 이상의 데이터가 존재 → 데이터가 꼭 하나의 클러스터로만 구분되지 않을 경우 문제 발생 → K-means++
– K-means++
km = KMeans(n_clusters = 3, # 클러스터 개수 3개 init = ‘k-means++’, # K평균++ 알고리즘 설정 n_init = 10, # 각기 다른 랜덤한 센트로이드에서 독립적으로 몇 번 실행하여 가장 낮은 제곱오차합을 만들 것인지 설정 max_iter = 300, # 최대 몇 번을 반복할 것인지 tol = 1e-04, # 허용 오차값 random_state = 0) y_km = km.fit_predict(X)
K-평균의 무작위성을 보완하기 위한 기법
초기 센트로이드가 서로 멀리 떨어지도록 위치 시킴
기본 K-평균보다 일관되고 좋은 결과 보여줌
– 사이킷런 사용하여 군집의 품질 평가하기
비지도학습은 올바른 정답이 없기 때문에 군집의 품질을 평가해야 하는 경우 알고리즘 자체의 지표를 사용해야함 ex) k-평균 군집의 성능 비교를 위한 오차 제곱합
KMeans 모델 학습을 진행한 객체 안에 관성이라는 뜻을 가진 ‘inertia’ 속성안에 이미 계산이 완료 되어 있음
print(‘왜곡 : %.2f’ % km.inertia_)
왜곡 값이 적절한 값인지는 k를 다양한 값으로 할당한 후에 왜곡값을 비교해봐야함 → 엘보우 방법
– 엘보우 방법(elbow method)
최적인 클러스터 개수 k를 추정
k값의 증가 → 센트로이드의 증가 →데이터들이 센트로이드에 더 가까워지는 것 → 왜곡값(SSE)의 감소
# k를 1부터 10까지 구축, 각각의 SSE를 시각화 distortions = [] for i in range(1, 11) : km = KMeans(n_clusters = i, init = ‘k-means++’, n_init = 10, max_iter = 300, random_state = 0) km.fit(X) distortions.append(km.inertia_) plt.plot(range(1,11), distortions, marker = ‘o’) plt.xlabel(‘Number of clusters’) plt.ylabel(‘Distortion’) plt.tight_layout() plt.show()
사람의 팔꿈치 형상
– 실루엣 분석(silhouette analysis)
군집 품질을 평가하는 또 다른 방법
클러스터 내 데이터들이 얼마나 조밀하게 모여있는지를 측정하는 그래프 도구
계수 구하는 방법 하나의 임의의 데이터(x(i))와 동일한 클러스터 내의 모든 다른 데이터 포인트 사이의 거리를 평균하여 클러스터의 응집력(a(i)) 을 계산 앞서 선정한 데이터와 가장 가까운 클러스터의 모든 샘플간 평균 거리로 최근접 클러스터의 클러스터 분리도(b(i)) 를 계산 클러스터 응집력과 분리도 사이의 차이를 둘 중 큰 값으로 나눠 실루엣 계수(s(i)) 를 계산
분리도 = 응집력 : 실루엣 계수는 0이 됨, 클러스터가 중첩되어 있다는 의미
분리도 > 응집력 : 이상적인 실루엣 계수인 1에 가깝게 됨
분리도 : 데이터가 다른 클러스터와 얼마나 다른지를 나타냄
응집력 : 클러스터 내 다른 샘플과 얼마나 비슷한지를 나타냄, 작을수록 클러스터 내 다른 데이터들과 비슷함
import numpy as np from matplotlib import cm from sklearn.metrics import silhouette_samples # sklearn의 metrics 모델 안에 silhouette_samples함수로 계산 # k-means++ 알고리즘 km = KMeans(n_clusters = 3, init = ‘k-means++’, n_init = 10, max_iter = 300, tol = 1e-04, random_state = 0) y_km = km.fit_predict(X) cluster_labels = np.unique(y_km) n_clusters = cluster_labels.shape[0] # 실루엣 분석 silhouette_vals = silhouette_samples(X, y_km, metric = ‘euclidean’) # 시각화 y_ax_lower, y_ax_upper = 0, 0 yticks = [] for i, c in enumerate(cluster_labels) : c_silhouette_vals = silhouette_vals[y_km == c] c_silhouette_vals.sort() y_ax_upper += len(c_silhouette_vals) color = cm.jet(float(i) / n_clusters) plt.barh(range(y_ax_lower, y_ax_upper), c_silhouette_vals, height = 1.0, edgecolor = ‘none’, color = color) yticks.append((y_ax_lower + y_ax_upper) / 2) y_ax_lower += len(c_silhouette_vals) silhouette_avg = np.mean(silhouette_vals) plt.yticks(yticks, cluster_labels + 1) plt.ylabel(‘Cluster’) plt.xlabel(‘Silhouette coefficient’) plt.tight_layout() plt.show()
이상치를 가진 클러스터 구별할 수 있게 됨 / 위의 그래프 경우에는 실루엣 계수가 대부분 최대값 1에 가깝게 형성되어 있으므로 군집이 잘 형성된 경우라 볼 수 있음 군집의 개수가 2개일 경우 → 군집이 비교적 잘 형성되어 있지 않다고 평가됨
728×90
K-Means 클러스터링 파이썬 연습 예제 – 고객 구매 데이터 분석
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()
결과값은 다음과 같다.
해석해보면, 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()
코드를 돌리면 다음과 같은 결과를 얻는다.
그래프를 살펴보면 Clu1인 제품 2435이 많이 안팔릴 뿐만 아니라 환불이 발생하는 것을 알 수 있다. 현재 그래프 상에는 데이터가 정규화되었기 때문에 면밀히 파악하기 어려우니 원래 데이터로 돌아가서 해당 제품을 찾아보자.
# 클러스터 1로 분류된 데이터를 추출해보자 data[ cluster_ids == 1 ]
안좋은 고객으로 할당된 고객 데이터를 보고 이제 문제점을 찾아 개선하면 된다!
■ 각 군집과 지역의 관계를 살펴보자
이번에는 클러스터링을 이용하여 지역마다의 마케팅 활동에 대해 인사이트를 얻어보자. 우편번호이기 때문에 따로 전처리를 할 필요는 없다. 다만, 전처리된 데이터 세트와 원 데이터의 세트의 레코드가 동일한 순서이기 때문에 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()
결과를 살펴보면, 우편번호가 1과 2인 지역에서 성과가 좋음을 알 수 있다. 1, 2 지역에서 어떤 마케팅을 진행하는지 확인하고 다른 지역에도 적용할 수 있는지 살펴보고, 다른 지역의 성과를 개선할 방안을 찾는다!
파이썬 가이드 자료 공유에 대한 문의가 많아 깃허브를 만들었습니다. 아래 링크로 가이드 파일을 확인해주세요. https://github.com/lucy-the-marketer/k-means-clustering
도움이 되셨다면 댓글 하나 써주시면 감사하겠습니다 🙂
[python] 자연어처리(NLP) – Kmeans, K대푯값 군집 분석
반응형
안녕하세요! 오늘은 텍스트 군집분석을 진행해보고자 합니다.
군집분석은 여러 문서들이 있을 때 유사한 텍스트끼리 그룹화하는 분석을 말합니다.
그중에서도 오늘은 분할 군집분석을 진행해 보겠습니다.
분할 군집 분석은 데이터를 k개의 그룹으로 나누어 주는 것을 말하는데 k개는 분석하는 사람에 따라 지정되는 숫자입니다. 연구자가 주관적으로 데이터 내에서 2개의 그룹으로 나누거나 3개의 그룹으로 나누어 겠다라고 결정하면 그 그룹 숫자에 따라 데이터들이 군집화 됩니다.
K-평균 군집 분석(K-means)
K-means (K-평균 군집 분석) 알고리즘은 아래의 사진으로쉽게 이해가 가능합니다.
위의 사진을 만들어 준비해 보았는데 이해가 잘 가시나요? ㅎㅎ
이제는 군집분석을 파이썬으로 구현하여 보겠습니다.
우선 데이터를 준비해 주어야 하는데요
저는 네이버 api를 이용해 뉴스 제목, 요약, 링크 등을 크롤링 하여 준비해 보았습니다.
검색어는 ‘크리스마스’ , ‘쇼미더머니’ , ‘SK하이닉스’ 이렇게 3개의 키워드로 검색된 내용을 데이터프레임으로 만들었습니다.
각각 15기사씩 총 45개의 기사가 있습니다.
데이터 파일 준비
clustering_ex.csv 0.02MB
필요한 모듈 설치
sklearn 설치
pip install sklearn
c_konlpy 설치(커스텀 할 수 있는 형태소분석기, 사전에 konlpy설치 후 ckonlpy설치)
git clone https://github.com/lovit/customized_konlpy.git
pip install customized_konlpy
pyclustering 설치
pip install pyclustering
코드
import pandas as pd from sklearn.feature_extraction.text import CountVectorizer from sklearn.cluster import KMeans from pyclustering.cluster import kmedoids from ckonlpy.tag import Twitter twitter = Twitter() #데이터 불러오기 df = pd.read_csv(‘clustering_ex.csv’) print(df.head())
출력:
준비한 데이터셋을 보면 요약 부분에 태그 등이 남아 있어 제거 한 후 분석을 진행해 보도록 하겠습니다.
# 텍스트 전처리 import re desc = df[‘요약’] for i in range(len(desc)): desc[i] = re.sub(‘(||”)’,”,desc[i]) print(desc)
출력:
위와 같이 태그가 깔끔하게 없어진 것을 확인해 볼 수 있습니다.
이번 군집 분석에는 요약부분을 사용하여 분석해보도록 하겠습니다.
각 텍스트의 형태소 분석을 ckonlpy로 진행해줍니다. ckonlpy에서 검색키워드였던 크리스마스, 쇼미더머니, sk하이닉스를 명사로 추가해 줍니다. 다른 명사를 추가하고 싶다면 [] 안에 추가하면 됩니다.
분석 후 명사가 추출된 문장을 띄어쓰기로 구분하여 기사당 한 문장으로 만들어 줍니다.
contents = [] # 형태소 분석, 명사만 추출 twitter.add_dictionary([‘크리스마스’,’쇼미더머니’,’SK하이닉스’],’Noun’) for i in desc: contents.append(twitter.nouns(i)) text = [‘ ‘.join(contents[i]) for i in range(len(contents))] print(text)
출력:
그 후 문장 벡터화를 하여 분석할 수 있는 형태로 텍스트를 바꾸어 줍니다.
#문장 벡터화 vectorize = CountVectorizer() x = vectorize.fit_transform(text)
이렇게 준비가 되었으면 평균 군집 분석을 진행해 줍니다.
데이터 셋이 3개의 키워드로 검색후 만든 파일이기 때문에 k=3으로 설정하여 진행해 보도록 하겠습니다.
######### 평균 군집 분석 ########### #데이터 프레임 생성 (문장 단어 매트릭스 만들기) new_df = pd.DataFrame(x.toarray(), columns=vectorize.get_feature_names_out()) # K- 평균 군집 분석 kmeans = KMeans(n_clusters=3).fit(new_df) print(‘[K-평균 군집 분석 결과]’) print(‘###########################################’) print(kmeans.labels_)
출력:
아까의 문장들이 k=3이라고 했기 때문에 0,1,2의 3 그룹 중 하나로 배정되었음을 확인할 수 있습니다.
K-대푯값 군집 분석
위의 데이터를 가지고 이번에는 대푯값 군집 분석을 진행하겠습니다.
k-대푯값은 보통 데이터들 중 어느 한 값만 매우 높거나 매우 작을때 평균값이 그 데이터들을 대표하지 못할 때 평균 아닌 다른 방법으로 중심값을 찾아야 할 때 쓰는 방법입니다.
숫자로 예를 들자면
[1,2,3,4,5,6,100] 이라는 데이터가 있을 때위 숫자들의 평균은 (1+2+3+4+5+6+100)/7 =17.28… 이 되는데, 이 평균이 숫자들의 값을 대표한다고 보기 어렵습니다.
이 때 중앙값인 4를 대푯값으로 정하는 등의 다른 방법이 필요하게 됩니다.
텍스트도 평균 값이 아닌 대푯값을 정하여 군집 분석을 진행해 보도록 하겠습니다.
초기 대푯값으로는 각 키워드의 기사들 중 임의의 기사를 1개씩 선정하여 initial_index_medoids에 세팅해 주었습니다.
######### k-대푯값 군집 분석 ########### #인스턴스 생성 kmedoids_ins = kmedoids.kmedoids(new_df.values,initial_index_medoids=[4,18,36]) # initial_index는 df행 중 대푯값 행 지정 kmedoids_ins.process() clusters = kmedoids_ins.get_clusters() print(‘###########################################’) print(‘[K-대푯값 군집 분석 결과]’) print(clusters)
출력:
각각 []로 3개의 군집으로 나누어졌음을 확인할 수 있습니다.
이번 텍스트에서는 k대푯값보다 kmeans가 더 분석이 잘 되었네요. 다른 텍스트로도 한 번 진행해 보시고 분석 목적에 맞는 방법을 선택해서 진행하면 됩니다 ㅎㅎ
전체코드
import pandas as pd from sklearn.feature_extraction.text import CountVectorizer from sklearn.cluster import KMeans from pyclustering.cluster import kmedoids from ckonlpy.tag import Twitter twitter = Twitter() #데이터 불러오기 df = pd.read_csv(‘clustering_ex.csv’) print(df.head()) # 텍스트 전처리 import re desc = df[‘요약’] for i in range(len(desc)): desc[i] = re.sub(‘(||”)’,”,desc[i]) #print(desc) contents = [] # 형태소 분석, 명사만 추출 twitter.add_dictionary([‘크리스마스’,’쇼미더머니’,’SK하이닉스’],’Noun’) for i in desc: contents.append(twitter.nouns(i)) #print(contents) text = [‘ ‘.join(contents[i]) for i in range(len(contents))] print(text) #문장 벡터화 vectorize = CountVectorizer() x = vectorize.fit_transform(text) ######### 평균 군집 분석 ########### #데이터 프레임 생성 (문장 단어 매트릭스 만들기) new_df = pd.DataFrame(x.toarray(), columns=vectorize.get_feature_names_out()) # K- 평균 군집 분석 kmeans = KMeans(n_clusters=3).fit(new_df) print(‘[K-평균 군집 분석 결과]’) print(‘###########################################’) print(kmeans.labels_) ######### k-대푯값 군집 분석 ########### #인스턴스 생성 kmedoids_ins = kmedoids.kmedoids(new_df.values,initial_index_medoids=[4,18,36]) # initial_index는 df행 중 대푯값 행 지정 kmedoids_ins.process() clusters = kmedoids_ins.get_clusters() print(‘###########################################’) print(‘[K-대푯값 군집 분석 결과]’) print(clusters)
참고자료
책- 「잡아라 텍스트 마이닝 with 파이썬」
보너스
PCA (주성분 분석)으로 군집 시각화하기
PCA(Principal component analysis)는 간단하게 말해 고차원의 데이터를 저차원의 데이터로 바꾸는 방법입니다.
여러 변수가 있으면 그 것을 융합해 주성분을 뽑아내어 그것을 새로운 변수로 만들어내는 방법입니다.여기서는 텍스트를 2차원으로 축소 후 결과를 시각화하여 보겠습니다.
#pca(주성분 분석)으로 시각화하기 from sklearn.decomposition import PCA import matplotlib.pyplot as plt pca = PCA(n_components=2) # 2차원으로 축소 pc = pca.fit_transform(new_df) p_df = pd.DataFrame(data=pc, columns=[‘main1’, ‘main2’]) p_df.index=df[‘검색어’] plt.scatter(p_df.iloc[kmeans.labels_ == 0,0], p_df.iloc[kmeans.labels_ == 0,1], s = 10, c = ‘red’, label = ‘clustering1’) plt.scatter(p_df.iloc[kmeans.labels_ == 1,0], p_df.iloc[kmeans.labels_ == 1,1], s = 10, c = ‘blue’, label = ‘clustering2’) plt.scatter(p_df.iloc[kmeans.labels_ == 2,0], p_df.iloc[kmeans.labels_ == 2,1], s = 10, c = ‘green’, label = ‘clustering3’) plt.legend() plt.show()
주성분 분석에 대해 더 알아보고 싶은 분은 아래의 링크를 참고해 주세요 🙂
전체 코드 파일
text_clustering.py 0.00MB
반응형
14 장 군집분석
import pandas as pd pandaspd import numpy as np numpynp import matplotlib.pyplot as plt matplotlib.pyplotplt # K-Means 알고리즘 from sklearn.cluster import KMeans, MiniBatchKMeans sklearn.clusterKMeans, MiniBatchKMeans from sklearn.datasets import load_iris sklearn.datasetsload_iris from sklearn.model_selection import train_test_split sklearn.model_selectiontrain_test_split # CLustering 알고리즘의 성능 평가 측도 from sklearn.metrics import homogeneity_score, \ sklearn.metricshomogeneity_score, \ completeness_score, v_measure_score, \ adjusted_rand_score, silhouette_score, rand_score calinski_harabasz_score from sklearn.metrics.cluster import contingency_matrix sklearn.metrics.clustercontingency_matrix from sklearn.preprocessing import StandardScaler # 변수 표준화 sklearn.preprocessingStandardScaler from sklearn import metrics sklearnmetrics # iris data = load_iris() irisload_iris() X = iris.data iris.data y = iris.target iris.target # 변수 표준화 = StandardScaler() # 변수 표준화 클래스 scalerStandardScaler() # 표준화를 위해 변수별 파라미터(평균, 표준편차) 계산 scaler.fit(X) # scaler.mean_, scaler.scale_ = scaler.transform(X) # 훈련자료 표준화 변환 X_stdscaler.transform(X)
11. K-Means 클러스터링(Clustering, 군집화)에 대해서 알아보자 with Python
이번 포스팅에서는 클러스터링(Clustering, 군집화)의 대표적인 알고리즘 중에 하나로 K-Means 클러스터링에 대해서 알아보려고 한다. 여기서 다루는 내용은 다음과 같다.
1. K-Means 클러스터링(Clustering, 군집화)이란?
2. K-Means 클러스터링(Clustering, 군집화) 알고리즘
3. K-Means 클러스터링(Clustering, 군집화) 장단점
4. K-Means 클러스터링(Clustering, 군집화) 파이썬 구현
본 포스팅에서는 수식을 포함하고 있습니다.
티스토리 피드에서는 수식이 제대로 표시되지 않을 수 있으니
PC 웹 브라우저 또는 모바일 웹 브라우저에서 보시기 바랍니다.
1. K-Means 클러스터링(Clustering, 군집화)이란?
– 정의 –
K-Means 클러스터링은 비지도 학습 알고리즘으로 사전에 클러스터 개수 $k$와 초기값을 입력하면 각 데이터의 그룹을 할당해 나가는 Hard Clustering 알고리즘이다.
이 말의 뜻을 하나씩 살펴보자.
a. K-Means 클러스터링은 비지도 학습이다.
K-Means 클러스터링 알고리즘은 데이터에 라벨(Label)이 없고 데이터의 유사도를 바탕으로 개별 데이터를 그룹에 할당하는(라벨을 만들어내는) 비지도 학습이다.
b. K-Means 클러스터링 알고리즘은 사전에 클러스터 개수와 초기값을 지정해야 한다.
K-Means 클러스터링 알고리즘이 데이터를 보고 자동으로 클러스터 개수를 파악하여 그룹화해주는 것은 아니다. 반드시 클러스터 개수를 지정해줘야 한다.
클러스터 개수를 지정했으면 그 개수만큼의 값을 초기값으로 선정해야 한다. 아래 그림과 같이 클러스터 개수를 3으로 정했다면 초기값도 적절하게 3개값을 정한다. 이때 초기값은 직접 지정해도 되고 랜덤 샘플링을 통하여 지정할 수도 있다.
c. K-Means 클러스터링은 그룹을 할당해 나가는 알고리즘이다.
앞에서 얘기한 초기값은 각 그룹의 초기 중심점이라는 의미이다. 이때 각 중심점은 그룹을 결정하며 개별 데이터는 자기와 가까운 중심점과 같은 그룹으로 할당된다. 이때 한 번에 종료되는 것은 아니고(물론 데이터 형태에 따라 또는 운이 좋으면 한번에 끝날 수 있다) 그룹의 중심점을 업데이트하고 다시 개별 데이터의 그룹을 할당하는 과정을 반복하게 된다.
d. K-Means 클러스터링은 Hard Clustering 알고리즘이다.
Hard Clustering이란 데이터 포인트들의 그룹이 중심에 가까운 점에 무조건적으로 할당하는 군집화라는 뜻이다. 어찌보면 그럴듯하지만 논란이 있다. 왜 그럴까?
아래 2 그림에서 검은점을 빨간 그룹과 파란 그룹 중에서 어느 그룹에 할당해야할지를 생각해보자.
왼쪽의 경우 검은점은 빨간 그룹이라고 아주 강하게 말할 수 있을 것이다. 따라서 검은점을 빨간 그룹에 할당시키는 것이 당연할 것이다. 하지만 오른쪽의 경우는 어떤가? 빨간쪽에 가깝다고 하지만 파란쪽 중심으로 부터 생성된 데이터가 아니라고 하기엔 무리가 있다. 이때에는 검은점이 빨간쪽에서 60%, 파란쪽에서 40%정도의 가능성을 갖고 나왔다고 얘기하는 것이 더 합리적일 것이다. 하지만 K-Means 클러스터링은 이러한 가능성은 생각하지 않고 무조건 가까운 쪽으로 그룹을 할당하는 Hard Clustering 알고리즘이다.
– 궁금 사항 –
여기서 궁금한 사항이 생길 수 있다.
클러스터 개수는 어떻게 정하면 좋을까?
클러스터링이 얼마나 잘되었는지를 정량화한 지표를 이용한다. 그러고 나서 클러스터 개수 후보를 정하고 각 클러스터 개수에 대하여 클러스터링을 수행한 뒤 지표를 계산한다.
이때 지표값을 최적화하는 클러스터링 개수를 최적 클러스터 개수로 선정한다.
자주 활용되는 지표로 Dunn Index, 실루엣(Silhouette) Index 등이 있는데 이에 대해선 다음 포스팅에서 소개하겠다.
반응형
2. K-Means 클러스터링 (Clustering, 군집화) 알고리즘
이번엔 K-Means 클러스터링(군집화) 알고리즘은 다음과 같다.
K-Means 클러스터링 알고리즘
(1) 클러스터 개수 $K$, $\epsilon > 0$ 그리고 최대 반복수 $L$을 설정한다.
(2) 초기값(초기 중심값) $\mu_j^{(0)}, j=1, \ldots, K$을 계산한다. 초기값은 직접 설정해주거나 데이터 포인트에서 클러스터 개수만큼 비 복원 추출할 수도 있다.
(3) $t$번째 스텝에서의 중심값을 $\mu_j^{(t)}, j=1, \ldots, K$라 하자. 이제 개별 데이터에 그룹을 할당한다. 이때 개별 데이터와 각 중심값과의 거리를 계산하고 최소 거리를 갖는 중심값을 그룹으로 정한다. 이때 거리는 유클리디안 거리(Euclidean Distance)를 사용한다. 즉,
$$ \DeclareMathOperator*{\argminA}{argmin} k = \argminA_{j=1, \ldots, K}\|x_n-\mu_j^{(t)} \|$$라 한다면 개별 데이터 $x_n$의 그룹은 $k$가 되는 것이다.
(4) 중심값을 업데이트한다. $r_{nk}$를 $x_n$의 그룹이 $k$라면 1, 아닌 경우 0의 값을 갖는다고 하자. 이때 $t+1$번째 중심값은 다음과 같이 업데이트된다.
$$\mu_k^{(t+1)} = \frac{\sum_{i=1}^nr_{ik}x_i}{\sum_{i=1}^nr_{ik}}$$
위식은 결국 각 그룹에서의 평균값을 다음 스텝의 중심값으로 업데이트됨을 의미한다.
(5) 만약 $t>L$ 또는 $\|\mu_k^{(t+1)}-\mu_k^{(t)} \|<\epsilon$이면 알고리즘을 종료하고 아닌 경우에는 (3)으로 돌아간다. 3. K-Means 클러스터링 (Clustering, 군집화) 알고리즘의 장단점 - 장점 - (1) 직관적이고 구현이 쉽다. 알고리즘이 돌아가는 과정이 직관적이고 이해가 쉽다. (2) 구현이 굉장히 쉽다. 알고리즘이 단순하여 구현하기가 쉽다. (3) 대용량 데이터에 적용 가능하다. 복잡한 계산이 필요하지 않아 대용량 데이터에도 적용 가능하다. (4) 수렴성이 보장된다. K-Means 알고리즘은 수렴성이 보장된다. - 단점 - (1) 초기값에 민감하다. 초기값에 따라서 결과가 매우 달라질 수 있다. (2) 이상치에 영향을 받는다. 거리를 Euclidean Distance를 기반으로 하기 때문에 중심값을 업데이트하는 과정에서 이상치에 영향을 받을 수 있다. (3) 그룹 내 분산 구조를 반영할 수 없다. 거리를 Euclidean Distance를 기반으로 하기 때문에 그룹 내 분산 구조를 제대로 반영할 수 없다. 아래 왼쪽 그림은 세개의 분산 구조를 갖는 클러스터를 나타낸 것이다. 우리가 원하는 것은 이러한 분산 구조를 반영한 타원 형태의 클러스터링(군집화) 결과이다. 하지만 K-Means를 실제로 돌려보면 Euclidean Distance의 영향으로 타원 구조가 아닌 원형 구조의 클러스터링 결과를 얻게 된다. (4) 차원의 저주에 걸릴 수 있다. 고차원으로 갈수록 개별 데이터 간 거리가 가까워져 클러스터링 효과가 없을 수 있다. 이는 군집간에는 거리를 최대한 떨어뜨려놔야 클러스터링을 하는 의미가 있는데 고차원으로 갈 수록 개별 데이터간 거리가 가까워져 이러한 효과를 볼 수 없다는 뜻이다. (5) 클러스터의 개수를 정해야 한다. K-Means 클러스터링은 클러스터 개수를 자동으로 잡아주지 않고 사전에 정해줘야 한다. 하지만 Dunn Index, 실루엣(Silhouette) Index과 같은 지표를 이용하여 최적 클러스터 개수를 정할 수 있다. (6) 범주형 변수가 있다면 K-Means 클러스터링을 할 수 없다. K-Means 클러스터링(군집화) 알고리즘은 Euclidean Distance를 사용하기 때문에 범주형 변수가 있다면 적용할 수 없다. 이때에는 K-Means 클러스터링(군집화) 알고리즘을 확장한 K-Modes Clustering 알고리즘을 이용하면 클러스터링(군집화)가 가능하다고 한다. 이와 관련된 내용도 추후에 포스팅 해봐야겠다. 반응형 4. K-Means 클러스터링(Clustering, 군집 분석) 파이썬 구현 먼저 샘플용 데이터를 만들어보자. import numpy as np import random import matplotlib.pyplot as plt np.random.seed(100) num_data = 50 x11 = np.linspace(0.3,0.7,20) x12 = np.linspace(1.3,1.8,15) x13 = np.linspace(2.4,3,15) x1 = np.concatenate((x11,x12,x13),axis=None) error = np.random.normal(1,0.5,num_data) x2 = 1.5*x1+2+error fig = plt.figure(figsize=(7,7)) fig.set_facecolor('white') plt.scatter(x1, x2, color='k') plt.show() 샘플 데이터 딱 봐도 그룹이 3개로 나뉘는 데이터이다. 1) 직접 구현 클러스터링(군집화) 알고리즘을 직접 구현해보자. 아래 코드가 K-Means 클러스터링을 수행하는 함수이다. 이 함수는 데이터(X), 클러스터 개수(n_clusters), 초기 중심값(init_center), 최대 반복수(max_iter). 오차한계(epsilon) 마지막으로 random_state를 인자로 받는다. 이 함수는 초기 중심값을 세팅하고 각 스텝마다 라벨과 중심값을 업데이트한다. 최대 반복수만큼 반복되었거나 이전 스텝의 중심값과 다음 스텝 중심값의 차이가 오차 한계보다 작다면 알고리즘은 종료되며 최종 라벨(labels), 반복 스텝 수(iteration), 라벨 업데이트 과정(labels_history), 중심값 업데이트 과정(center_history)을 출력한다. def kmeans_clustering(X, n_clusters, init_center=None, max_iter=10, epsilon=1e-4, random_state=100): # inititalize centeroids if init_center is None: random.seed(random_state) idx = random.sample(range(X.shape[0]), n_clusters) center = X[idx,:] else: center = init_center iteration = 1 labels_history = [] # label history center_history = [] # centeroid history while(iteration<=max_iter): ## assign label labels = [] for i in range(X.shape[0]): data = X[i, :] labels.append(np.argmin([np.linalg.norm(data-x) for x in center])) labels = np.array(labels) ## update centeroids next_center = [] for i in range(n_clusters): target_idx = np.where(labels==i)[0] center_val = np.mean(X[target_idx,:], axis=0) next_center.append(center_val) next_center = np.array(next_center) if epsilon: if np.linalg.norm(next_center-center) <= epsilon: break center = next_center labels_history.append(labels) center_history.append(center) iteration += 1 return (labels, iteration, labels_history, center_history) 이제 이 함수를 이용하여 K-Means 클러스터링을 수행해보자. 클러스터 개수를 3개로 설정하고 초기 중심값을 지정해주었다. X = np.stack([x1, x2], axis=1) init_center= np.array([[2,4],[1,5],[2.5,6]]) max_iter=50 epsilon=1e-10 random_state=101 n_clusters=3 results = kmeans_clustering(X, n_clusters, init_center, max_iter, epsilon=1e-4, random_state=100) labels = results[0] 이제 군집화가 잘되었는지 확인해보자. fig = plt.figure(figsize=(7,7)) fig.set_facecolor('white') for i, label in enumerate(labels): if label == 0: color = 'blue' elif label ==1: color = 'red' else: color = 'green' plt.scatter(X[i,0],X[i,1], color=color) plt.xlabel('x1') plt.ylabel('x2') plt.show() K-Means 클러스터링 결과 클러스터링(군집화)이 아주 잘되었다. 이번엔 업데이트 진행과정을 살펴보자. labels_history = results[2] for j, labels in enumerate(labels_history): fig = plt.figure(figsize=(7,7)) fig.set_facecolor('white') for i, label in enumerate(labels): if label == 0: color = 'blue' elif label ==1: color = 'red' else: color = 'green' plt.scatter(X[i,0],X[i,1], color=color) plt.title(f'Iteration : {j+1}') plt.xlabel('x1') plt.ylabel('x2') plt.show() K-Means 클러스터링 업데이트 과정 알고리즘 4 스텝만에 클러스터링이 완료된 것을 알 수 있다. 2) Scikit-Learn 이용 이번에는 Scikit-Learn 패키지를 이용하여 K-Means 클러스터링을 해보자. Scikit-Learn에서는 KMeans 클래스를 이용하여 클러스터링(군집화)을 수행한다. 이때 n_clusters는 3, init에는 초기 중심값 init_center를 넣고 KMeans 인스턴스를 생성한다. 그러고 나서 fit 함수에 클러스터링(군집화)하려고 하는 데이터(X)를 넣어주면 클러스터링(군집화)이 수행된다. 그리고 최종 라벨은 labels_ 필드를 이용하여 얻을 수 있다. import warnings warnings.filterwarnings('ignore') from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=3, init=init_center) kmeans.fit(X) labels = kmeans.labels_ 클러스터링(군집화)를 시각화해보자. fig = plt.figure(figsize=(7,7)) fig.set_facecolor('white') for i, label in enumerate(labels): if label == 0: color = 'blue' elif label ==1: color = 'red' else: color = 'green' plt.scatter(X[i,0],X[i,1], color=color) plt.xlabel('x1') plt.ylabel('x2') plt.show() Scikit-Learn을 이용한 K-Means 클러스터링 결과 이번 포스팅에서는 클러스터링(군집화)의 대표적인 알고리즘 K-Means 클러스터링을 알아보았다. 다음 포스팅에서는 클러스터링이 잘되었는지를 정량적으로 알아볼 수 있는 여러가지 지표들에 대해서 알아보려고 한다. 참고자료 문일철 - 인공지능 및 기계학습 개론2
키워드에 대한 정보 파이썬 군집 분석
다음은 Bing에서 파이썬 군집 분석 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.
이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!
사람들이 주제에 대해 자주 검색하는 키워드 [파이썬 실습] 군집분석
- 동영상
- 공유
- 카메라폰
- 동영상폰
- 무료
- 올리기
YouTube에서 파이썬 군집 분석 주제의 다른 동영상 보기
주제에 대한 기사를 시청해 주셔서 감사합니다 [파이썬 실습] 군집분석 | 파이썬 군집 분석, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.