Kmeans Clustering은 Unsupervised learning에 속하는 분류 기법으로 데이터와 그룹의 갯수(K)를 지정하면 알아서 데이터를 분류해줍니다. 간단하고 아주 빠르고 (주어진 데이터 기준으로) 잘 분류해주기 때문에 많이 사용하며 사랑 받는 기법 중 하나입니다. 다만 k를 결정하는데 있어서 어떻게 나눠야할지는 수치적으로 명확하게 정의되지 않기 때문에 분석자의 주관이 다소 들어가는 부분이 있습니다.
그럼 간단하게 kmeans Clustering을 수행해보겠습니다. 사용할 예제는 유명한 iris 데이터입니다.
# package를 가져옵니다.
from sklearn.cluster import KMeans
import numpy as np
from sklearn.datasets import load_iris
import pandas as pd
# iris 데이터를 가져옵니다.
iris_ds = load_iris()
sklearn에는 다양한 샘플 데이터를 가지고 있는데 포함된 iris 데이터는 다음과 같은 구조를 가지고 있습니다.
보통은 data frame으로 많이 다루기 때문에 이 데이터를 data frame으로 변환합니다.
X = iris_ds.data
Y = iris_ds.target
# dataframe으로 전환하고 concat()함수를 활용하여 하나의 dataframe으로 합칩니다.
iris = pd.concat([pd.DataFrame(X), pd.DataFrame(Y)], axis=1)
iris.columns = ['SepalLength','SepalWidth','PetalLength','PetalWidth','Species']
iris.head()
pandas의 concat() 함수는 R에서 rbind()와 cbind()의 기능을 수행합니다. Species의 값들이 0,1,2로 종이 분류되어있습니다. pandas.replace() 함수를 사용하여 각각 종의 명칭을 부여합니다.
# 각각의 그룹값을 종명칭으로 대체합니다.
iris = iris.replace({'Species':0}, {'Species':'setosa'})
iris = iris.replace({'Species':1}, {'Species':'versicolor'})
iris = iris.replace({'Species':2}, {'Species':'virginica'})
먼저 간단하게 데이터 현황을 산점도로 출력하여 봅시다.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
for name, group in iris.groupby('Species'):
ax.scatter(group.SepalLength, group.SepalWidth, marker='o', label=name)
ax.legend(fontsize=10, loc='lower right')
fig, ax = plt.subplots()
for name, group in iris.groupby('Species'):
ax.scatter(group.PetalLength, group.PetalWidth, marker='o', label=name)
ax.legend(fontsize=10, loc='lower right')
각 축의 기준에 된 SepalLength, SepalWidth 기준에서는 setosa는 눈으로 봐도 잘 분류됩니다만 나머지 두 종 versicolor와 virginica는 혼합된 것을 볼 수 있습니다. PetalLength, PetalWidth 기준에서는 3종이 모두 잘 분류되어 보이는 것을 확인 할 수 있습니다. 일단은 4개의 지표를 활용하여 Kmeans를 실행합니다.
kmeans = KMeans(n_clusters=3, random_state=0).fit(iris[['SepalLength','SepalWidth','PetalLength','PetalWidth']])
iris_fit = pd.concat([iris, pd.DataFrame(kmeans.labels_)], axis=1)
iris_fit.columns = ['SepalLength','SepalWidth','PetalLength','PetalWidth','Species', 'KmeansFit']
kmeans Clustering 결과는 각 그룹에 대한 번호가 나옵니다만 해당 번호가 어떤 종을 지칭하는지는 알 수가 없습니다. 위에서 했던 방법과 동일하게 Kmeans Clustering 결과도 하나의 테이블로 합칩니다. 종 분류 결과도 종명칭을 부여합니다. 정말 잘 분류 되었는지 교차테이블을 만들어서 확인해봅시다.
pd.crosstab(iris_fit.Species, iris_fit.KmeansFit)
결과를 보면 setosa는 모두 50개 하나의 그룹으로 분류가 되었지만 versicolo는 2개가, virginica는 14개가 오분류된 것을 확인할 수 있습니다. 앞서 scatter plot으로 확인한 바와 같이 PetalLength, PetalWidth만 선택하여 KmeansClustering을 수행합니다.
kmeans2 = KMeans(n_clusters=3, random_state=0).fit(iris[['PetalLength','PetalWidth']])
iris_fit2 = pd.concat([iris, pd.DataFrame(kmeans2.labels_)], axis=1)
iris_fit2.columns = ['SepalLength','SepalWidth','PetalLength','PetalWidth','Species', 'KmeansFit']
pd.crosstab(iris_fit2.Species, iris_fit2.KmeansFit)
setosa는 50개 모두 분류되었으며 versicolor는 2개, virginica는 4개가 오분류 되었습니다. 앞서 진행했던 결과보다 더 좋은 결과를 확인 할 수 있습니다. KmeansClustering은 간단하고 사용하기가 쉬워 많이 사용들 하지만 투입되는 데이터(지표)를 어떻게 만들고 어떤 것을 선택하느냐에 따라 분류율의 변화가 생깁니다. 실무에서도 이를 적용하기 위해 데이터를 만드는 과정을 꽤 오랫동안 거치게 되는데 이 과정에서 데이터를 얼마나 잘 다듬고 정교화하느냐에 따라 결과가 판이하게 달라집니다.
'Data Analysis > Python' 카테고리의 다른 글
[Python] 업무자동화 - 1 : Python으로 Naver 이메일 보내기 (0) | 2020.07.17 |
---|---|
[Python] 정규성 검정 (2) | 2020.01.27 |
[Python] 다중 회귀 분석(Multiple Linear Regression) (0) | 2019.05.19 |
Python : Data Handling(수정) (0) | 2015.12.10 |
[Python] jdbc로 Database(Oracle) 접근하기 (2) | 2015.12.03 |
댓글