일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- numpy
- 머신러닝
- 기초통계
- F분포
- 결정계수
- 오래간만에 글쓰네
- student t분포
- 군집화
- 자연어 처리
- 최소자승법
- Django
- Pandas
- rnn
- 은준아 화이팅
- 감성분석
- 다층 퍼셉트론
- 가설검정
- 회귀분석
- 밑바닥부터 시작하는 딥러닝
- 기술통계학
- word2vec
- 텐서플로2와 머신러닝으로 시작하는 자연어처리
- 차원축소
- 코사인 유사도
- 히스토그램
- 파이썬 pandas
- 텍스트 분류
- 모두의 딥러닝
- 구글 BERT의 정석
- 밑바닥부터 시작하는 딥러닝2
- Today
- Total
데이터 한 그릇
군집화 개요, k-평균 알고리즘 본문
- k-평균 알고리즘 이해
- 군집화 알고리즘 테스트 해보기
- 군집평가
k-평균 알고리즘 이해
k-평균 알고리즘은 군집화 데이터 분석을 할 때 가장 많이 사용되는 알고리즘 중 하나이다. 특정 지점을 임의로 선택하고 그 지점에 가까운 데이터들을 선택하는 군집화 기법이다. 처음에 임의로 지정되었던 군집 중심점은 첫 선택된 데이터들의 평균 중심지점을 계산하고 그곳으로 이동한다. 계속 이러한 과정을 반복하면서 더이상 군집 중심점의 이동이 없다면 데이터 학습을 마치게 된다.
k-평균은 알고리즘이 단순하고 간결하다는 장점을 가지고 있다. 반면에 군집화의 정확도가 떨어지고 반복을 수행하는 횟수가 많을수록 처리속도가 느리다는 단점도 존재한다.
from sklearn.preprocessing import scale
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
%matplotlib inline
iris = load_iris()
iris_df = pd.DataFrame(data = iris.data, columns=['sepal_length', 'sepal_width', 'petal_length', 'petal_width'])
파이썬 내장 데이터셋인 붓꽃 품종을 군집화시키려고 한다.
kmeans = KMeans(n_clusters = 3, init='k-means++', max_iter=300, random_state = 0)
kmeans.fit(iris_df)
print(kmeans.labels_)
kmean 군집화 객체를 만들고 n_cluster로 군집화 개수를 지정해준다. 이때 max_iter는 최대반복 횟수이며 300회이상 군집 중심점이 이동이 없을 시에는 모델 생성을 끝낸다는 의미를 가진다. 그리고 kmeans.labels_로 각 행의 데이터들이 어느 군집단에 속해있는지 확인한다.
iris_df['target'] = iris.target
iris_df['cluster'] = kmeans.labels_
iris_result = iris_df.groupby(['target','cluster'])['sepal_length'].count()
print(iris_result)
iris_df에 타겟 데이터와 클러스터 데이터를 삽입하고 그룹바이로 실태를 확인한다.
marker0_index = iris_df[iris_df['cluster']==0].index
marker1_index = iris_df[iris_df['cluster']==1].index
marker2_index = iris_df[iris_df['cluster']==2].index
군집이 0, 1, 2번인 행들을 각각 추출하여 marker_index에 저장한다.
from sklearn.decomposition import PCA
pca = PCA(n_components = 2)
pca_transformed = pca.fit_transform(iris.data)
iris_df['pca_x'] = pca_transformed[:,0]
iris_df['pca_y'] = pca_transformed[:,1]
그래프를 그리기 위해서 차원축소를 하여 두 개의 피처로 축소한다.
plt.scatter(x=iris_df.loc[marker0_index, 'pca_x'], y=iris_df.loc[marker0_index,'pca_y'], marker = 'o')
plt.scatter(x=iris_df.loc[marker1_index, 'pca_x'], y=iris_df.loc[marker1_index,'pca_y'], marker = 's')
plt.scatter(x=iris_df.loc[marker2_index, 'pca_x'], y=iris_df.loc[marker2_index,'pca_y'], marker = '^')
plt.xlabel('PCA_1')
plt.ylabel('PCA_2')
plt.title('3 Clusters Visualization by 2 PCA Component')
plt.savefig('cluster')
plt.show()
군집화 알고리즘 테스트 해보기
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
%matplotlib inline
make blobs는 개별 군집의 중심점과 표준 편차 제어 기능이 추가되어 있다. (make blobs는 대표적인 군집화용 데이터 생성기)
#n_samples = 데이터의 개수, n_features = 열의 개수, centers = 군집의 개수, 생성될 군집의 표준편차
X, y = make_blobs(n_samples=200, n_features=2,centers=3,cluster_std=0.8,random_state=0)
print(X.shape, y.shape)
unique, counts = np.unique(y, return_counts = True)
print(unique, counts)
n_samples로 200개의 데이터를 만들고 n_feature로 2개의 열을 만든다. centers를 통해서 중심점을 3개 만들기로 결정하고 표준편차는 0.8로 결정을 한다. 그 이후에 shape을 확인해보면 200, 2의 튜플형태가 반환이 된다. 그리고 y 타겟데이터는 200개로 (200,)의 튜플을 반환한다.
그 이후에 넘파이의 unique함수를 이용하여 레이블의 종류와 각 레이블의 개수를 확인할 수 있다.
import pandas as pd
clusterDF = pd.DataFrame(data = X, columns = ['feature_1','feature_2'])
clusterDF
clusterDF['target'] = y
clusterDF
앞서 만든 군집화용 데이터와 타겟 데이터를 이용하여 데이터 프레임을 만든다.
target_list = np.unique(y)
markers=['o','s','^','P','D','H','x']
for target in target_list:
cluster = clusterDF[clusterDF['target']==target]
plt.scatter(x=cluster['feature_1'],y=cluster['feature_2'], edgecolor='k', marker=markers[target])
plt.show()
만들어 놓은 데이터 프레임의 인덱스를 조작하여 그래프를 그려본다.
kmeans = KMeans(n_clusters = 3, init='k-means++', max_iter = 200, random_state = 0)
cluster_labels = kmeans.fit_predict(X)
clusterDF['kmeans_label'] = cluster_labels
kmeans 모델의 n_cluster를 통해서 몇 개의 군집으로 할지 서정한다. 그리고 200번 이상의 군집 중심점이 이동을 하지 않는다면 모델의 학습을 끝마친다. 학습이 끝난 이후에는 label들을 어떻게 분류했는지 cluster_labels에 저장하고 데이터 프레임에 추가한다.
#cluster_centers는 각 군집의 중심 좌표를 말해줌
centers = kmeans.cluster_centers_
centers[0][0]
cluster_centers_ 를 통해서 군집 중심점의 좌표를 확인할 수 있다. (x,y)좌표
markers = ['o','s','^','P','D','H','x']
unique_labels = np.unique(cluster_labels)
for label in unique_labels:
label_cluster = clusterDF[clusterDF['kmeans_label']==label]
center_x_y = centers[label]
plt.scatter(x=label_cluster['feature_1'],y = label_cluster['feature_2'], edgecolor = 'k', marker = markers[label])
#군집별 중심 위치 좌표 시각화
plt.scatter(x=center_x_y[0], y=center_x_y[1], s=200, color = 'white',
alpha = 0.9, edgecolor = 'k', marker = markers[label])
plt.scatter(x=center_x_y[0], y=center_x_y[1], s=70, color = 'k', edgecolor = 'k', marker='$%d$' % label)
넘파이의 unique함수를 통해서 분류된 레이블들의 종류를 파악한 이후 unique_labels에 집어 넣는다. 그리고 centers에는 각 군집의 중심 위치의 좌표가 리스트 형태로 들어가 있기 때문에 이 또한 for 문으로 끄집어 내준다. 그리고 scatter를 통해서 중심 위치를 나타낸다.
군집화 평가
앞서 붓꽃 데이터 같은 경우에는 따로 target 데이터를 가지고 있기 때문에, 군집화 된 것을 target 데이터와 비교하면서 모델의 성능을 평가할 수 있다. 하지만 대부분의 데이터가 target 데이터를 가지고 있지 않은 경우가 많다. 따라서 군집화를 평가할 새로운 방법이 필요한데 바로 "실루엣 분석" 이다.
실루엣 분석는 각 군집 간의 거리가 얼마나 효율적으로 분리돼 있는지를 나타낸다. 만일 효율적으로 잘 분리가 됐다면 "다른 군집과의 거리는 떨어져 있고, 동일 군집끼리의 데이터는 서로 가깝게 잘 뭉쳐 있다는 의미" 이다. 이때 실루엣 분석은 실루엣 계수를 기반을 평가하게 된다. (실루엣 계수 = 군집화 지표) 실루엣 계수는 같은 군집과는 얼마나 잘 밀집해 있는지를 나타내고 다른 군집과는 얼마나 멀리 분리돼 있는지를 나타낸다.
실루엣 계수는 -1에서 1사이의 값을 가지며 1로 가까울수록 근처의 군집과는 멀리 떨어져 있음을 이야기 한다. -1은 그 반대를 의미한다.
from sklearn.preprocessing import scale
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
%matplotlib inline
iris = load_iris()
feature_names = ['sepal_length','sepal_width','petal_length','petal_width']
iris_df = pd.DataFrame(data = iris.data, columns = feature_names)
kmeans = KMeans(n_clusters = 3, init = 'k-means++', max_iter = 300, random_state = 0)
kmeans.fit(iris_df)
iris_df['cluster'] = kmeans.labels_
iris_df
붓꽃 데이터를 가지고 앞의 과정을 다시 반복한다. 이때 사이킷런 metrics 에서 실루엣 샘플과 실루엣 스코어를 임포트 해야한다.
#아이리스의 모든 개별 데이터에 실루엣 계수 값을 구함
#silhouette_samples() 를 통해서 각 데이터의 실루엣 계수를 구함
score_samples = silhouette_samples(iris.data, iris_df['cluster'])
print('silhouette_samples() return 값의 shape', score_samples.shape)
iris_df['silhouette_coeff'] = score_samples
#모든 데이터의 평균 실루엣 계수를 구하기
#silhouette_score()를 통해서 평균 계수를 구하기
average_score = silhouette_score(iris.data, iris_df['cluster'])
np.round(average_score,3)
silhouette_samples를 통해서 각 데이터의 실루엣 계수를 구하고 그 shape를 확인한다. 그리고 silhouette_score를 통해서 평균 데이터 실루엣 계수를 구한다. 파라미터 값은 데이터 값과 분류 클러스터를 집어 넣는다.
#cluster별 평균 실루엣 계수 보기
#0은 평균보다 적고 1은 평균보다 크고 2는 평균보다 작다
iris_df.groupby('cluster')['silhouette_coeff'].mean()
그룹바이를 통해서 전체 평균이 아니라 각 레이블마다의 실루엣 계수의 평균을 구할 수 있다.
pca = PCA(n_components = 2)
a = pca.fit_transform(iris.data)
pca_df = pd.DataFrame(data = a, columns = ['feat1','feat2'])
kmeans = KMeans(n_clusters = 3, init='k-means++', max_iter = 300, random_state = 1)
kmeans.fit(pca_df)
pca_df['cluster'] = kmeans.labels_
np.unique(pca_df['cluster'])
label_list = [0,1,2]
markers = ['o','s','^']
for cluster in label_list:
plt.scatter(x=pca_df[pca_df['cluster']==cluster]['feat1'], y = pca_df[pca_df['cluster']==cluster]['feat2'], edgecolor='k',
marker=markers[cluster])
그래프로 눈에 잘 나타나게 시각화 하기 위해서 차원 축소를 감행하고, 앞전과 같은 과정을 다시 반복핟나.
'머신러닝 > 군집화' 카테고리의 다른 글
Customer Personality Analysis (0) | 2021.12.08 |
---|---|
군집화)평균 이동 (0) | 2021.05.26 |
군집화)DBSCAN 군집화 (0) | 2021.05.25 |
군집화) GMM(Gaussian Mixture Model) (0) | 2021.05.21 |