聚類算法

目錄

1、k-means

2、密度聚類DBSCAN

3、使用高斯混合模型(GMM)的期望最大化(EM)聚類

3.1、EM算法

4、層次聚類


聚類指事先並不知道任何樣本的類別標號,希望通過某種算法來把一組未知類別的樣本劃分成若干類別,聚類的時候,我們並不關心某一類是什麼,我們需要實現的目標只是把相似的東西聚到一起,一個聚類算法通常只需要知道如何計算相似度就可以開始工作了,因此 clustering 通常並不需要使用訓練數據進行學習,這在機器學習中被稱作 unsupervised learning (無監督學習)

通常,人們根據樣本間的某種距離或者相似性來定義聚類,即把相似的(或距離近的)樣本聚爲同一類,而把不相似的(或距離遠的)樣本歸在其他類。

聚類的目標:組內的對象相互之間時相似的(相關的),而不同組中的對象是不同的(不相關的)。組內的相似性越大,組間差別越大,聚類就越好。分組的原則是組內距離最小化而組間距離最大化。

1、k-means

典型的基於距離的非層次聚類算法,在最小化誤差函數的基礎上將數據劃分爲預定的K類別,採用距離作爲相似性的評級指標,即認爲兩個對象的距離越近,其相似性越大。

算法過程:

  1. 從N個樣本中隨機選取k個對象作爲原始的聚類質心。
  2. 分別計算每個樣本到各個聚類中心的距離,將對象分配到距離最近的聚類中。
  3. 所有對象分配完成後,重新計算k個聚類的質心。
  4. 與前一次的k個聚類中心比較,如果發生變化,重複過程(2),否則(5).
  5. 當質心不再發生變化時,停止聚類過程並輸出結果。 

聚類的結果可能依賴初始聚類中心的隨機選擇,可能使得結果嚴重偏離全局最優分類。實踐中爲了得到更好的結果,通常選擇不同的初始聚類中心,多次運行KM算法,在所有對象分配完成後,重新計算K個聚類的中心時,對於連續數據,聚類中心取該簇的均值,當但樣本的屬性是分類變量時,可以使用K-衆數方法。

K值的確定:

1.手肘法

手肘法的核心指標是SSE(sum of the squared errors,誤差平方和):

SSE=\sum_{i=1}^{k} \sum_{p\in C_i}|p-m_i|^{2}

其中,Ci是第i個簇,p是Ci中的樣本點,mi是Ci的質心(Ci中所有樣本的均值),SSE是所有樣本的聚類誤差,代表了聚類效果的好壞。

 手肘法的核心思想是:隨着聚類數k的增大,樣本劃分會更加精細,每個簇的聚合程度會逐漸提高,那麼誤差平方和SSE自然會逐漸變小。並且,當k小於真實聚類數時,由於k的增大會大幅增加每個簇的聚合程度,故SSE的下降幅度會很大,而當k到達真實聚類數時,再增加k所得到的聚合程度回報會迅速變小,所以SSE的下降幅度會驟減,然後隨着k值的繼續增大而趨於平緩,也就是說SSE和k的關係圖是一個手肘的形狀,而這個肘部對應的k值就是數據的真實聚類數。當然,這也是該方法被稱爲手肘法的原因。

SSE = []  # 存放每次結果的誤差平方和
for k in range(1,9):
    estimator = KMeans(n_clusters=k)  # 構造聚類器
    estimator.fit(df_features[['R','F','M']])
    SSE.append(estimator.inertia_)
X = range(1,9)
plt.xlabel('k')
plt.ylabel('SSE')
plt.plot(X,SSE,'o-')
plt.show()

顯然,肘部對於的k值爲4,故對於這個數據集的聚類而言,最佳聚類數應該選4.

2、輪廓係數法:

該方法的核心指標是輪廓係數(Silhouette Coefficient),某個樣本點Xi的輪廓係數定義如下:

S = \frac{b-a}{max(a,b)}

其中,a是Xi與同簇的其他樣本的平均距離,稱爲凝聚度,b是Xi與最近簇(用Xi到某個簇所有樣本平均距離作爲衡量該點到該簇的距離後,選擇離Xi最近的一個簇作爲最近簇。)中所有樣本的平均距離,稱爲分離度。

求出所有樣本的輪廓係數後再求平均值就得到了平均輪廓係數。平均輪廓係數的取值範圍爲[-1,1],且簇內樣本的距離越近,簇間樣本距離越遠,平均輪廓係數越大,聚類效果越好。那麼,很自然地,平均輪廓係數最大的k便是最佳聚類數。

Scores = []  # 存放輪廓係數
for k in range(2,9):
    estimator = KMeans(n_clusters=k)  # 構造聚類器
    estimator.fit(df_features[['R','F','M']])
    Scores.append(silhouette_score(df_features[['R','F','M']],estimator.labels_,metric='euclidean'))
X = range(2,9)
plt.xlabel('k')
plt.ylabel('輪廓係數')
plt.plot(X,Scores,'o-')
plt.show()

可以看到,輪廓係數最大的k值是2,這表示我們的最佳聚類數爲2。但是,值得注意的是,從k和SSE的手肘圖可以看出,當k取2時,SSE還非常大,所以這是一個不太合理的聚類數,我們退而求其次,考慮輪廓係數第二大的k值4,這時候SSE已經處於一個較低的水平,因此最佳聚類係數應該取4而不是2。

 但是,講道理,k=2時輪廓係數最大,聚類效果應該非常好,那爲什麼SSE會這麼大呢?在我看來,原因在於輪廓係數考慮了分離度b,也就是樣本與最近簇中所有樣本的平均距離。爲什麼這麼說,因爲從定義上看,輪廓係數大,不一定是凝聚度a(樣本與同簇的其他樣本的平均距離)小,而可能是b和a都很大的情況下b相對a大得多,這麼一來,a是有可能取得比較大的。a一大,樣本與同簇的其他樣本的平均距離就大,簇的緊湊程度就弱,那麼簇內樣本離質心的距離也大,從而導致SSE較大。所以,雖然輪廓係數引入了分離度b而限制了聚類劃分的程度,但是同樣會引來最優結果的SSE比較大的問題,這一點也是值得注意的。
 

初始點的選擇:

K-means算法是初始值敏感的,選擇不同的初始值可能導致不同的簇劃分規則。

方法一:kmeans++:

1)從輸入的數據點集合中隨機選擇一個點作爲第一個聚類中心

2)對於數據集中的每一個點x,計算它與最近聚類中心(指已選擇的聚類中心)的距離D(x)

3)選擇一個新的數據點作爲新的聚類中心,選擇的原則是:D(x)較大的點,被選取作爲聚類中心的概率較大

4)重複2和3直到k個聚類中心被選出來

5)利用這k個初始的聚類中心來運行標準的k-means算法

 從上面的算法描述上可以看到,算法的關鍵是第3步,如何將D(x)反映到點被選擇的概率上,一種算法如下:

1)先從我們的數據庫隨機挑個隨機點當“種子點”

2)對於每個點,我們都計算其和最近的一個“種子點”的距離D(x)並保存在一個數組裏,然後把這些距離加起來得到Sum(D(x))。

3)然後,再取一個隨機值,用權重的方式來計算下一個“種子點”。這個算法的實現是,先取一個能落在Sum(D(x))中的隨機值Random,然後用Random -= D(x),直到其<=0,此時的點就是下一個“種子點”。

4)重複2和3直到k個聚類中心被選出來

5)利用這k個初始的聚類中心來運行標準的k-means算法

kmeans++改進:K-means II算法:

K-means II算法爲解決Kmeans++算法缺點而產生的一種算法:主要思路是改變每次遍歷時候的取樣規則,並非按照K-means++算法每次遍歷只取一個樣本,而是每次取K個樣本,重複該取樣O(logn)次,然後再將這些抽樣出來的樣本聚類出K個點,最後使用這K個點作爲K-means算法的初始聚類中心點。實踐證明:一般5次重複採用就可以保證一個比較好的聚類中心點。

方法二:選用層次聚類或Canopy算法進行初始聚類,然後從k個類別中分別隨機選取k個點,來作爲kmeans的初始聚類中心點

優缺點:

優點:

K-Means算法的優勢在於它的速度非常快,因爲我們所做的只是計算點和簇中心之間的距離; 這已經是非常少的計算了!因此它具有線性的複雜度O(n)。算法簡單,容易解釋,聚類效果中上,適用於高維。

缺點:

1)必須手動選擇K值,

2)從隨機選擇的簇中心點開始運行,這導致每一次運行該算法可能產生不同的聚類結果。因此,該算法結果可能具有不可重複,缺乏一致性等性質。

3)對離羣點敏感,對噪聲點和孤立點很敏感(通過k中值算法可以解決)

思考:

1、K-means算法在迭代過程中選擇所有點的均值作爲新的質心,如果簇中存在異常點,將導致均值偏差比較嚴重。比如一個簇中有2,4,6,8,100五個數據,計算平均值,新的質點爲24,顯然這個質點離絕大多數點都比較遠;在當前情況下,使用中位數6可能比使用均值的方法更好,使用中位數的聚類算法叫K中值聚類K-Medians。

K-medians的優點是對數據中的異常值不太敏感,但是在較大的數據集時進行聚類時,速度要慢得多,造成這種現象的原因是這種方法每次迭代時,都需要對數據進行排序。

2、在傳統的k-means算法中,要計算所有的樣本點到所有的質心的距離,如果樣本量非常大,如達到10萬以上,特徵100以上,此時使用傳統的k-means非常耗時。在大數據時代,這樣的情形越來越多,此時Mini Batch K-means應運而生。

顧名思義,Mini Batch,也就是用樣本集中的一部分樣本來做傳統的K-means,這樣可以避免樣本量太大時的計算難題,算法收斂速度大大加快。當然此時的代價就是聚類的精度會有所下降,一般來說降低的幅度在可以接受的範圍內。

算法步驟:

1)首先抽取部分數據集,使用K-means算法構建出K個聚簇點的模型。

2)繼續抽取訓練集中的部分數據集樣本數據(吳放回的隨機抽樣),並將其添加到模型中,分配給最近的聚簇中心點。

3)更新聚簇的中心點值。

循環迭代2)和3),直到中心點穩定或者達到迭代次數。

2、密度聚類DBSCAN

DBSCAN算法是一種基於密度的聚類算法:

  • 聚類的時候不需要預先指定簇的個數
  • 最終的簇的個數不定

DBSCAN算法將數據點分爲三類:

  • 核心點:在半徑Eps內含有超過MinPts數目的點
  • 邊界點:在半徑Eps內點的數量小於MinPts,但是落在覈心點的鄰域內
  • 噪音點:既不是核心點也不是邊界點的點

舉例說明算法流程:

               

1)取Eps = 3,MinPts = 3,依據DBSCAN對所有點進行聚類(曼哈頓距離)

2)對每個點計算其鄰域Eps = 3內的點的集合;集合內點的個數超過MinPts個的點爲核心點;查看剩餘點是否在覈心點的鄰域內,若在,則爲邊界點,否則爲噪聲點;

3)將距離不超過Eps的點相互連接,構成一個簇,核心點鄰域內的點也會被加到這個簇中,則上圖形成3個簇。

優缺點:

優點:

1)不需要輸入要劃分的聚類個數;

2)聚類的形狀沒有偏倚,可以發現任意形狀的聚類空間。(K-means基於距離的度量聚類空間通常爲圓形)

3)能夠有效的處理噪聲點。

缺點:

1)由於該算法直接對整個數據庫操作,當數據量很大時,要求較大的內存支持,i/o消耗也很大;

2)當空間聚類的密度不均勻、聚類間距差相差很大時,聚類質量較差(有些簇內距離較小,有些簇內距離很大,但是Eps是確定的,所以,大的點可能被誤判斷爲離羣點或者邊界點,如果Eps太大,那麼小距離的簇內,可能會包含一些離羣點或者邊界點,KNN的k也存在同樣的問題)。

3、使用高斯混合模型(GMM)的期望最大化(EM)聚類

高斯混合模型是聚類算法的一種。k−means算法是確切給出每個樣本被分配到某一個簇,稱爲硬分配;而高斯混合模型則是給出每個樣本被分配到每個簇的概率,最後從中選取一個最大的概率對應的簇作爲該樣本被分配到的簇,稱爲軟分配

高斯混合(Mixture-of-Gaussian)聚類採用概率模型來表達聚類原型。

不一樣參數下,高斯分佈如下:

對於多元高斯分佈,n維樣本空間X中的隨機向量x,概率密度函數爲  

p(x|\mu,\Sigma ) = \frac{1}{(2\pi)^{\frac{n}{2}}|\Sigma |^{\frac{1}{2}}}e^{-\frac{1}{2}(x-\mu)^T\Sigma ^{-1}(x-\mu)}

其中μ是n維均值向量,Σ是n×m的協方差矩陣。高斯概率密度函數由μ和Σ兩個參數決定.
高斯混合分佈爲:

f(x) = \sum_{i=1}^k\alpha_ip(x|\mu,\Sigma ) 
該分佈由k個高斯分佈混合而成,\alpha_i爲混合係數,\alpha_i≥0且\sum_{i=1}^k\alpha_i=1.(權重和爲1)
下面是一個高斯模型學習過程簡圖,先有個感性的認識:

那麼該怎麼求解各個權重係數,常用的方法是EM(期望最大)算法

3.1、EM算法

初識EM算法

硬幣問題

先看一個拋硬幣問題,如果我們有AB兩個不均勻硬幣,選擇任意一個硬幣拋10次(這裏我們知道選擇是的哪一個硬幣),共計選擇5次。正面記爲H,背面記爲T。記錄實驗結果,求AB再拋正面向上的概率?

使用極大似然估計(Maximum likelihood)來算:

  • 統計出每次實驗,正反面的次數
  • 多次實驗結果相加
  • 相除得到結果,P(A)=0.8,P(B)=0.45

但是在實際過程中,很有可能我們只知道有兩個硬幣,不知道每次選擇的哪一個硬幣,問是否能求出每個硬幣拋出正面的概率?

這裏使用的是EM算法:

使用期望最大值(Expectation maximization,EM)算法來算:

  • 假設\hat{\theta}_A^{(0)}=0.6,\hat{\theta}_B^{(0)}=0.5
  • 統計每次的實驗結果,記錄正反面
  • 通過貝葉斯公式,估計每次實驗選擇的A硬幣或是B硬幣的概率
  • 依據計算出的選擇硬幣概率得到該概率下的正反面結果
  • 相加,相除得到\hat {\theta}_A^{(1)} \approx 0.71, \hat{\theta}_B^{(1)} \approx 0.58
  • 重複上面的過程,例如迭代10次後,得到\hat{\theta}_A^{(10)}\approx 0.8,\hat{\theta}_B^{(10)} \approx 0.52
  • \hat{\theta}_A^{(10)},\hat{\theta}_B^{(10)}就是使用EM算法計算出的概率值

這裏比較難理解的是:如何利用貝葉斯公式計算每次實驗選擇的A硬幣或是B硬幣的概率?

那麼先看下面這個例子:

假如現在有射擊運動員甲和乙,甲乙射擊靶心的概率爲\hat{\theta}_{jia} = 0.9 \cdot \hat{\theta}_{yi}=0.2  如果現在有一組實驗結果爲
                                                                      中,不中,中,中,中,
問這次是誰射擊的?

直觀上的來看,非常大的概率是甲射擊的,但是也有可能是乙走狗屎運了。那麼該如何從概率的角度計算是誰射擊的?

首先我們知道選擇甲和乙的概率爲P(甲)=P(乙)=0.5(先驗概率),本次實驗記爲E。通過貝葉斯公式:

故本次實驗有98%的可能是A射擊的,2%的可能是B射擊的。

上面我們計算出每次實驗中是拋A或拋B的概率值就是隱變量.這個過程就是EM算法的簡單案例。

形式化EM算法

未觀測變量的學名是“隱變量”(latent variable).令X表示已觀測變量集,Z表示隱變量集,Θ表示模型參數,欲對Θ做極大似然估計,則應最大化對數似然:

LL(\Theta|X,Z)=lnP(X,Z|\Theta)

因爲Z是隱變量,無法直接求解。我們可通過對Z計算期望,來最大化已觀測數據的對數“邊際似然”:

LL(\Theta|X)=lnP(X|\Theta)=ln\sum_{Z}P(X,Z|\Theta)

EM算法是常用的估計參數隱變量的利器,基本思想是:

若參數Θ已知,則可根據訓練數據推斷出最優隱變量Z的值(E步);再由推斷出的最優隱變量Z對參數Θ做極大似然估計(M步)。

以初始值\Theta ^0爲起點,對上式迭代執行以下步驟直到收斂:

  • 基於\Theta ^t推測隱變量Z的期望,記爲Z^t
  • 基於已觀測變量X和Z^t對參數Θ做極大似然估計,記爲\Theta ^{t+1}

這就是EM算法的原型。

高斯混合模型聚類算法參考鏈接

4、層次聚類

分層聚類算法實際上分爲兩類:自上而下或自下而上。自下而上的算法首先將每個數據點視爲一個單一的簇,然後連續地合併(或聚合)成對的簇,直到所有的簇都合併成一個包含所有數據點的簇。因此,自下而上的分層聚類被稱爲合成聚類或HAC。這個簇的層次可以用樹(或樹狀圖)表示。樹的根是收集所有樣本的唯一簇,葉是僅具有一個樣本的簇。在進入算法步驟之前,請查看下面的圖解。

1、我們首先將每個數據點視爲一個單一的簇,即如果我們的數據集中有X個數據點,那麼我們就有X個簇。然後,我們選擇一個距離度量,來度量兩個簇之間距離。作爲一個例子,我們將使用平均關聯度量,它將兩個簇之間的距離定義爲第一個簇中的數據點與第二個簇中的數據點之間的平均距離。

2、在每次迭代中,我們將兩個簇合併成一個簇。選擇平均關聯值最小的兩個簇進行合併。根據我們選擇的距離度量,這兩個簇之間的距離最小,因此是最相似的,所有應該合併。

3、重複步驟2直到我們到達樹的根,即我們只有一個包含所有數據點的簇。通過這種方式,我們可以選擇最終需要多少個簇。方法就是選擇何時停止合併簇,即停止構建樹時!

分層次聚類不需要我們指定簇的數量,我們甚至可以在構建樹的同時,選擇一個看起來效果最好的簇的數量。另外,該算法對距離度量的選擇並不敏感;與其他距離度量選擇很重要的聚類算法相比,該算法下的所有距離度量方法都表現得很好。當基礎數據具有層次結構,並且想要恢復層次結構時,層次聚類算法能實現這一目標;而其他聚類算法則不能做到這一點。與K-Means和GMM的線性複雜性不同,層次聚類的這些優點是以較低的效率爲代價,即它具有O(n3)的時間複雜度。
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章