赞
踩
声明:本文修改自《数学建模清风》老师的代码
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法。与划分和层次聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇,并可在噪声的空间数据库中发现任意形状的聚类。
作为经典的聚类算法,DBSCAN聚类在数学建模竞赛中用到的概率很大。本文不详细展开讲解DBSCAN的原理,只介绍相关代码的使用步骤。
DBSCAN函数代码:
- function [IDX, isnoise]=DBSCAN(X,epsilon,MinPts)
-
- C=0;
-
- n=size(X,1);
- IDX=zeros(n,1); % 初始化全部为0,即全部为噪音点
-
- D=pdist2(X,X);
-
- 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
- % X(i,:) is NOISE
- 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]; %#ok
- 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);
- end
-
- end
绘制聚类图的代码:
- function PlotClusterinResult(X, IDX)
-
- k=max(IDX);
-
- Colors=hsv(k);
-
- 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)];
- 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;
- axis equal;
- grid on;
- legend(Legends);
- legend('Location', 'NorthEastOutside');
-
- end
接下来是主函数:
- clc;
- clear;
- close all;
-
- load mydata;
- %%注意,此处Data.mat用于导入自己的数据,数据名字要用X,或者在下方改变量名也可以
-
- if size(X,2)==2
- %%如果列数=2才可以运算
- epsilon=0.5;
- %%规定聚类半径
- MinPts=10;
- %%规定半径内最小数目点
-
- %%上面两个参数对聚类的结果很敏感,可以多次修改得出最好的结果
-
- IDX=DBSCAN(X,epsilon,MinPts);
- %%调用DBSCAN函数,输入参数有三个,分别是原始数据,聚类半径,最小数目点
- %%IDX用于保存每一项数据所属的聚类类别数目
-
- PlotClusterinResult(X, IDX);
- %%画出聚类结果图
- title(['DBSCAN Clustering (\epsilon = ' num2str(epsilon) ', MinPts = ' num2str(MinPts) ')']);
- else
- disp("请修改数据,DBCASN对二维聚类最佳!")
- end
如下是聚类结果:
使用要点:
前两个函数分别保存为独立的m文件,将其与主函数放置同一文件夹目录之下即可。此外,自己的数据要独立保存为.mat文件,也在同一目录之下。最后直接运行main函数即可。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。