# 手肘法調(diào)研了一下基本是畫出圖片以后,采取目測的方式選擇合適的K,# 這里我自己寫了一個獲取K的方法,好像有點(diǎn)不準(zhǔn)import matplotlib.pyplot as plt
from sklearn.cluster import KMeansdef get_k_value(distortions, start_class_num =1):"""通過手肘法計算最優(yōu)的k值A(chǔ)rgs:border_entity_info: Returns:k: 最優(yōu)的k值"""k =0foriin range(len(distortions) - 1):if distortions[i] - distortions[i+1]<1:k = i + start_class_numbreakreturn kdef elbow_method_K(data, range_K, pro_num):K = range(1, range_K + 1)meandistortions =[]forkin K:kmeans = KMeans(n_clusters=k)kmeans.fit(data)meandistortions.append(kmeans.inertia_)best_k = get_k_value(meandistortions)plt.plot(K, meandistortions, 'bx-')plt.xlabel('k')plt.ylabel('Average Dispersion')plt.title('Selecting k with the Elbow Method')plt.savefig(f'/Users/cecilia/Desktop/K_圖片/{pro_num}_elbow_K.jpg')plt.cla()return best_k
# 這個函數(shù)是我自己使用的時候封裝的# data是需要進(jìn)行聚類的數(shù)據(jù),可以是多維矩陣# range_K是類別的可選擇范圍# pro_num是名稱,沒有實(shí)際意義是為了將圖片保存下來,不想保存圖片可以直接使用plt.show()
(2)Gap Statistic
是斯坦福大學(xué)的三位教授在2001年的一篇論文中(R. Tibshirani, G. Walther, and T. Hastie, 2001)提出來的,可用于任何的聚類方法。Gap Statistic的主要思想是比較不同k時原始數(shù)據(jù)的簇內(nèi)偏差總和與數(shù)據(jù)在均勻分布推斷下的簇內(nèi)偏差總和。使Gap Statistic這個統(tǒng)計量達(dá)到最大值意味著此時的聚類結(jié)果結(jié)構(gòu)與隨機(jī)均勻分布產(chǎn)生的數(shù)據(jù)的聚類結(jié)果差別最大,此時的k就是最優(yōu)的k。算法如下:
平均輪廓系數(shù)方法衡量了聚類結(jié)果的質(zhì)量,即衡量每個點(diǎn)被放到當(dāng)前類簇有多合適,平均輪廓系數(shù)很高意味著聚類的結(jié)果很好。這種方法計算不同k值下,所有點(diǎn)的平均輪廓系數(shù),能夠使平均輪廓系數(shù)最大的k就是最優(yōu)的類簇數(shù)量(Kaufman and Rousseeuw 1990)。 具體的過程與手肘法是相似的:
選擇一個聚類算法(例如K-means),計算不同k時的聚類結(jié)果,例如k可以取為0~10。
對于每個k,計算所有觀測點(diǎn)的平均輪廓系數(shù)。
畫出這個指標(biāo)隨著k變化的曲線。
曲線中最高點(diǎn)對應(yīng)的k就是最優(yōu)聚類數(shù)量。
from sklearn.metrics import silhouette_score
from sklearn.cluster import KMeansdef get_silhouette_K(data, range_K, pro_num):K = range(2, range_K)Scores =[]forkin K:kmeans = KMeans(n_clusters=k)kmeans.fit(data)Scores.append(silhouette_score(data, kmeans.labels_, metric='euclidean'))max_idx = Scores.index(max(Scores))best_k = K[max_idx]plt.plot(K, Scores, 'bx-')plt.xlabel('k')plt.ylabel('silhouette')plt.title('Selecting k with the silhouette Method')plt.savefig(f'/Users/cecilia/Desktop/K_圖片/{pro_num}_silhouette_K.jpg')plt.cla()return best_k
# 這個函數(shù)是我自己使用的時候封裝的# data是需要進(jìn)行聚類的數(shù)據(jù),可以是多維矩陣# range_K是類別的可選擇范圍# pro_num是名稱,沒有實(shí)際意義是為了將圖片保存下來,不想保存圖片可以直接使用plt.show()