机器学习 聚类篇——DBSCAN的参数选择及其应用于离群值检测
機器學(xué)習(xí) 聚類篇——DBSCAN的算法原理、參數(shù)選擇及其應(yīng)用于離群值檢測
- 摘要
- 1. DBSCAN算法原理
- 1.1 基本概念定義
- 1.2 算法流程
- 2. 參數(shù)選擇
- 2.1 領(lǐng)域半徑:Eps的選取方法(**k-distance函數(shù)**)
- 2.2 MinPts的選取方法
- 3. Python實現(xiàn)
- 4. 檢測離群值的實例
- 4.1 導(dǎo)包及設(shè)置隨機種子
- 4.2 生成moon數(shù)據(jù)并繪圖
- 4.3 選擇參數(shù)
- 4.4 建立聚類模型
- 4.5 可視化展示
摘要
DBSCAN(Density-Based Spatial Clustering of Applications with Noise) 為一種基于密度的聚類算法,本文主要介紹了DBSCAN算法的原理和參數(shù)選擇方法,并實現(xiàn)了一個離群值檢測案例,供讀者參考。
1. DBSCAN算法原理
1.1 基本概念定義
DBSCAN算法主要有兩個參數(shù):
領(lǐng)域半徑:Eps;
成為核心對象的在領(lǐng)域半徑內(nèi)的最少點數(shù):MinPts。
以上兩個參數(shù)都會在下面的概念介紹中提到。
-
Eps領(lǐng)域(Eps-neighborhood of a point)
點p的Eps鄰域,記為NEps(p),定義為NEps(p)= {q∈D | dist(p,q)≤Eps}。 -
核心對象 (core points)
如果給定對象Eps領(lǐng)域內(nèi)的樣本點數(shù)大于等于MinPts,則稱該對象為核心對象。 -
直接密度可達(directly density-reachable)
若:
1) p∈ NEps(q)
2)|NEps(q)| ≥ MinPts
則稱對象p從核心對象q是直接密度可達的。 -
密度可達(density-reachable)
對于對象p1,p2, …, pn;
令p1= q, pn = p。
若pi+1是從pi直接密度可達的,則稱p是從q密度可達的。 -
密度相連(density-connected)
對于點p和點q,若點p點q都是從點o密度可達的,則稱點p和點q密度相連。 -
簇(cluster)
對于數(shù)據(jù)集D,若C是其中一個簇,C中的點需要滿足以下兩個條件:
1)? p, q,如果 p∈ C且q 是從p密度可達的,則 q∈ C。
2)? p, q ∈ C,p和q是密度相連的。 -
噪音(noise)
不屬于任何簇的點為噪音數(shù)據(jù)。
1.2 算法流程
- 1)給定領(lǐng)域半徑:Eps和成為核心對象的在領(lǐng)域半徑內(nèi)的最少點數(shù):MinPts。
- 2)從任意點p開始,將其標(biāo)記為”visited“,檢查其是否為核心點(即p的Eps鄰域至少有MinPts個對象),如果不是核心點,則將其標(biāo)記為噪聲點。否則為p創(chuàng)建一個新的簇C,并且把把p的Eps鄰域中的所有對象都放到候選集合N中。
- -3)迭代地把N中不屬于其它簇的對象添加至C中,在此過程中,對于N中標(biāo)記為”unvisited"的對象p‘,把它標(biāo)記為“visited”,并且檢查它的Eps鄰域,如果p’也為核心對象,則p’的Eps鄰域中的對象都被添加至N中。繼續(xù)添加對象至C中,直到C不能擴展,即直到N為空。此時,簇C完全生成。
- 4)從剩余的對象中隨機選擇下一個未訪問對象,重復(fù)3)的過程,直到所有對象都被訪問。
2. 參數(shù)選擇
2.1 領(lǐng)域半徑:Eps的選取方法(k-distance函數(shù))
- 1)選取k值,建議取k為2*維度-1。(其中維度為特征數(shù))
- 2) 計算并繪制k-distance圖。(計算出每個點到距其第k近的點的距離,然后將這些距離從大到小排序后進行繪圖。)
- 3)找到拐點位置的距離,即為Eps的值。
如下圖所示:
2.2 MinPts的選取方法
- MinPts的取值為上述k值加1,即:
MinPts=k+1MinPts = k+1 MinPts=k+1
3. Python實現(xiàn)
鏈接: 參考我的另一篇博客.
4. 檢測離群值的實例
4.1 導(dǎo)包及設(shè)置隨機種子
import numpy as np from sklearn.datasets import make_moons import matplotlib.pyplot as plt from sklearn.cluster import DBSCANnp.random.seed(2021)4.2 生成moon數(shù)據(jù)并繪圖
data = np.ones([1005,2]) data[:1000] = make_moons(n_samples=1000,noise=0.05,random_state=2022)[0] data[1000:] = [[-1,-0.5],[-0.5,-1],[-1,1.5],[2.5,-0.5],[2,1.5]] print(data.shape) plt.scatter(data[:,0],data[:,1],color="c") plt.show()4.3 選擇參數(shù)
def select_MinPts(data,k):k_dist = []for i in range(data.shape[0]):dist = (((data[i] - data)**2).sum(axis=1)**0.5)dist.sort()k_dist.append(dist[k])return np.array(k_dist) k = 3 # 此處k取 2*2 -1 k_dist = select_MinPts(data,k) k_dist.sort() plt.plot(np.arange(k_dist.shape[0]),k_dist[::-1])
有明顯拐點
4.4 建立聚類模型
dbscan_model = DBSCAN(eps=eps,min_samples=k+1) label = dbscan_model.fit_predict(data) print(label) [ 0 0 0 ... -1 -1 -1]4.5 可視化展示
class_1 = [] class_2 = [] noise = [] for index,value in enumerate(label):if value == 0:class_1.append(index)elif value == 1:class_2.append(index)elif value == -1:noise.append(index) plt.scatter(data[class_1,0],data[class_1,1],color="g",label="class 1") plt.scatter(data[class_2,0],data[class_2,1],color="b",label = "class 2") plt.scatter(data[noise,0],data[noise,1],color="r",label = "noise") plt.legend() plt.show()by CyrusMay 2021 02 03
你和我背著空空的書包
逃出名為日常的監(jiān)牢
忘了要長大
忘了要變老
忘了時間有腳
——————五月天(好好)——————
總結(jié)
以上是生活随笔為你收集整理的机器学习 聚类篇——DBSCAN的参数选择及其应用于离群值检测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Git篇——Git使用教程
- 下一篇: python进阶 多线程编程 —— th