<jupyter_start><jupyter_text>1) 載入資料集<jupyter_code>iris = load_iris()
df_data = pd.DataFrame(data= np.c_[iris['data'], iris['target']],
                     columns= ['SepalLengthCm','SepalWidthCm','PetalLengthCm','PetalWidthCm','Species'])
df_data
X = df_data.drop(labels=['Species'],axis=1).values # 移除Species並取得剩下欄位資料
y = df_data['Species']<jupyter_output><empty_output><jupyter_text>K-MeansParameters:- n_cluster: K的大小，也就是分群的類別數量。- random_state: 亂數種子，設定常數能夠保證每次分群結果都一樣。- n_init: 預設為10次隨機初始化，選擇效果最好的一種來作為模型。- max_iter: 迭代次數，預設為300代。    Attributes:- inertia_: inertia_：float，每個點到其他叢集的質心的距離之和。- cluster_centers_： 特徵的中心點 `[n_clusters, n_features]`。    Methods:- fit: K個集群分類模型訓練。- predict: 預測並回傳類別。- fit_predict: 先呼叫fit()做集群分類，之後在呼叫predict()預測最終類別並回傳輸出。- transform: 回傳的陣列每一行是每一個樣本到kmeans中各個中心點的L2(歐幾里得)距離。- fit_transform: 先呼叫fit()再執行transform()。  K-Means 的演算過程:1. 初始化：指定K個分群，並隨機挑選K個資料點的值當作群組中心值2. 分配資料點：將每個資料點設為距離最近的中心3. 計算平均值：重新計算每個分群的中心點> 重複步驟2、3，直到資料點不再變換群組為止<jupyter_code>from sklearn.cluster import KMeans

kmeansModel = KMeans(n_clusters=3, random_state=46)
clusters_pred = kmeansModel.fit_predict(X)<jupyter_output><empty_output><jupyter_text>評估分群結果inertia: within cluster sum of squres, 各sample到各該群的centroid的距離之平方和，用來評估cluster的成效，越大代表越差<jupyter_code>kmeansModel.inertia_<jupyter_output><empty_output><jupyter_text>查看各cluster的中心，並在圖上畫出<jupyter_code>kmeansModel.cluster_centers_<jupyter_output><empty_output><jupyter_text>真實分類<jupyter_code>sns.lmplot("PetalLengthCm", "PetalWidthCm", hue='Species', data=df_data, fit_reg=False, legend=False)
plt.legend(title='target', loc='upper left', labels=['Iris-Setosa', 'Iris-Versicolour', 'Iris-Virginica'])
plt.show()<jupyter_output>/opt/anaconda3/lib/python3.7/site-packages/seaborn/_decorators.py:43: FutureWarning: Pass the following variables as keyword args: x, y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.
  FutureWarning<jupyter_text>K-mean 後預測結果<jupyter_code>df_data['Predict']=clusters_pred
sns.lmplot("PetalLengthCm", "PetalWidthCm", data=df_data, hue="Predict", fit_reg=False, legend=False)
plt.scatter(kmeansModel.cluster_centers_[:, 2], kmeansModel.cluster_centers_[:, 3], s=200,c="r",marker='*')
plt.legend(title='target', loc='upper left', labels=['Iris-Setosa', 'Iris-Versicolour', 'Iris-Virginica'])
plt.show()<jupyter_output>/opt/anaconda3/lib/python3.7/site-packages/seaborn/_decorators.py:43: FutureWarning: Pass the following variables as keyword args: x, y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.
  FutureWarning<jupyter_text>使用inertia做評估<jupyter_code># k = 1~9 做9次kmeans, 並將每次結果的inertia收集在一個list裡
kmeans_list = [KMeans(n_clusters=k, random_state=46).fit(X)
                for k in range(1, 10)]
inertias = [model.inertia_ for model in kmeans_list]<jupyter_output><empty_output><jupyter_text>如圖，當K值越來越大，inertia會隨之越來越小，(但k=n時理論上inertia會減為0, 因此實際上不能選inertia最小的那個k) 一般是取elbow point, 即inertia迅速下降轉為平緩的那個點<jupyter_code>plt.figure(figsize=(8, 3.5))
plt.plot(range(1, 10), inertias, "bo-")
plt.xlabel("$k$", fontsize=14)
plt.ylabel("Inertia", fontsize=14)
plt.annotate('Elbow',
             xy=(3, inertias[3]),
             xytext=(0.55, 0.55),
             textcoords='figure fraction',
             fontsize=16,
             arrowprops=dict(facecolor='black', shrink=0.1)
            )
plt.axis([1, 8.5, 0, 1300])

plt.show()<jupyter_output><empty_output><jupyter_text>另外一個方法是用silhouette scores 去評估. The Silhouette Coefficient is calculated using the mean intra-cluster distance (a) and the mean nearest-cluster distance (b) for each sample. The Silhouette Coefficient for a sample is (b - a) / max(a, b). (https://scikit-learn.org/stable/modules/generated/sklearn.metrics.silhouette_score.htmlsklearn.metrics.silhouette_score)Silhouette Coefficient 越大代表分群效果越好<jupyter_code>from sklearn.metrics import silhouette_score
silhouette_scores = [silhouette_score(X, model.labels_)
                     for model in kmeans_list[1:]]
plt.figure(figsize=(8, 3))
plt.plot(range(2, 10), silhouette_scores, "bo-")
plt.xlabel("$k$", fontsize=14)
plt.ylabel("Silhouette score", fontsize=14)

plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13227513227513227, 'fraction_numerical': 0.0197837589141937, 'mean_word_length': 7.022140221402214, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 36, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '437635', 'license': 'MIT', 'n_tokens_mistral': 2018, 'n_tokens_neox': 2059, 'n_words': 270, 'path': '_posts/ithome/2021/6.非監督式學習k-means分群/6.非監督式學習 k-means分群.ipynb', 'repo_name': 'andy6804tw/andy6804tw.github.io', 'size': '4347'}