1. 程式人生 > >12.【基礎】手寫體數字影象聚類--KMeans

12.【基礎】手寫體數字影象聚類--KMeans

本文所有實現程式碼均來自《Python機器學習及實戰》

#-*- coding:utf-8 -*-

#分別匯入numpy、matplotlib、pandas,用於數學運算、作圖以及資料分析
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd 

#第一步:使用pandas讀取訓練資料和測試資料
digits_train = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tra'
,header=None) digits_test = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tes',header=None) #第二步:已知原始資料有65個特徵值,前64個是畫素特徵,最後一個是每個影象樣本的數字類別 #從訓練集和測試集上都分離出64維度的畫素特徵和1維度的數字目標 X_train = digits_train[np.arange(64)] y_train = digits_train[64] X_test = digits_test[np.arange(64
)] y_test = digits_test[64] #第三步:使用KMeans模型進行訓練並預測 from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=10) kmeans.fit(X_train) kmeans_y_predict = kmeans.predict(X_test) #第四步:評估KMeans模型的效能 #如何評估聚類演算法的效能? #1.Adjusted Rand Index(ARI) 適用於被用來評估的資料本身帶有正確類別的資訊,ARI指標和計算Accuracy的方法類似 #2.Silhouette Coefficient(輪廓係數) 適用於被用來評估的資料沒有所屬類別 同時兼顧了凝聚度和分散度,取值範圍[-1,1],值越大,聚類效果越好
from sklearn.metrics import adjusted_rand_score print 'The ARI value of KMeans is',adjusted_rand_score(y_test,kmeans_y_predict) #到此為止,手寫體數字影象聚類--kmeans學習結束,下面單獨討論輪廓係數評價kmeans的效能 #**************************************************************************************************** #拓展學習:利用輪廓係數評價不同累簇數量(k值)的K-means聚類例項 from sklearn.metrics import silhouette_score #分割出3*2=6個子圖,並且在1號子圖作圖 subplot(nrows, ncols, plot_number) plt.subplot(3,2,1) #初始化原始資料點 x1 = np.array([1,2,3,1,5,6,5,5,6,7,8,9,7,9]) x2 = np.array([1,3,2,2,8,6,7,6,7,1,2,1,1,3]) # a = [1,2,3] b = [4,5,6] zipped = zip(a,b) 輸出為元組的列表[(1, 4), (2, 5), (3, 6)] X = np.array(zip(x1,x2)).reshape(len(x1),2) #X輸出為:array([[1, 1],[2, 3],[3, 2],[1, 2],...,[9, 3]]) #在1號子圖作出原始資料點陣的分佈 plt.xlim([0,10]) plt.ylim([0,10]) plt.title('Instances') plt.scatter(x1,x2) colors = ['b','g','r','c','m','y','k','b'] markers = ['o','s','D','v','^','p','*','+'] clusters = [2,3,4,5,8] subplot_counter = 1 sc_scores = [] for t in clusters: subplot_counter += 1 plt.subplot(3,2,subplot_counter) kmeans_model = KMeans(n_clusters=t).fit(X) for i,l in enumerate(kmeans_model.labels_): plt.plot(x1[i],x2[i],color=colors[l],marker=markers[l],ls='None') plt.xlim([0,10]) plt.ylim([0,10]) sc_score = silhouette_score(X,kmeans_model.labels_,metric='euclidean') sc_scores.append(sc_score) #繪製輪廓係數與不同類簇數量的直觀顯示圖 plt.title('K=%s,silhouette coefficient = %0.03f'%(t,sc_score)) #繪製輪廓係數與不同類簇數量的關係曲線 plt.figure() #此處必須空一行,表示在for迴圈結束之後執行!!! plt.plot(clusters,sc_scores,'*-') #繪製折線圖時的樣子 plt.xlabel('Number of Clusters') plt.ylabel('Silhouette Coefficient Score') plt.show() #**************************************************************************************************** #總結: #k-means聚類模型所採用的迭代式演算法,直觀易懂並且非常實用,但是有兩大缺陷 #1.容易收斂到區域性最優解,受隨機初始聚類中心影響,可多執行幾次k-means來挑選效能最佳的結果 #2.需要預先設定簇的數量,通過“肘部觀察法”,選擇拐點對應的k值

這裡寫圖片描述
這裡寫圖片描述

補充:

  • 由折線圖可知,在k=3時 ,對應的輪廓係數值是最大的,那麼我們將採用k=3時的訓練模型,為此例中最佳的模型;
  • 值得一提的是,這裡的折線圖縱軸是輪廓係數,而不是“肘部”觀察法採用的距離平方和的均值,二者不要混淆,下一講中會詳細講解如何使用“肘部”觀察法。