聚類-K-Means


1.什么是K-Means?

K均值算法聚類

關鍵詞:K個種子,均值
聚類的概念:一種無監督的學習,事先不知道類別,自動將相似的對象歸到同一個簇中

K-Means算法是一種聚類分析(cluster analysis)的算法,其主要是來計算數據聚集的算法,主要通過不斷地取離種子點最近均值的算法.

K-Means算法的思想很簡單,對於給定的樣本集,按照樣本之間的距離大小,將樣本集划分為K個簇。讓簇內的點盡量緊密的連在一起,而讓簇間的距離盡量的大.

2.k-Means原理

每次計算距離采用的是歐式距離

 

 

 步驟圖:

 

 

 

步驟總結:

  • 從數據中選擇k個對象作為初始聚類中心;
  • 計算每個聚類對象到聚類中心的距離來划分;
  • 再次計算每個聚類中心
  • 2~3步for循環,直到達到最大迭代次數,則停止,否則,繼續操作。
  • 確定最優的聚類中心

主要優點:

  • 原理比較簡單,實現也是很容易,收斂速度快。
  • 聚類效果較優。
  • 算法的可解釋度比較強。
  • 主要需要調參的參數僅僅是簇數k。
  • 當簇近似為高斯分布時,效果是最高的.
  • 對處理大數據集該算法保持可伸縮性和高效率

主要缺點:

  • K-Means算法需要用初始隨機種子點來搞,這個隨機種子點太重要,不同的隨機種子點會有得到完全不同的結果。(K-Means++算法可以用來解決這個問題,其可以有效地選擇初始點)

  • 必須事先給出k(要生成的簇的數目),而且對初值敏感,對於不同的初值,可能會導致不同的結果.
  • 對於不是凸的數據集比較難收斂
  • 如果各隱含類別的數據不平衡,比如各隱含類別的數據量嚴重失衡,或者各隱含類別的方差不同,則聚類效果不佳。
  • 采用迭代方法,得到的結果只是局部最優。
  • 對噪音和異常點比較的敏感。

 3.K-Means算法應用:

  • 對於多維數據的分類,效果很好
  • 二維坐標點的X,Y 坐標,其實是一種向量,是一種數學抽象。現實世界中很多屬性是可以抽象成向量的,比如,我們的年齡,我們的喜好,我們的商品,等等,能抽象成向量的目的就是可以讓計算機知道某兩個屬性間的距離。如:我們認為,18歲的人離24歲的人的距離要比離12歲的距離要近,鞋子這個商品離衣服這個商品的距離要比電腦要近,等等。解決實際問題比較好

4.K-Means實例-亞洲國家隊足球水平分類

 1 import numpy as np
 2 
 3 import pandas as pd
 4 
 5 # cluster :簇,一堆
 6 # 只有分類
 7 from sklearn.cluster import KMeans
 8 
 9 import matplotlib.pyplot as plt
10 %matplotlib inline
11 
12 from mpl_toolkits.mplot3d.axes3d import Axes3D
13 import warnings
14 warnings.filterwarnings('ignore')
15 
16 # 2006年世界杯,2010年世界杯,2007亞洲杯,比賽數據
17 football = pd.read_csv('./AsiaFootball.txt')
18 
19 X = football.iloc[:,1:]
20 
21 kmeans = KMeans(n_clusters=5)
22 
23 # 無監督學習 PCA也是無監督 NMF無監督
24 kmeans.fit(X)
25 y_ = kmeans.predict(X)
26 
27 # 分成3類
28 for i in range(3):
29     index = np.argwhere(y_ == i).reshape(-1)
30     print('類別是%d國家隊有:'%(i),football['國家'].loc[index].get_values())
31 
32 # 分成5類
33 for i in range(5):
34     index = np.argwhere(y_ == i).reshape(-1)
35     print('類別是%d國家隊有:'%(i),football['國家'].loc[index].get_values())

加載的數據結構:

 

 

 

分成3類打印輸出:

分成5類打印輸出:

 

 

 分類好了,但是我們不知道分成4類好還是分成5類好,現在選取一些指標來評判一下:

(1)輪廓系數 Silhouette Coefficient

1 # 輪廓系數
2 from sklearn.metrics import silhouette_score
3 
4 for i in range(2,16):
5     kmeans = KMeans(n_clusters=i)
6     kmeans.fit(X)
7     y_ = kmeans.predict(X)
8     s = silhouette_score(X,y_)
9     print('聚類個數是:%d。輪廓系數是:%0.2f'%(i,s))

 

 

由輪廓系數分析可知,當分為6類的時候,效果最好

(2)calinski_harabasz_score CH分數(值越大,效果越好)

 

1 for i in range(2,16):
2     kmeans = KMeans(n_clusters=i)
3     kmeans.fit(X)
4     y_ = kmeans.predict(X)
5     s = metrics.calinski_harabasz_score(X,y_)
6     print('聚類個數是:%d。calinski_harabasz_score:%0.2f'%(i,s))

 

(3)davies_bouldin_score 戴維森堡丁指數DBI(度量是每個聚類最大相似度的均值)

 

1 for i in range(2,16):
2     kmeans = KMeans(n_clusters=i)
3     kmeans.fit(X)
4     y_ = kmeans.predict(X)
5     s = metrics.davies_bouldin_score(X,y_)
6     print('聚類個數是:%d。davies_bouldin_score:%0.2f'%(i,s))

 

 以上三種方式得到的最優分類均不同,這是因為數據的原因,數據不太好.

 5.Kmeans評價指標,這個就是聚類的衡量指標,之后再具體詳細的解釋一下

(1)輪廓系數 metrics.silhouette_score

(2)蘭德系數 metrics.adjusted_rand_score

(3)互信息指標 metrics.adjusted_mutual_info_score

(4)同質性 homogeneity_completeness_v_measure

(5)Calinski-Harabasz索引 metrics.calinski_harabasz_score

(6)Davies-Bouldin索引 metrics.davies_bouldin_score

 

補充:

1.k-Means算法,初值的選擇,對聚類結果有影響嗎?

k-Means是初值敏感的,舉個例子:

 

 對於左圖來說,使用k-means分類,我們肉眼可見,選擇初值會在四個區域選擇四個樣本,

但是如圖所示,在第二部分選擇了兩個樣本作為初始值,而第一部分沒有選擇,

這種情況下,最終的分類結果可能是右圖所示,這樣的話結果就不太好,分類效果明顯不好,

所以,由此可見,初值的選擇對分類有很大的影響.

我覺得有一種解決方法是:

k-means++算法:

先隨機選擇一個樣本點為初始值,然后計算其他所有樣本到該該本點的距離,然后計算加權平均,相當於給每個樣本點一個權值,也就是被選中的概率,然后按照概率選擇其他的初始值,並不是概率高的一定會被選中,概率低的也可能會被選中,這是一個概率問題,一般來說選中都是距離第一個初始值比較遠的,這樣我們就有下一個聚類中心了,再然后找第三個聚類中心的話,更新一下之前的距離權值,根據樣本到兩個聚類中心的距離,哪個距離大選擇哪個,這樣再根據概率挑選出第三個聚類中心,之后的步驟是一樣的,這就是k-means++算法

2.k-means使用場景

k-means其實對樣本的分布是有要求的,我們認為k個樣本其實是服從高斯混合分布的,並且每個高斯分布的方差是一樣的,其實也就是每個簇的方差是一樣的.

3.k-means的公式化解釋:

 

 我們上邊所說的原理其實就是兩個公式的重復循環

4.如果樣本量巨大的話,可以考慮使用mini-batch k-means算法

5.k-means算法可能會振盪

采用迭代的方法,多做幾次,每次結果可能都不一樣,具體哪個效果好,可能需要人為去判斷.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM