KMeans聚類算法

何爲聚類?

俗話說“物以類聚,人以羣分”說的是把相同或相似的東西放在一起比較討論,志同道合的朋友常常能夠相聚在一起把酒言歡。朋友間正是因爲有相同的志向和趣味,所以能夠走到一起,與人一樣,數據挖掘裏面的聚類是指把具有相同或者相似(退後一步)的對象放在一起討論,從而挖掘出放在一起的理由和不放在一起的理由以及這樣放在一起與不放在一起所帶來的額外效用。也許你會問用什麼辦法來衡量兩個對象的相似性呢?這時候就需要把對象的各種屬性考慮進來,通過對比分析兩個對象的不同屬性間的差異來進行判斷,比如考察某個班所有學生的聚類情況,已經知道所有學生的期末考試成績以及平時缺課次數兩個屬性,可以按照下面規則聚集

  • 學神
    期末考試成績優異,平時缺課無數

  • 學霸
    期末考試成績優異,平時不缺課

  • 學渣
    期末考試成績掉渣,平時缺課無數

  • 學弱
    期末考試成績掉渣,平時不缺課

我們看到了按照成績屬性取優異還是掉渣以及缺課屬性取缺還是不缺共4種組合可以把班裏所有學生劃分成4類,這樣每一類的學生都有自己的特點,同類別的學生有着非常高的相似度,不同類的學生卻是天壤之別。這裏,我們又引進了相似度的概念,如果兩個對象各屬性相似度高,那麼這兩個對象理應屬於同一類別,反之應該屬於不同類別,上面我們只是通過描述性的語言來說明分類情況, 那麼如何用數學語言來刻畫呢? 常見的相似度刻畫採用距離公式,主要有以下幾種距離公式,爲討論的一般性,我們假設有nn個樣本,每個樣本有pp個指標,數據矩陣如下表所示
在這裏插入圖片描述
記第ii個樣本爲(i)=(xi1,,xip)T(i)=(x_{i1},\cdots,x_{ip})^T,第jj個樣本爲(j)=(xj1,,xjp)T(j)=(x_{j1},\cdots,x_{jp})^T,把每個樣本看成pp維空間裏的質點,記i(i)j(j)的距離爲D(i,j)D(i,j) , 那麼

  • 歐式距離(Euclidean Distance)
    D(i,j)=[l=1pxilxjl2]12D(i,j)=[ \sum\limits_{l=1}^{p}|x_{il}-x_{jl}|^2 ]^ {\frac{1} {2} }

  • 曼哈頓距離(Manhattan Distance)
    D(i,j)=l=1pxilxjlD(i,j)=\sum\limits_{l=1}^{p}|x_{il}-x_{jl}|

  • 切比雪夫距離 (Chebyshev Distance )
    D(i,j)=max1lpxilxjlD(i,j)=max_ {1\leq l\leq p} |x_{il}-x_{jl}|

  • 閔可夫斯基距離(Minkowski Distance)
    D(i,j)=[l=1pxilxjlq]1qD(i,j)=[ \sum\limits_{l=1}^{p}|x_{il}-x_{jl}|^q ]^ {\frac{1} {q} }

從各種距離公式可以看出,切比雪夫距離和歐式距離是閔科夫斯基距離當q=1q=1q=2q=2的特殊情況。

聚類與分類的區別

很多初學者會把聚類和分類混餚,那麼聚類和分類有何區別呢?主要體現在

  • 學習範疇
    分類屬於監督學習範疇,而聚類屬於無監督學習範疇

  • 進程不一樣
    分類主要用訓練數據學習一個模型,裏面數據的類別是確定的,然後把測試集中的實例對應到這些確定的類別中,是兩步走的過程。而聚類是起初並不知道具體有多少類,可以先行假定類別數,即kk 值,然後通過某些判斷方法,把所有數據劃分到這kk個類別中,使得同一類的實例儘可能聚集到一起,不同類實例儘量離間,不需要訓練測試,更多像一錘子買賣。

常見聚類算法及KMeans算法

常見的聚類算法有基於空間測距的KMeans算法,基於密度劃分的DBSCAN算法,基於點距離的 hierarchical clustering算法,基於圖距離的Affinity Propagation算法等,這裏重點介紹KMeans算法。

KMeans翻譯成中文表示k均值,KMeans算法的關鍵是找kk個均值來當作類別的中心,並以此爲參考將其他實例吸收到這kk個類別,使得最後距離和最小。假設有nn個實例,現在要將其劃分到kk個不相鄰的類別或簇C={c1,,ck}\mathcal{C}=\{c_1,\cdots,c_k\},記第jj個簇cjc_j中的樣本均值(中心)爲uju_j, KMeans 算法旨在選擇合適的uju_j,使得簇內平方和最小,即
minujCj=1ki=1nxiuj2\min\limits_ {u_j\in C}\sum\limits_{j=1}^k\sum\limits_{i=1}^n||x_i-u_j||^2

算法實現步驟

KMeans算法比較簡單,只有三步

  1. 初始化kk箇中心,當成kk個初始簇
  2. 將每一個實例劃分到離其最近的中心簇
  3. 計算每個簇的均值,得到新的簇中心
    如果前後兩次計算得到簇中心不發生變化,或者變化小於給定的閾值,算法結束,否則返回2計算每個樣本到新的簇中心的距離

KMeans的優缺點

KMeans算法假設簇都是凸的且同性的,而對長條形和不正規的形狀表現不好,對於高維數據,KMeans算法會消耗更多計算資源。

KMeans聚類算法實例

完整代碼

# -*- coding: utf-8 -*-
"""
project_name:聚類算法
@author: 帥帥de三叔
Created on Wed Nov  6 10:05:42 2019
"""
import pandas as pd #導入數據分析模塊
from sklearn import  preprocessing #導入數據預處理模塊
from sklearn.cluster import KMeans #導入kmeans聚類算法
data=pd.read_excel("2018vs2016.xlsx",index_col=u"板塊名稱",sheet_name="2018") #讀取數據
X=data.iloc[:,0:-1] #聚類用到的特徵屬性
X_scaled=preprocessing.StandardScaler(copy=True,with_mean=True,with_std=True).fit_transform(X) #特徵屬性標準化
feature=pd.DataFrame(X_scaled)
k=4 #設置聚類類別數
maxiteration=500 #設置最大迭代次數
model=KMeans(n_clusters=k,init='k-means++',n_init=10,max_iter=maxiteration,tol=1e-4,precompute_distances='auto',verbose=0,random_state=None,copy_x=True,n_jobs=2,algorithm='auto') #聚類模型初始化
model.fit(feature,y=None,sample_weight=None) #訓練模型
lables=pd.DataFrame(model.labels_,index=data.index) #類別標籤
cluster_result=pd.concat([data,lables],axis=1) #沿着水平方向拼接類別標籤
cluster_result.columns=["交通","商業購物","教育","醫療","景觀周遊","生活娛樂","綜合得分","類別標籤"] #重命名錶頭
print(cluster_result)
cluster_result.to_excel("板塊聚類結果.xlsx")    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章