聚類算法及其模型評估

聚類(Clustering)就是按照某個特定標準把一個數據集分割成不同的類或簇,使得同一個簇內的數據對象的相似性盡可能大,同時不在同一個簇中的數據對象的差異性也盡可能地大。即聚類后同一類的數據盡可能聚集到一起,不同類數據盡量分離。

主要的聚類方法可以劃分成如下幾類:劃分方法、層次方法、基于密度的方法、基于網絡的方法、基于模型的方法。

聚類和分類有什么區別

聚類(Clustering)

聚類,簡單地說就是把相似的東西分到一組,聚類的時候,我們并不關心某一類是什么,我們需要實現的目標只是把相似的東西聚到一起。一個聚類算法通常只需要知道如何計算相似度就可以開始工作了,因此聚類通常并不需要使用訓練數據進行學習,在機器學習中屬于無監督學習

分類(Classifification)

分類,對于一個分類器,通常需要你告訴它“這個東西被分為某某類”。一般情況下,一個分類器會從它 得到的訓練集中進行學習,從而具備對未知數據進行分類的能力,在機器學習中屬于監督學習

k-means算法

k-means是劃分方法中較經典的聚類算法之一。由于該算法的效率高,所以在對大規模數據進行聚類時被廣泛應用。目前,許多算法均圍繞著該算法進行擴展和改進。 k-means算法以k為參數,把n個對象分成k個簇,使簇內具有較高的相似度,而簇間的相似度較低。

k-means.png

k-means的算法流程

輸入:包含n個對象的數據和簇的數目k

(1) 隨機地選擇k個對象,它們初始地代表著k個簇的中心或者說平均值

(2) 對每個對象,根據其與各簇中心的距離,將它劃分給最近的簇

(3) 重新計算每個簇的平均值

(4) 重復步驟(2)、(3)知道簇中心不再變化

輸出:n個對象到k個簇,使平方誤差準則最小

平方誤差準則定義如下:

E = \sum\limits_{i=1}^k\sum\limits_{p\in C_i}||p - m_i||^2

這里E是數據中所有對象的平方誤差的總和,p是對象,m_i是簇的平均值,C_i是每個簇的對象集。該目標函數使生成的簇盡可能緊湊獨立,使用的距離度量是歐氏距離,當然也可以用其他距離度量。當平方誤差最小,簇中心不再變化,循環結束。

k-means算法的優缺點

優點:

? 簡單、速度快、適合發現球形聚類

缺點:

  1. k值不好選取,解決方案:可用GridSearch
  2. 對初始聚類中心敏感,解決方案:多初始化幾遍,選取損失函數小的
  3. 對噪音和異常值免疫能力差
  4. 不能解決非凸數據

DBSCAN

DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪聲的基于密度的聚類方法)是一種典型的基于密度的空間聚類算法。該算法將具有足夠密度的區域劃分為簇,并在具有噪聲的空間數據庫中發現任意形狀的簇,它將簇定義為密度相連的點的最大集合。

要理解DNSCAN算法的流程,首先要熟悉幾個概念:

  1. 算法需要給定兩個參數:鄰域半徑eps和密度閾值minPts。

    這兩個算法參數實際可以刻畫什么叫密集——當鄰域半徑eps內的點的個數大于密度閾值minPts時,就是密集。

  2. 3種點的類別:核心點,邊界點和噪聲點。

    鄰域半徑eps內樣本點的數量大于等于minPts的點叫做核心點。不屬于核心點但在某個核心點的鄰域內的點叫做邊界點。既不是核心點也不是邊界點的是噪聲點。

DBSCAN3種點的類別.jpg
  1. 4種點的關系:密度直達,密度可達,密度相連,非密度相連。

    如果P為核心點,Q在P的eps鄰域內,那么稱P到Q密度直達。任何核心點到其自身密度直達,密度直達不具有對稱性,如果P到Q密度直達,那么Q到P不一定密度直達。

    如果存在核心點P2,P3,……,Pn,且P1到P2密度直達,P2到P3密度直達,……,P(n-1)到Pn密度直達,Pn到Q密度直達,則P1到Q密度可達。密度可達也不具有對稱性。

    如果存在核心點S,使得S到P和Q都密度可達,則P和Q密度相連。密度相連具有對稱性,如果P和Q密度相連,那么Q和P也一定密度相連。密度相連的兩個點屬于同一個聚類簇。

    如果兩個點不屬于密度相連關系,則兩個點非密度相連。非密度相連的兩個點屬于不同的聚類簇,或者其中存在噪聲點。

DBSCAN4種點的關系.jpg

DBSCAN的算法流程

輸入:鄰域半徑eps,密度閾值minPts

(1) 掃描數據集中每點,如果某點p的eps鄰域半徑范圍內包含的點多于minPts個,則將其納入核心點列表,并將其密度直達的點形成對應的臨時聚類簇。

(2) 對于每一個臨時聚類簇,檢查其中的點是否為核心點,如果是,將該點對應的臨時聚類簇和當前臨時聚類簇合并,得到新的臨時聚類簇。重復此操作,直到當前臨時聚類簇中的每一個點要么不在核心點列表,要么其密度直達的點都已經在該臨時聚類簇,該臨時聚類簇升級成為聚類簇。最終所有臨時簇全部被處理為止。

輸出:簇的劃分結果

DBSCAN算法的優缺點

優點:

  1. 不需要指定簇的個數
  2. 可以發現任意形狀的簇
  3. 擅長找到離群點

缺點:

  1. 對于高維度數據不好處理
  2. 參數難以選擇

分層聚類

分層聚類(Hierarchical Clustering)是通過計算不同類別數據點間的相似度來創建一棵有層次的嵌套聚類樹。在聚類樹中,不同類別的原始數據點是樹的最低層,樹的頂層是一個聚類的根節點。創建聚類樹有自下而上合并(凝聚)和自上而下分裂兩種方法。

分層聚類的算法流程:

注:這里以自下而上凝聚的方法為例。

  1. 初始化,把每個樣本(假設一共N個樣本)各自歸為一類,計算每兩個類之間的距離,也就是樣本與樣本之間的相似度
  2. 尋找各個類之間最相近的兩個類,把他們歸為同一類
  3. 重新計算新生成的這個類與各個舊類之間的距離
  4. 重復(2)、(3)步驟,知道所有樣本都歸為一類,算法結束(當然,我們可以事先給定n_clusters參數,表示分成幾個聚類簇,當算法達到這個閾值時,迭代也會結束。)
分層聚類.gif

通過這張gif圖,就能更加清楚地看出分層聚類的工作流程了。

關于如何判斷兩個類之間的距離,也就是相似度,有不少辦法,這里介紹三種:

  1. Single Linkage

    Single Linkage方法是將兩個組合數據點中距離最近的兩個數據點間的距離作為這兩個組合數據點的距離。這種方法容易受到極端值的影響。兩個很相似的組合數據點可能由于其中的某個極端的數據點距離較近而組合在一起。

  2. Complete Linkage

    complete Linkage的計算方法與Single Linkage相反,將兩個組合數據點中距離最遠的兩個數據點間的距離作為這兩個組合數據點的距離。Complete Linkage的問題也與Single Linkage相反,兩個不相似的組合數據點可能由于其中的極端值距離較遠而無法組合在一起。

  3. Average Linkage

    Average Linkage的計算方法是計算兩個組合數據點中的每個數據點與其他所有數據點的距離。將所有距離的均值作為兩個組合數據點間的距離。這種方法計算量比較大,但結果比前兩種方法更合理。

分層算法的優缺點

優點:

  1. 可以發現類的層次關系
  2. 能幫助解決k-means不能解決的非凸數據

缺點:

  1. 時間復雜度高
  2. 貪心算法,一步錯步步錯

聚類模型評估

評價聚類方法分簇的最佳數量和分簇效果。

1.輪廓系數(silhouette coefficient)

輪廓系數綜合考慮了內聚度和分離度兩種因素。

樣本i輪廓系數:

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

a(i)表示樣本i與其所在簇內其他樣本的平均距離,b(i)表示樣本i與其他簇樣本的平均距離

聚類總的輪廓系數SC為:

SC = \frac{1}{N}\sum\limits_{i=1}^{N}s(i)

輪廓系數取值范圍為[-1,1],取值越接近1則說明聚類性能越好,相反,取值越接近-1則說明聚類性能越差。輪廓系數最高的簇的數量表示簇的數量的最佳選擇。

輪廓系數使用案例

  1. 準備數據
# 導包
import numpy as np
from sklearn import datasets
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from sklearn.metrics import silhouette_score

# 生成數據
X, y = datasets.make_blobs(random_state=100)    # make_blobs 默認100樣本,2個特征
print(X.shape)    # (100, 2)
plt.scatter(X[:, 0], X[:, 1], c=y)

生成的數據如下所示,從圖中可以看出分為3簇最好:

準備數據.png
  1. 計算輪廓系數
