基於密度的聚類之Dbscan演算法

2021-09-07 00:19:05 字數 4034 閱讀 3134

該演算法利用基於密度的聚類的概念,即要求聚類空間中的一定區域內所包含物件(點或其他空間物件)的數目不小於某一給定閾值。dbscan演算法的顯著優點是聚類速度快且能夠有效處理雜訊點和發現任意形狀的空間聚類。但是由於它直接對整個資料庫進行操作且進行聚類時使用了乙個全域性性的表徵密度的引數,因此也具有兩個比較明顯的弱點:

(1)當資料量增大時,要求較大的記憶體支援i/o消耗也很大;

(2)當空間聚類的密度不均勻、聚類間距差相差很大時,聚類質量較差(有些簇內距離較小,有些簇內距離很大,但是eps是確定的,所以,大的點可能被誤判斷為離群點或者邊界點,如果eps太大,那麼小距離的醋內,可能會包含一些離群點或者邊界點,knn的k也存在同樣的問題)。

(1)與k-means比較起來,不需要輸入要劃分的聚類個數;

(2)聚類簇的形狀沒有偏倚(這個不明白啥意思);

(3)可以在需要時輸入過濾雜訊的引數;

dbscan演算法基於乙個事實:乙個聚類可以由其中的任何核心物件唯一確定。等價可以表述為:任一滿足核心物件條件的資料物件p,資料庫d中所有從p密度可達的資料物件o所組成的集合構成了乙個完整的聚類c,且p屬於c。

%% 匯入資料集

% data = load('testdata.txt');

data = randn(50,2);

% 定義引數eps和minpts

minpts = 5;

eps = epsilon(data, minpts);

[m,n] = size(data);%得到資料的大小

x = [(1:m)' data];

[m,n] = size(x);%重新計算資料集的大小

types = zeros(1,m);%用於區分核心點1,邊界點0和噪音點-1

dealed = zeros(m,1);%用於判斷該點是否處理過,0表示未處理過

dis = caldistance(x(:,2:n));

number = 1;%用於標記類

%% 對每乙個點進行處理

for i = 1:m

%找到未處理的點

if dealed(i) == 0

xtemp = x(i,:);

d = dis(i,:);%取得第i個點到其他所有點的距離

ind = find(d<=eps);%找到半徑eps內的所有點

%% 區分點的型別

%邊界點

if length(ind) > 1 && length(ind) < minpts+1

types(i) = 0;

class(i) = 0;

end%噪音點

if length(ind) == 1

types(i) = -1;

class(i) = -1;

dealed(i) = 1;

end%核心點(此處是關鍵步驟)

if length(ind) >= minpts+1

types(xtemp(1,1)) = 1;

class(ind) = number;

% 判斷核心點是否密度可達

while ~isempty(ind)

ytemp = x(ind(1),:);

dealed(ind(1)) = 1;

ind(1) = ;

d = dis(ytemp(1,1),:);%找到與ind(1)之間的距離

ind_1 = find(d<=eps);

if length(ind_1)>1%處理非噪音點

class(ind_1) = number;

if length(ind_1) >= minpts+1

types(ytemp(1,1)) = 1;

else

types(ytemp(1,1)) = 0;

endfor j=1:length(ind_1)

if dealed(ind_1(j)) == 0

dealed(ind_1(j)) = 1;

ind=[ind ind_1(j)];

class(ind_1(j))=number;

end

endend

endnumber = number + 1;

endend

end% 最後處理所有未分類的點為噪音點

ind_2 = find(class==0);

class(ind_2) = -1;

types(ind_2) = -1;

%% 畫出最終的聚類圖

hold on

for i = 1:m

if class(i) == -1

plot(data(i,1),data(i,2),'.r');

elseif class(i) == 1

if types(i) == 1

plot(data(i,1),data(i,2),'+b');

else

plot(data(i,1),data(i,2),'.b');

endelseif class(i) == 2

if types(i) == 1

plot(data(i,1),data(i,2),'+g');

else

plot(data(i,1),data(i,2),'.g');

endelseif class(i) == 3

if types(i) == 1

plot(data(i,1),data(i,2),'+c');

else

plot(data(i,1),data(i,2),'.c');

endelse

if types(i) == 1

plot(data(i,1),data(i,2),'+k');

else

plot(data(i,1),data(i,2),'.k');

endend

endhold off

麼麼噠.............

%% 計算矩陣中點與點之間的距離

function [ dis ] = caldistance( x )

[m,n] = size(x);

dis = zeros(m,m);

for i = 1:m

for j = i:m

%計算點i和點j之間的歐式距離

tmp =0;

for k = 1:n

tmp = tmp+(x(i,k)-x(j,k)).^2;

enddis(i,j) = sqrt(tmp);

dis(j,i) = dis(i,j);

endend

end

麼麼噠.............

function [eps]=epsilon(x,k)

% function: [eps]=epsilon(x,k)

%% aim:

% analytical way of estimating neighborhood radius for dbscan

%% input:

% x - data matrix (m,n); m-objects, n-variables

% k - number of objects in a neighborhood of an object

% (minimal number of objects considered as a cluster)

[m,n]=size(x);

eps=((prod(max(x)-min(x))*k*gamma(.5*n+1))/(m*sqrt(pi.^n))).^(1/n);

注意:prod是陣列內元素的乘積,a^n是a*a*....*a,a.^n是a中每個元素的n次方。

DBSCAN基於密度的聚類演算法

1.密度 密度指的是在某距離內含有物件的最小數目。2.核心物件 如果乙個物件的eps鄰域內至少包含minpt個物件,則稱該物件是核心物件。3.直接密度可達 給定乙個物件集合d,如果p在q的eps鄰域內,並且q是乙個核心物件,則p是從q直接密度可達的。如下圖所示 eps可以想象為乙個超球體的半徑,mi...

基於密度的聚類演算法DBSCAN

可以發現,密度可達是直接密度可達的傳遞閉包,並且這種關係是非對稱的。密度相連是對稱關係。dbscan目的是找到密度相連物件的最大集合。eg 假設半徑 3,minpts 3,點p的e領域中有點,點m的e領域中有點,點q的e領域中有點,點o的e領域中有點,點s的e領域中有點.那麼核心物件有p,m,o,s...

DBSCAN 密度聚類

dbscan 密度聚類 dbscan演算法是一種基於密度的聚類演算法 聚類的時候不需要預先指定簇的個數 最終的簇的個數不定 dbscan演算法將資料點分為三類 核心點 在半徑eps內含有超過minpts數目的點 邊界點 在半徑eps內點的數量小於minpts,但是落在核心點的鄰域內 噪音點 既不是核...