機器學習A-Z~K平均聚類算法

本文來講講K平均聚類算法(K-Means Clustering),K Means算法是所有聚類算法中最經典的一種,因爲它不斷在直覺上容易理解,而且它的計算效率也是非常的高。

原理

在講K-Means算法前我們先看看,這個算法能做什麼。下面有一組數據,我們想要把數據分成若干個類,在某一類當中,這些數據的彼此之間的距離比較近。對於這個大問題,我們有兩個小問題。第一個是,我們如何確定分的類的個數;第二個問題是,如何在確定類的個數的情況下,如何確定每個類中包含的元素。那麼K-Means算法就可以自動幫助我們找到最佳的聚類的方式。如圖所示,K-Means算法講這些數據分成了紅藍綠三組。

那麼我們就來看看K-Means算法的工作流程。

  1. 選擇我們想要的類的個數K;
  2. 在平面上隨機選擇K個點,作爲初始化類的中心點,不一定在原先數據當中;
  3. 對於數據集中的每個點,要判斷它屬於我們之前K箇中心點的哪一類。依據數據中的每個點對這K個點的距離的大小,找到最短的距離,那麼就是每個數據點對應的類別,這一步可以稱作是分配;
  4. 重新計算一些新的中心點,就是應用之前分配的結果重新計算分配好的每個類當中的中心點;
  5. 重新分配,如果重新分配的結果和之前分配的結果相同,則說明找到最佳的K-Means算法的結果,如果不同,那繼續去第四步進行分配計算,直到找到最佳算法結果

下面從具體的例子來講述這個步驟。假設有一組數據,我們要分配成兩類,即K=2;然後隨機選擇兩個點,分別計算每個點距離這兩個點的距離。這裏可以有個比較簡單的計算方式,我們作出這兩個點的垂直平分線,那麼這個綠線上方的點都是離藍色點比較近,下面的離紅色比較近。

那麼我們就把上面的點分作藍組,下面的分爲紅組。目前的步驟相當於已經進行到第三步。接下來第四步,更新每組數據的中心點,那麼我們就找到了新的中心點可以進行第五步,依據新的中心點,重新進行分配。

不斷重複45步驟,直到分配的結果和前一步分配的結果是一致的。

K-Means算法可以以一種算法的方式告訴我們最佳的聚類的方式,這裏就得到了左下方紅組,右上方藍組的這樣一個結論。

隨機初始化陷阱

現在看看初始點的選擇對最終K-Meas聚類結果的影響。下面有一個例子,我們需要用K-Means算法對這組數據進行聚類,選擇K=3。這裏很明顯有三類,我們這裏就直接選擇最佳的中心點並標記出這三類數據。

那麼這裏是我們肉眼看出來的三個中心點,但如果我們選擇的不是這最佳的中心點,則需要重複上述的45步,比如選的是下面這三個中心點。

那麼這時就需要對中心點進行位移,但由於這個位移是非常小的,所以新的分類結果和之前並不會有什麼改變,所以算法就這樣結束了。

這樣得到的分類結果和之前那個顯然是不同的。但這樣就發生了同一組數據,卻產生了兩個不同的分類結果。區別就在於選擇了不同的初始中心點。我們不好直接說哪一個分類算法更好,需要有一個方法來判斷如何選擇初始中心點。也就是說初始中心點不能隨機進行選擇了。現在有一個K-Means算法的更新版本,叫做K-Means++,它完美的解決了初始化中心點的陷阱,數學上來講叫做局部最小值的一個陷阱。無論在R還是Python中,這個K-Means++都已經加入了算法當中,因此不用擔心之後的代碼實現會不會掉入這個陷阱。

選擇類的個數

上文講到的是選擇中心點的陷阱,那麼現在在談談如何選擇類的個數。從直觀上,上文中的圖像大部分人應該很容易想到分爲3組,也有的人可能想分爲2組,但怎樣選擇纔是最佳的分組方式是個需要好好研究的問題。首先來定義一個數學的量,組內平方和(WCSS)。

WCSS