score = []
for i in range(2, 7):
    kmeans = KMeans(n_clusters = i)
    kmeans.fit(X)
    y_ = kmeans.predict(X)    # 預測類別 == 標簽

    print('當聚類類別數量是%d的時候,評價指標的輪廓系數是:'%i, silhouette_score(X, y_))
    score.append(silhouette_score(X, y_))

plt.rcParams['font.sans-serif'] = ['KaiTi']   # 用來正常顯示中文標簽
plt.rcParams['axes.unicode_minus'] = False  # 用來正常顯示負號
plt.rcParams['font.size'] = 18  # 設置字體大小
plt.plot(range(2,7), score)
plt.xlabel('K值')
plt.ylabel('輪廓系數')

得到如下結果:

當聚類類別數量是2的時候,評價指標的輪廓系數是: 0.6380785232724551
當聚類類別數量是3的時候,評價指標的輪廓系數是: 0.8353147343303
當聚類類別數量是4的時候,評價指標的輪廓系數是: 0.692708669793985
當聚類類別數量是5的時候,評價指標的輪廓系數是: 0.5318434130364085
當聚類類別數量是6的時候,評價指標的輪廓系數是: 0.3814586763403103

輪廓系數.png

當k值為3時,輪廓系數最高,聚類效果最好。

2.蘭德系數(adjusted rand index)

如果 C 是一個真實簇的標簽分配, K 是簇的個數,我們定義a和b為:

  • a,在 C 中的相同集合的與 K 中的相同集合中的元素對數
  • b,在 C 中的不同集合與 K 中的不同集合中的元素對數

蘭德系數為:

RI = \frac{a + b}{C_2^{n_{samples}}}

其中C_2^{n_{samples}}是數據集中可能的數據對的總數。RI取值范圍為[0,1],值越大意味著聚類結果與真實情況越吻合。

蘭德系數使用案例

  1. 準備數據

數據仍用上文輪廓系數的數據。

  1. 計算蘭德系數
from sklearn.metrics import adjusted_rand_score    # 蘭德系數

score2 = []
for i in range(2, 7):
    kmeans = KMeans(n_clusters = i)
    kmeans.fit(X)
    y_ = kmeans.predict(X)    # 預測類別 == 標簽

    print('當聚類類別數量是%d的時候,評價指標的蘭德系數是:'%i, adjusted_rand_score(y, y_))
    score2.append(adjusted_rand_score(y, y_))

plt.plot(range(2,7), score2)
plt.xlabel('K值')
plt.ylabel('蘭德系數')

得到如下結果:

當聚類類別數量是2的時候,評價指標的蘭德系數是: 0.5628321618378193
當聚類類別數量是3的時候,評價指標的蘭德系數是: 1.0
當聚類類別數量是4的時候,評價指標的蘭德系數是: 0.8704389719572353
當聚類類別數量是5的時候,評價指標的蘭德系數是: 0.7187670100598754
當聚類類別數量是6的時候,評價指標的蘭德系數是: 0.5789975932695749

蘭德系數.png

當k為3是,蘭德系數最大,聚類效果最好。

然而,RI得分不能保證隨機標簽分配(random label assignments)會獲得接近零的值(特別是如果簇的數量與樣本數量有著相同的規模排序)。

為了抵消這種影響,我們可以通過定義 adjusted Rand index 來低估(discount)隨機標簽的預期RI——E[RI],如下所示:

ARI = \frac{RI - E[RI]}{max(RI) - E[RI]}

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,755評論 2 371

推薦閱讀更多精彩內容

  • 聚類算法 前面介紹的集中算法都是屬于有監督機器學習方法,這章和前面不同,介紹無監督學習算法,也就是聚類算法。在無監...
    飄涯閱讀 41,416評論 3 52
  • 其他 這篇文章的整體排版主要是根據個人的博客來噠,如果感興趣的話可以去我的自己搭建的個人博客看這篇文章。 正文 聚...
    DeamoV閱讀 1,216評論 0 2
  • ??在《戰國策·齊策三》中有這么一句話:“物以類聚,人以群分”,用于比喻同類的東西常聚在一起,志同道合的人相聚成群...
    小小何先生閱讀 1,046評論 0 1
  • 1. 章節主要內容 “聚類”(clustering)算法是“無監督學習”算法中研究最多、應用最廣的算法,它試圖將數...
    閃電隨筆閱讀 5,058評論 1 24
  • 一瞬間的美好 只是短暫的 大多無用時有用
    無點有感閱讀 172評論 0 8