import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
import numpy as np
# # 隨機產生 10 組 2 features 的資料 500 筆 (dy 即原始目標值 label 0~9)
# dx, dy = make_blobs(n_samples=500, n_features=2, centers=1, random_state=42)
#
# # 用 KMeans 在資料中找出 5 個分組
# kmeans = KMeans(n_clusters=7)
# kmeans.fit(dx)
# # 預測新的目標值 label
# new_dy = kmeans.predict(dx)
# plt.rcParams['font.size'] = 14
# plt.figure(figsize=(16, 8))
# # 以不同顏色畫出原始的 10 群資料
# plt.subplot(121)
# plt.title('Original data (10 groups)')
# plt.scatter(dx.T[0], dx.T[1], c=dy, cmap=plt.cm.Set1)
# # 根據重新分成的 5 組來畫出資料
# plt.subplot(122)
# plt.title('KMeans=5 groups')
# plt.scatter(dx.T[0], dx.T[1], c=new_dy, cmap=plt.cm.Set1)
# # 顯示圖表
# plt.tight_layout()
# plt.show()
#
# import matplotlib.pyplot as plt
# from mpl_toolkits.mplot3d import Axes3D # matplotlib 3.2.0 後可省略
# from sklearn.datasets import make_blobs
# from sklearn.cluster import KMeans
# dx, dy = make_blobs(n_samples=500, n_features=3, centers=10, random_state=42)
# kmeans = KMeans(n_clusters59)
# kmeans.fit(dx)
# new_dy = kmeans.predict(dx)
# plt.rcParams['font.size'] = 14
# fig = plt.figure(figsize=(16, 8))
# ax = fig.add_subplot(121, projection='3d')
# plt.title('Original data (10 groups)')
# ax.scatter(dx.T[0], dx.T[1], dx.T[2], c=dy, cmap=plt.cm.Set1)
# ax = fig.add_subplot(122, projection='3d')
# plt.title('KMeans=5 groups')
# ax.scatter(dx.T[0], dx.T[1], dx.T[2], c=new_dy, cmap=plt.cm.Set1)
# plt.show()

import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score
from sklearn.cluster import KMeans
colors = ['red', 'orange', 'yellow', 'green', 'cyan',
          'blue', 'purple', 'brown', 'grey', 'black']
# 產生的資料組數 (10)
clusters = 10
# K 值的範圍 (2~10)
k_range = range(2, clusters + 1)
dx, dy = make_blobs(n_samples=500, n_features=2, centers=clusters, random_state=42)
distortions = []
scores = []
# 記錄每種 K 值建出的 KMeans 模型的成效
for i in k_range:
    kmeans = KMeans(n_clusters=i).fit(dx)
    distortions.append(kmeans.inertia_) # 誤差平方和 (SSE)
    scores.append(silhouette_score(dx, kmeans.predict(dx))) # 側影係數
# 找出最大的側影係數來決定 K 值
selected_K = scores.index(max(scores)) + 2
# 重新建立 KMeans 模型並預測目標值
kmeans = KMeans(n_clusters=selected_K).fit(dx)
new_dy = kmeans.predict(dx)
# 新分組的資料中心點
centers = kmeans.cluster_centers_
plt.rcParams['font.size'] = 12
plt.figure(figsize=(12, 12))
# 原始資料分組
plt.subplot(221)
plt.title(f'Original data ({clusters} groups)')
plt.scatter(dx.T[0], dx.T[1], c=dy, cmap=plt.cm.Set1)
# 新資料分組
plt.subplot(222)
plt.title(f'KMeans={selected_K} groups')
plt.scatter(dx.T[0], dx.T[1], c=new_dy, cmap=plt.cm.Set3)
plt.scatter(centers.T[0], centers.T[1], marker='^', color='orange')
for i in range(centers.shape[0]): # 標上各分組中心點
    plt.text(centers.T[0][i], centers.T[1][i], str(i + 1),
             fontdict={'color': 'red', 'weight': 'bold', 'size': 24})
# 繪製誤差平方和圖 (手肘法)
plt.subplot(223)
plt.title('SSE (elbow method)')
plt.plot(k_range, distortions)
plt.plot(selected_K, distortions[selected_K - 2], 'go') # 最佳解
# 繪製係數圖
plt.subplot(224)
plt.title('Silhouette score')
plt.plot(k_range, scores)
plt.plot(selected_K, scores[selected_K - 2], 'go') # 最佳解
plt.tight_layout()
plt.show()