DBSCAN算法有2个关键的输入参数
- 指定的最小点数MinPts
- 半径Eps
聚类时将数据点看成3类数据
- 核心点数据:在半径Eps内点数>MintPts
- 边界点数据:在半径Eps内点数<MintPts,但是数据点落在核心点邻域
- 噪音点数据:既不是核心点,也不是边界点的数据
基于距离的聚类算法和基于密度的聚类算法有何异同?
基于密度的聚类算法主要的目标是寻找被低密度区域分离的高密度区域。与基于距离的聚类算法不同的是,基于距离的聚类算法的聚类结果是球状的簇,而基于密度的聚类算法可以发现任意形状的聚类,这对于带有噪音点的数据起着重要的作用。
制作分类测试的数据集
附上我自己做的数据集
链接:https://pan.baidu.com/s/1O-0M-OsJEI7cLHLKHu4YNA
提取码:d13k
利用Excel随机生成200*3个数据点(但是这些数据点是随机的,似乎没有类别的不同),于是我利用三个公式产生不同范围的数据。第一类数据(第一列)数据大小范围在50-90之间,第二类数据大小大30-60之间,第三类数据大小在10-30之间。
另存为文本文件
代码
主函数
clc;clear all;
data=load('300point2.txt');
MinPts = 6;%点数不同,结果也有区别
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;
end
for 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
end
end
end
number=number+1;
end
end
end
% 最后处理所有未分类的点为噪音点
ind_2 = find(class==0);
class(ind_2) = -1;
types(ind_2) = -1;
%% 画出最终的聚类图
figure(1);
plot(data(:,1),data(:,2),'.r');
figure(2);
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),'pb');
else
plot(data(i,1),data(i,2),'ob');
end
elseif class(i) == 2
if types(i) == 1
plot(data(i,1),data(i,2),'pg');
else
plot(data(i,1),data(i,2),'og');
end
elseif class(i) == 3
if types(i) == 1
plot(data(i,1),data(i,2),'pc');
else
plot(data(i,1),data(i,2),'oc');
end
else
if types(i) == 1
plot(data(i,1),data(i,2),'pk');
else
plot(data(i,1),data(i,2),'ok');
end
end
end
hold off
子函数1
%% epsilon函数
function[Eps]=epsilon(x,k)
[m,n]=size(x);
Eps=((prod(max(x)-min(x))*k*gamma(.5*n+1))/(m*sqrt(pi.^n))).^(1/n);
end
子函数2
%% 计算矩阵中点与点之间的距离
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;
end
dis(i,j) = sqrt(tmp);
dis(j,i) = dis(i,j);
end
end
end
注:主函数、子函数、数据集要放在同一路径下
运行结果
未进行分类的散点图
基于密度分类结果图
聚类结果将数据分为三类,分别用浅蓝色,绿色,深蓝色代表不同种类,红点代表噪音点,圆圈代表边界点,五角星代表核心点。
浅蓝色的核心点分布在30-40之间,绿色的核心点分布在50-70之间,深蓝色的核心点分布在85-95之间,核心点分布的范围表示在该范围内的数据密度大(即点数多)。