來看這個表達式,一共有3項,每一項代表對於每一組的平方和。比如第一項,就是對所有數據點對這一組中心點距離的平方。很顯然,如果每一組的數據蜷縮的越緊,那麼這個平方和就越小。

那麼如果將這組數據分爲1組,那麼這個組內平方和只有一項,那麼這個結果很顯然會很大。如果分爲2組,那麼結果比1組的肯定要小,當分爲3組時,得到的結果會更小。也就是說,隨着分組的個數增加,這個組內平方和會逐漸變小。那麼現在的問題來了,如何選擇最合適的分組的個數?

這裏要介紹一個法則,叫做手肘法則(The Elbow Method)。我們把隨着分組個數的增加,WCSS的結果的圖像畫出來。

手肘法則

找到最像手肘的這個點,這裏就是3,那麼這個點,就是最佳的分組的個數。這個曲線上可以看到,從1到2,和2到3時,下降的速率都是比較快的,但從3往後,下降的速率都是非常小的,那麼我們要找的就是這樣一個點,在到達這個點之前和從這個點開始的下降,速率的變化時最大的。

代碼實現

我們這次要用到的數據集部分如下,反映的是一個購物商場的購物信息。最後一列Spending Score是購物商場根據客戶的信息打出的客戶的評分,分數越低意味着客戶花的錢越少,越高以爲着客戶花的越多。商場希望通過對客戶的年收入和購物指數來進行分羣。

CustomerID Genre Age Annual Income (k$) Spending Score (1-100)
0001 Male 19 15 39
0002 Male 21 15 81
0003 Female 20 16 6
0004 Female 23 16 77

那麼這個問題的自變量就是第三四列,年收入和購物指數。但它是個無監督學習,因此沒有因變量。這裏我們要用到的工具是sklearn.cluster中的KMeans類。

首先要計算各個分組的WCSS。這裏我們計算組數從1到10的情況。

wcss = []
for i in range(1, 11):
    kmeans = KMeans(n_clusters=i, max_iter=300, n_init=10, init='k-means++', random_state=0)
    kmeans.fit(X)
    wcss.append(kmeans.inertia_)
plt.plot(range(1, 11), wcss)
plt.title('The Elbow Method')
plt.xlabel('Number of Clusters')
plt.ylabel('WCSS')
plt.show()

這裏的KMeans中的參數也解釋下,n_clusters指的是分組數,max_iter指的是每一次計算時最大的循環個數,這裏使用默認值300,n_init代表每一個做K平均算法時,會對多少組不同的中心值進行計算。init這個參數非常重要,指的是我們如何選擇初始值,最簡單的是random,即隨機,但爲了避免掉入隨機初始值陷阱,這裏使用k-means++。

擬合好後得到組間距離就是kmeans.inertia_。這樣我們就可以畫出對於不同的分組數,wcss的圖像。

那麼通過手肘法則,可以得到最佳的分組個數是5組,則可以開始擬合數據。

# Applying the k-means to the mall dataset
kmeans = KMeans(n_clusters=5, max_iter=300, n_init=10, init='k-means++', random_state=0)
y_kmeans = kmeans.fit_predict(X)

擬合好數據後,得到的y_means實際上就是0-4五個分組。我們來將分組後的圖像畫出來看看。

# Visualizing the clusters
plt.scatter(X[y_kmeans == 0, 0], X[y_kmeans == 0, 1], s=100, c='red', label='Careful')
plt.scatter(X[y_kmeans == 1, 0], X[y_kmeans == 1, 1], s=100, c='blue', label='Standard')
plt.scatter(X[y_kmeans == 2, 0], X[y_kmeans == 2, 1], s=100, c='green', label='Target')
plt.scatter(X[y_kmeans == 3, 0], X[y_kmeans == 3, 1], s=100, c='cyan', label='Careless')
plt.scatter(X[y_kmeans == 4, 0], X[y_kmeans == 4, 1], s=100, c='magenta', label='Sensible')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=300, c='yellow', label='Centroids')
plt.title('Clusters of clients')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.legend()
plt.show()

得到的圖像如下,我們就可以根據圖像來進行分析,給予不同的標籤。

分類結果

以上,就是K-Means聚類算法的相關基礎知識點。

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