本文基于MATLAB官网提供的DBSCAN算法进行修改,帮助小伙伴更好的理解,代码已添加上相应的注释。
DBSCAN Clustering Algorithm - File Exchange - MATLAB Central
主函数(运行该函数即可)
clc;
clear;
close all;
%% 随机生成数据
X = rand(100, 2); % 可替换为自己的数据
D = pdist2(X, X);
%% 运行 DBSCAN
epsilon = 0.15;
MinPts = 10;
IDX = DBSCAN(D,epsilon,MinPts);
%% 绘制结果
PlotClusterinResult(X, IDX);
title(['DBSCAN Clustering (\epsilon = ' num2str(epsilon) ', MinPts = ' num2str(MinPts) ')']);
子函数1
function [IDX, isnoise]=DBSCAN(D,epsilon,MinPts)
C=0;
n=size(D,1);
IDX=zeros(n,1); % 所属cluster
visited=false(n,1); % 初始化访问矩阵
isnoise=false(n,1); % 是否是噪声点
for i=1:n
if ~visited(i)
visited(i)=true;
Neighbors=RegionQuery(i); % 获取邻域
if numel(Neighbors)<MinPts % 判断是否是噪声点
isnoise(i)=true;
else
C=C+1;
ExpandCluster(i,Neighbors,C);
end
end
end
function ExpandCluster(i,Neighbors,C)
IDX(i)=C;
k = 1;
while true
j = Neighbors(k);
if ~visited(j)
visited(j)=true;
Neighbors2=RegionQuery(j);
if numel(Neighbors2)>=MinPts
Neighbors=[Neighbors Neighbors2];
end
end
if IDX(j)==0
IDX(j)=C;
end
k = k + 1;
if k > numel(Neighbors)
break;
end
end
end
function Neighbors=RegionQuery(i)
Neighbors=find(D(i,:)<=epsilon); % 找到所有距离小于epsilon的点(包括自身)
end
end
子函数2
function PlotClusterinResult(X, IDX)
k=max(IDX);
Colors=hsv(k); % 生成hsv颜色空间的颜色映射矩阵
Legends = {};
for i=0:k
Xi=X(IDX==i,:);
if i~=0
Style = 'x';
MarkerSize = 8;
Color = Colors(i,:);
Legends{end+1} = ['Cluster #' num2str(i)]; % 所属cluster
else
Style = 'o';
MarkerSize = 6;
Color = [0 0 0];
if ~isempty(Xi)
Legends{end+1} = 'Noise'; % 标注"噪点"
end
end
if ~isempty(Xi)
plot(Xi(:,1),Xi(:,2),Style,'MarkerSize',MarkerSize,'Color',Color);
end
hold on;
end
hold off;
grid on;
legend(Legends, 'Location', 'northoutside');
end
基于rand函数随机生成数据,运行结果如下:
Over!