MATLAB DBSCAN


DBSCAN全稱Density-Based Spatial Clustering of Applications with Noise,是一種密度聚類算法。

和Kmeans相比,不需要事先知道數據的類數。

以編程的角度來考慮,具體算法流程如下:

1.首先選擇一個待處理數據。

2.尋找和待處理數據距離在設置半徑內的數據。

3.將找到的半徑內的數據放到一個隊列中。

4.拿隊列頭數據作為當前待處理數據並不斷執行第2步。

5.直到遍歷完隊列中所有數據,將這些數據記為一類。

6.選擇沒有處理到的數據作為一個待處理數據執行第2步。

7.直到遍歷完所有數據,算法結束。

大概就是下圖所示的樣子:

我這里沒有單獨輸出離群點,不過稍微改進增加離群點個數判斷閾值應該就可以,比較容易修改。

代碼如下:

 1 clear all;  2 close all;  3 clc;  4 
 5 theta=0:0.01:2*pi;  6 p1=[3*cos(theta) + rand(1,length(theta))/2;3*sin(theta)+ rand(1,length(theta))/2];      %生成測試數據  7 p2=[2*cos(theta) + rand(1,length(theta))/2;2*sin(theta)+ rand(1,length(theta))/2];  8 p3=[cos(theta) + rand(1,length(theta))/2;sin(theta)+ rand(1,length(theta))/2];  9 p=[p1 p2 p3]';
10 
11 randIndex = randperm(length(p))'; %打亂數據順序
12 p=p(randIndex,:); 13 plot(p(:,1),p(:,2),'.') 14 
15 flag = zeros(length(p),1);      %聚類標記 16 clsnum = 0;                     %類的個數 17 disnear = 0.3;                 %聚類半徑 18 
19 for i=1:length(p) 20     nxtp = p(i,:);      %初始聚類半徑內的鄰域點隊列 21     if flag(i)==0
22         clsnum = clsnum+1; 23         pcstart = 1;            %設置隊列起始指針 24         preflag = flag;         %聚類標記更新 25         while pcstart<=length(nxtp)         %判斷是否完成隊列遍歷 26             curp = nxtp(pcstart,:);         %得到當前要處理的點 27             pcstart = pcstart+1;            %隊列指針更新 28             diffp = p-curp;                 %這里直接和所有數據比較了,數據量大的時候可以考慮kdtree 29             dis = sqrt(diffp(:,1).*diffp(:,1)+diffp(:,2).*diffp(:,2));      %判斷當前點與所有點之間的距離 30 
31             ind = dis<disnear;                  %得到距離小於閾值的索引 32             flag(ind) = clsnum;                 %設置當前聚類標記 33             
34             diff_flag = preflag-flag; 35             diff_ind = (preflag-flag)<0;        %判斷本次循環相比上次循環增加的點 36             
37             tmp = zeros(length(p),1); 38             tmp(diff_ind) = clsnum; 39             flag = flag + tmp;                  %增加的點將其標記為一類 40             preflag = flag;                 %聚類標記更新 41             nxtp = [nxtp;p(diff_ind,:)];    %增加聚類半徑內的鄰域點隊列 42  end 43  end 44 end 45 %聚類可能不止三組,我偷懶不想判斷並plot了 46 figure; 47 plot(p(flag==1,1),p(flag==1,2),'r.') 48 hold on; 49 plot(p(flag==2,1),p(flag==2,2),'g.') 50 plot(p(flag==3,1),p(flag==3,2),'b.')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM