12.【基礎】手寫體數字影象聚類--KMeans
阿新 • • 發佈:2019-02-19
本文所有實現程式碼均來自《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時的訓練模型,為此例中最佳的模型;
- 值得一提的是,這裡的折線圖縱軸是輪廓係數,而不是“肘部”觀察法採用的距離平方和的均值,二者不要混淆,下一講中會詳細講解如何使用“肘部”觀察法。