python實(shí)現(xiàn)dbscan算法
DBSCAN 算法是一種基于密度的空間聚類算法。該算法利用基于密度的聚類的概念,即要求聚類空間中的一定區(qū)域內(nèi)所包含對(duì)象(點(diǎn)或其它空間對(duì)象)的數(shù)目不小于某一給定閥值。DBSCAN 算法的顯著優(yōu)點(diǎn)是聚類速度快且能夠有效處理噪聲點(diǎn)和發(fā)現(xiàn)任意形狀的空間聚類。但是由于它直接對(duì)整個(gè)數(shù)據(jù)庫(kù)進(jìn)行操作且進(jìn)行聚類時(shí)使用了一個(gè)全局性的表征密度的參數(shù),因此也具有兩個(gè)比較明顯的弱點(diǎn):
1. 當(dāng)數(shù)據(jù)量增大時(shí),要求較大的內(nèi)存支持 I/0 消耗也很大;
2. 當(dāng)空間聚類的密度不均勻、聚類間距離相差很大時(shí),聚類質(zhì)量較差。
DBSCAN算法的聚類過(guò)程
DBSCAN算法基于一個(gè)事實(shí):一個(gè)聚類可以由其中的任何核心對(duì)象唯一確定。等價(jià)可以表述為: 任一滿足核心對(duì)象條件的數(shù)據(jù)對(duì)象p,數(shù)據(jù)庫(kù)D中所有從p密度可達(dá)的數(shù)據(jù)對(duì)象所組成的集合構(gòu)成了一個(gè)完整的聚類C,且p屬于C。
先上結(jié)果
大致流程
先根據(jù)給定的半徑 r 確定中心點(diǎn),也就是這類點(diǎn)在半徑r內(nèi)包含的點(diǎn)數(shù)量 n 大于我們的要求(n>=minPionts)
然后遍歷所有的中心點(diǎn),將互相可通達(dá)的中心點(diǎn)與其包括的點(diǎn)分為一組
全部分完組之后,沒(méi)有被納入任何一組的點(diǎn)就是離群點(diǎn)啦!
導(dǎo)入相關(guān)依賴
import numpy as np import matplotlib.pyplot as plt from sklearn import datasets
求點(diǎn)跟點(diǎn)之間距離(歐氏距離)
def cuircl(pointA,pointB): distance = np.sqrt(np.sum(np.power(pointA - pointB,2))) return distance
求臨時(shí)簇,即確定所有的中心點(diǎn),非中心點(diǎn)
def firstCluster(dataSets,r,include): cluster = [] m = np.shape(dataSets)[0] ungrouped = np.array([i for i in range (m)]) for i in range (m): tempCluster = [] #第一位存儲(chǔ)中心點(diǎn)簇 tempCluster.append(i) for j in range (m): if (cuircl(dataSets[i,:],dataSets[j,:]) < r and i != j ): tempCluster.append(j) tempCluster = np.mat(np.array(tempCluster)) if (np.size(tempCluster)) >= include: cluster.append(np.array(tempCluster).flatten()) #返回的是List center=[] n = np.shape(cluster)[0] for k in range (n): center.append(cluster[k][0]) #其他的就是非中心點(diǎn)啦 ungrouped = np.delete(ungrouped,center) #ungrouped為非中心點(diǎn) return cluster,center,ungrouped
將所有中心點(diǎn)遍歷并進(jìn)行聚集
def clusterGrouped(tempcluster,centers): m = np.shape(tempcluster)[0] group = [] #對(duì)應(yīng)點(diǎn)是否遍歷過(guò) position = np.ones(m) unvisited = [] #未遍歷點(diǎn) unvisited.extend(centers) #所有點(diǎn)均遍歷完畢 for i in range (len(position)): coreNeihbor = [] result = [] #刪除第一個(gè) #刨去自己的鄰居結(jié)點(diǎn),這一段就類似于深度遍歷 if position[i]: #將鄰結(jié)點(diǎn)填入 coreNeihbor.extend(list(tempcluster[i][:])) position[i] = 0 temp = coreNeihbor #按照深度遍歷遍歷完所有可達(dá)點(diǎn) #遍歷完所有的鄰居結(jié)點(diǎn) while len(coreNeihbor) > 0 : #選擇當(dāng)前點(diǎn) present = coreNeihbor[0] for j in range(len(position)): #如果沒(méi)有訪問(wèn)過(guò) if position[j] == 1: same = [] #求所有的可達(dá)點(diǎn) if (present in tempcluster[j]): cluster = tempcluster[j].tolist() diff = [] for x in cluster: if x not in temp: #確保沒(méi)有重復(fù)點(diǎn) diff.append(x) temp.extend(diff) position[j] = 0 # 刪掉當(dāng)前點(diǎn) del coreNeihbor[0] result.extend(temp) group.append(list(set(result))) i +=1 return group
核心算法完畢!
生成同心圓類型的隨機(jī)數(shù)據(jù)進(jìn)行測(cè)試
#生成非凸數(shù)據(jù) factor表示內(nèi)外圈距離比 X,Y1 = datasets.make_circles(n_samples = 1500, factor = .4, noise = .07) #參數(shù)選擇,0.1為圓半徑,6為判定中心點(diǎn)所要求的點(diǎn)個(gè)數(shù),生成分類結(jié)果 tempcluster,center,ungrouped = firstCluster(X,0.1,6) group = clusterGrouped(tempcluster,center) #以下是分類后對(duì)數(shù)據(jù)進(jìn)行進(jìn)一步處理 num = len(group) voice = list(ungrouped) Y = [] for i in range (num): Y.append(X[group[i]]) flat = [] for i in range(num): flat.extend(group[i]) diff = [x for x in voice if x not in flat] Y.append(X[diff]) Y = np.mat(np.array(Y))
繪圖~
color = ['red','blue','green','black','pink','orange'] for i in range(num): plt.scatter(Y[0,i][:,0],Y[0,i][:,1],c=color[i]) plt.scatter(Y[0,-1][:,0],Y[0,-1][:,1],c = 'purple') plt.show()
結(jié)果
紫色點(diǎn)就是離散點(diǎn)
到此這篇關(guān)于python實(shí)現(xiàn)dbscan算法的文章就介紹到這了,更多相關(guān)python dbscan算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python常用時(shí)間庫(kù)time、datetime與時(shí)間格式之間的轉(zhuǎn)換教程
Python項(xiàng)目中很多時(shí)候會(huì)需要將時(shí)間在Datetime格式和TimeStamp格式之間轉(zhuǎn)化,下面這篇文章主要給大家介紹了關(guān)于python常用時(shí)間庫(kù)time、datetime與時(shí)間格式之間轉(zhuǎn)換的相關(guān)資料,需要的朋友可以參考下2023-02-02pycharm 在debug循環(huán)時(shí)快速debug到指定循環(huán)次數(shù)的操作方法
在 PyCharm 中,可以使用條件斷點(diǎn)來(lái)實(shí)現(xiàn)在特定循環(huán)次數(shù)后停止調(diào)試,本文重點(diǎn)介紹pycharm 在debug循環(huán)時(shí)快速debug到指定循環(huán)次數(shù)的操作方法,需要的朋友可以參考下2024-04-04將Python的Django框架與認(rèn)證系統(tǒng)整合的方法
這篇文章主要介紹了將Python的Django框架與認(rèn)證系統(tǒng)整合的方法,包括指定認(rèn)證后臺(tái)和編寫認(rèn)證后臺(tái)等內(nèi)容,需要的朋友可以參考下2015-07-07python機(jī)器學(xué)習(xí)MATLAB最小二乘法的兩種解讀
這篇文章主要為大家介紹了python機(jī)器學(xué)習(xí)中MATLAB最小二乘法的兩種解讀方式,有需要的朋友可以借鑒參考下希望能夠有所幫助2022-02-02Python使用Matplotlib繪制三維散點(diǎn)圖詳解流程
matplotlib是基建立在python之上,適用于創(chuàng)建靜態(tài),動(dòng)畫(huà)和交互式可視化,通常與數(shù)據(jù)分析模塊pandas搭配使用,用于數(shù)據(jù)的分析和展示,適用于主流的操作系統(tǒng),如Linux、Win、Mac2022-11-11使用Python獲取當(dāng)前工作目錄和執(zhí)行命令的位置
這篇文章主要介紹了使用Python獲取當(dāng)前工作目錄和執(zhí)行命令的位置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03Pandas把dataframe或series轉(zhuǎn)換成list的方法
這篇文章主要介紹了Pandas把dataframe或series轉(zhuǎn)換成list的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06