BASEMENT
K - means 본문
K-평균 알고리즘 (K-means algorithm)
1. 개념
- 주어진 데이터를 K개의 클러스터로 묶는 알고리즘으로, 각 클러스터와 거리 차이의 분산을 최소화하는 방법
- label이 없는 입력 데이터에 label을 달아주는 역할을 수행함
- 각 군집 중심의 위치, 각 개체가 어떤 군집에 속해야 하는지 EM 알고리즘을 사용함
- 데이터 분류, 클러스터링 / 성향이 불분명한 시장 분석 / 패턴인식, 음성인식 / 관련성 파악 등
- K 는 데이터 세트에서 찾을 것으로 예상되는 클러스터(그룹) 수
- Means 는 각 데이터로부터 그 데이터가 속한 클러스터의 중심까지의 평균 거리
1) 장점
- 간단한 알고리즘으로 대규모에도 적용 가능 (계산시간이 짧음)
- 데이터에 대한 사전정보가 필요 없음 (특정 변수에 대한 역할 정의가 필요 없음)
2) 단점
- K의 개수를 정하기가 어려움
- 정답이 없기 때문에 단순정확도(Accuracy)등 지표로 평가할 수 없음
- 결과해석이 어려움 (분석결과가 관찰치 사이의 거리 또는 유사성을 어떻게 정의하느냐에 따라 좌우됨)
- 초기 클러스터링 개수 선정 (군집의 크기, 밀도에 따라 결과가 제대로 작동하지 않음)
=> K-Means : 데이터가 확실한 경우에만 사용하는 것이 좋음
2. 과정
1) 초기 K 평균값은 데이터 오브젝트 중 무작위로 선택됨
2) K 각 데이터 오브젝트들은 가장 가까이 있는 평균값을 기준으로 묶이고, 평균값을 기준으로 분할된 영역은 다이어그램으로 표시
3) K개의 클러스터의 중심점 기준으로 평균값이 재조정됨
4) 수렴할 때까지 2, 3 과정을 반복함
3. K-Means 결과 측정 및 평가
1) SSE (Sum of Squared Error)
- K-Means는 클러스터 내 SSE (오차제곱합)이 최소가 되도록 클러스터의 중심을 결정함
- 관측치와 중심점 사이의 거리를 계산하여 elbow point를 정함
2) Silhouette 통계랑
- 군집의 정확도 평가
- a(i)는 i번째 개체와 같은 군집에 속한 요소들 간 거리들의 평균
- b(i)는 i번째 개체와 다른 군집에 속한 요소들 간 거리들의 평균
- -1 ~ 1 사이의 값
=> 0.5 이상일 경우 잘 분류된 것
4. K-Means 사용
from sklearn.cluster import KMeans
model = KMeans(n_clusters=k)
model.fit(data)
model.predict(samples)
model.inertia_
- inertia_ : 응집도(얼마나 퍼져있는지/뭉쳐있는지) 확인. 값이 낮을수록 군집화가 더 잘됨
5. K-Means 예제
1)
import numpy as np
from sklearn.cluster import KMeans
x_data =np.array([
[2,1],
[3,2],
[3,4],
[6,5],
[7,5],
[2,5],
[9,2],
[6,3],
[2,5]
])
from sklearn.metrics import accuracy_score
y_data = np.array([1,1,2,0,0,2,1,0,2])
model = KMeans(n_clusters=3, random_state=4)
model.fit(x_data)
print(model.labels_)
print("정확도: {:.2f}".format(accuracy_score(y_data, model.labels_)))
import pandas as pd
x_data = pd.DataFrame(x_data, columns=['x','y'])
print(x_data)
x_data['cluster'] = model.labels_
print(x_data)
import seaborn as sns
sns.lmplot('x', 'y', data=x_data, fit_reg=False, scatter_kws={"s":200}, hue="cluster")
2)
import random
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
%matplotlib inline
random.seed(42)
X = -2 * np.random.rand(100,2)
X1 = 1 + 2 * np.random.rand(50,2)
X[50:100, :] = X1
plt.scatter(X[:,0], X[:,1], s=50, c='b')
plt.show()
Kmean = KMeans(n_clusters=2)
Kmean.fit(X)
# SSE : elbow point - k개수 결정
ks = range(1,10)
inertias = []
for k in ks:
model = KMeans(n_clusters=k)
model.fit(X)
inertias.append(model.inertia_)
# Plot ks vs inertias
plt.plot(ks, inertias, '-o')
plt.xlabel('number of clusters, k')
plt.ylabel('inertia')
plt.xticks(ks)
plt.show() # k=2 일때 적합
# 센터 포인트(중앙값) 찾기
Kmean.cluster_centers_
# 중앙값 그래프에 나타내기
plt.scatter(X[:,0], X[:,1], s=50, c='b')
plt.scatter(-1.06937451, -0.9992503, s=200, c='r', marker='s')
plt.scatter(2.00546486, 2.03616281, s=200, c='g', marker='s')
plt.show()
3) iris 데이터
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris['feature_names'])
data = X[['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)']]
# SSE
sse = {}
for k in range(1,10):
kmeans = KMeans(n_clusters=k, max_iter=1000).fit(data)
data["clusters"] = kmeans.labels_
sse[k] = kmeans.inertia_
plt.figure()
plt.plot(list(sse.keys()), list(sse.values()))
plt.xlabel("Number of cluster")
plt.ylabel("SSE")
plt.show()
# silhouette : 군집 정확도 평가
from sklearn.metrics import silhouette_score
for n_cluster in range(2, 11):
kmeans = KMeans(n_clusters=n_cluster).fit(data)
label = kmeans.labels_
sil_coeff = silhouette_score(X, label, metric='euclidean')
print("For n_clusters={}, The Silhouette Coefficient is {}".format(n_cluster, sil_coeff))
'Programming > Machine Learning' 카테고리의 다른 글
군집화 (0) | 2020.10.10 |
---|---|
랜덤포레스트 (Random Forest) (0) | 2020.10.10 |
의사결정트리 (0) | 2020.10.10 |
SVM, SVR (0) | 2020.10.05 |
Naive Bayes (나이브 베이즈) (0) | 2020.10.05 |