用R語言實現密度聚類dbscan (下)

歡迎關注天善智能,我們是專注於商業智能BI,人工智能AI,大數據分析與挖掘領域的垂直社區,學習,問答、求職一站式搞定!

對商業智能BI、大數據分析挖掘、機器學習,python,R等數據領域感興趣的同學加微信:tstoutiao,邀請你進入數據愛好者交流群,數據愛好者們都在這兒。

作者:張丹,R語言中文社區專欄特邀作者,《R的極客理想》系列圖書作者,民生銀行大數據中心數據分析師,前況客創始人兼CTO。

個人博客 http://fens.me, Alexa全球排名70k。

下面我們通過繪製k-距離曲線,尋找knee,即明顯拐點位置為對應較好的參數,找到適合的eps值。使用kNNdistplot()函數,讓參數k=dim + 1,dim為數據集列的個數,iris2是4列,那麼設置k=5。

1# 畫出最近距離圖
2> kNNdistplot(iris2, k = 5)
3> abline(h=0.5, col = "red", lty=2)


用R語言實現密度聚類dbscan (下)


kNNdistplot()會計算點矩陣中的k=5的最近鄰的距離,然後按距離從小到大排序後,以圖形進行展示。x軸為距離的序號,y軸為距離的值。圖中黑色的線,從左到右y值越來越大。

通過人眼識別,k-距離曲線上有明顯拐點,我們以y=0.5平行於x軸畫一條紅色線,突出標識。所以,最後確認的eps為0.5。

調用dbscan()函數,進行對iris2數據集進行聚類,eps=0.5,minPts=5。

 1> res  2> res
3DBSCAN clustering for 150 objects.
4Parameters: eps = 0.5, minPts = 5
5The clustering contains 2 cluster(s) and 17 noise points.
6
7 0 1 2
817 49 84
9
10Available fields: cluster, eps, minPts

聚類後,一共分成了2組,第1組49個值,第2組84個值,另外,第0組17個值為噪聲點。把聚類的結果畫圖展示。

1> pairs(iris, col = res$cluster + 1L)


用R語言實現密度聚類dbscan (下)


數據集是多列的,把每2列組合形成的二維平面,都進行輸出。紅色點表示第1組,綠色點表示為第2組,黑色點表示噪聲點。這樣就完成了有噪聲的基於密度的dbscan聚類。

五、hdbscan()函數使用

hdbscan(),快速實現了分層DBSCAN算法,與stats包中的hclust()方法形成的傳統分層聚類方法類似。

函數定義:

1hdbscan(x, minPts, xdist = NULL,gen_hdbscan_tree = FALSE, gen_simplified_tree = FALSE)

參數解釋:

  • x,矩陣或者距離對象
  • minPts,區域中的最小點數量
  • xdist,dist對象,可以提前算出來,當參數傳入
  • gen_hdbscan_tree,生成一個hdbscan樹
  • gen_simplified_tree,生成一個簡化的樹結構

3.1 iris鳶尾花的數據集

以iris鳶尾花的數據集,做為樣本,去掉種屬列。設置minPts =5讓當前群集中最小的數量為5,開始聚類。

1> hcl2HDBSCAN clustering for 150 objects.
3Parameters: minPts = 5
4The clustering contains 2 cluster(s) and 0 noise points.
5
6 1 2
7100 50
8
9Available fields: cluster, minPts, cluster_scores, membership_prob, outlier_scores, hc


聚類後,一共分成了2組,第1組100個值,第2組50個值,沒有噪聲點。生成的hcl對象包括6個屬性。

屬性解釋

  • cluster,表明屬性哪個群集,零表示噪聲點。
  • minPts,群集中最小的數量
  • cluster_scores,每個突出(“平坦”)群集的穩定性分數之和。
  • membership_prob,群集內某點的“概率”或個體穩定性
  • outlier_scores,每個點的異常值
  • hc,層次結構對象

把聚類的結果畫圖展示。

1> plot(iris2, col=hcl$cluster+1, pch=20)


用R語言實現密度聚類dbscan (下)


數據集是多列的,把每2列組合形成的二維平面,都進行輸出。紅色點表示第1組,綠色點表示為第2組,這樣就完成了hdbscan聚類。

打印hcl對象層次結構,包括150個數據,聚法方法是健壯單一的,距離是相互可達。

1> hcl$hc
2
3Call:
4hdbscan(x = iris2, minPts = 5)
5
6Cluster method : robust single
7Distance : mutual reachability
8Number of objects: 150


畫出層次的合併過程圖

1> plot(hcl$hc, main="HDBSCAN* Hierarchy")


用R語言實現密度聚類dbscan (下)


從圖可以清楚的看出,主要的2類的分支,區分度比較高。

3.2 moons數據集

由於iris數據集用hdbscan聚類獲得的結果,與真實的數據分類結果不一致。我們再用dbscan包自帶的數據集moons做一下測試。

先準備數據,加載moons數據集,瞭解數據基本情況,畫出散點圖。

 1# 加載dbscan自帶數據集
2> data("moons")
3> head(moons)
4 X Y
51 -0.41520756 1.0357347
62 0.05878098 0.3043343
73 1.10937860 -0.5097378
84 1.54094828 -0.4275496
95 0.92909498 -0.5323878
106 -0.86932470 0.5471548
11
12# 畫出散點圖
13> plot(moons, pch=20)


用R語言實現密度聚類dbscan (下)


用hdbscan()函數,實現層次dbscan算法。

 1> cl  2> cl
3HDBSCAN clustering for 100 objects.
4Parameters: minPts = 5
5The clustering contains 3 cluster(s) and 0 noise points.
6
7 1 2 3
825 25 50
9
10Available fields: cluster, minPts, cluster_scores, membership_prob, outlier_scores, hc


一共100條數據,被分成了3類,沒有噪聲。把聚類的結果畫圖展示。

1# 畫圖
2> plot(moons, col=cl$cluster+1, pch=20)



用R語言實現密度聚類dbscan (下)


打印層次結構

1> cl$hc
2Call:
3hdbscan(x = moons, minPts = 5)
4
5Cluster method : robust single
6Distance : mutual reachability
7Number of objects: 100


畫出層次的合併過程圖

1> plot(cl$hc, main="HDBSCAN* Hierarchy")


用R語言實現密度聚類dbscan (下)


從圖可以清楚的看出,主要的3類的分支,區分度比較高。

如果我們想省略分層的細節,我們可以只畫出主要分支,並標識類別。

1plot(cl, gradient = c("purple", "blue", "green", "yellow"), show_flat = T)


用R語言實現密度聚類dbscan (下)



接下來,我們要對群集的穩定性做一些優化,cluster_scores屬性可以查看集群的得分。

1> cl$cluster_scores
2 1 2 3
3110.70613 90.86559 45.62762


通過membership_prob屬性,畫圖表示個體的穩定性。

 1# 打印membership_prob
2> head(cl$membership_prob)
3[1] 0.4354753 0.2893287 0.4778663 0.4035933 0.4574012 0.4904582
4
5# 計算群集的數量
6> num 7
8# 從彩虹色中取得對應數量的顏色
9> rains10> cols11> cols[which(cols==1)]12> cols[which(cols==2)]13> cols[which(cols==3)]14
15# 設置透明度,表示個體的穩定性
16> plot(moons, col=alpha(cols,cl$membership_prob), pch=19)



用R語言實現密度聚類dbscan (下)


最後,我們可以在圖中,在標記出異常值得分最高的前6個點。

1# 對異常值進行排序,取得分最高的
2> top_outliers % head
3> plot(moons, col=alpha(cols,cl$outlier_scores), pch=19)
4> text(moons[top_outliers, ], labels = top_outliers, pos=3)


用R語言實現密度聚類dbscan (下)


從圖中看到,異常得分高的點(outlier_scores)與個體的穩定性(membership_prob),並不是同一類點。異常值通常被認為是,偏離其假定的基礎分佈的離群點。

在最後

通過上面3個函數的使用案例,我們瞭解瞭如何用dbscan包實現基於密度的聚類方法。真實世界的數據是複雜的,我們用來分析數據的工具也是多樣的,多掌握一種工具、多一些知識積累,讓我們迎接真實世界數據的挑戰吧。



用R語言實現密度聚類dbscan (下)


往期精彩:

  • R語言實現46種距離算法
  • R語言中文社區2018年終文章整理(作者篇)
  • R語言中文社區2018年終文章整理(類型篇)
用R語言實現密度聚類dbscan (下)

回覆 爬蟲 爬蟲三大案例實戰

回覆 Python 1小時破冰入門

回覆 數據挖掘 R語言入門及數據挖掘

回覆 人工智能 三個月入門人工智能

回覆 數據分析師 數據分析師成長之路

回覆 機器學習 機器學習的商業應用

回覆 數據科學 數據科學實戰

回覆 常用算法 常用數據挖掘算法


分享到:


相關文章: