最近博主根据matlab2019b的函数,仿写了欧氏距离聚类,其代码如下:
其实代码就是一模一样的,哈哈哈哈,博主偷了点懒。
clear
clc
%% 模拟数据
[X,Y,Z] = sphere(100);
loc1 = [X(:),Y(:),Z(:)];
loc2 = 2*loc1;
ptCloud = pointCloud([loc1;loc2]);
pcshow(ptCloud)
title('Point Cloud')
a = ptCloud.Location;
%% 欧式距离聚类
% 设置参数r
r = 0.5;
% 半径搜索
ind = rangesearch(a,a,r,'Distance','euclidean','NSMethod','kdtree');
% 设置索引列
num = numel(a(:,1));
idx = zeros(num,1);
% 设置指针
newlable = 0;
for i = 1:num
if idx(i)~=0
continue
end
% 选取第i个点的索引
curp = ind(i,:);
% cell转换为数组mat
curp = cell2mat(curp);
% 第一个索引是自己,所以去除
curp = curp(:,2:end);
for j = 1:length(curp)
temp = curp(j);
if idx(i)>0 && idx(temp)>0
if idx(i) > idx(temp)
idx(idx==idx(i)) = idx(temp);
elseif idx(temp) > idx(i)
idx(idx==idx(temp)) = idx(i);
end
else
if idx(i)>0
idx(temp) = idx(i);
elseif idx(temp)>0
idx(i) = idx(temp);
end
end
end
if idx(i) == 0
newlable = newlable+1;
idx(i) = newlable;
idx(curp) = newlable;
end
end
pcshow(a,idx)
模拟的数据:
根据dbscan代码改的:
% 欧式距离聚类
clc
clear
rng('default') % For reproducibility
% Parameters for data generation
N = 300; % Size of each cluster
r1 = 0.5; % Radius of first circle
r2 = 5; % Radius of second circle
theta = linspace(0,2*pi,N)';
X1 = r1*[cos(theta),sin(theta)]+ rand(N,1);
X2 = r2*[cos(theta),sin(theta)]+ rand(N,1);
data = [X1;X2]; % Noisy 2-D circular data set
scatter(data(:,1),data(:,2))
title('聚类之前')
% 距离阈值
r = 1;
% rangesearch功能为搜索r内的所有点
d = rangesearch(data,data,r);
% 计算数据的大小
[n,m] = size(data);
% 设置访问标记
vist = zeros(n,1);
% 设置聚类组
idx = zeros(n,1);
% 设置聚类标签
lab = 0;
tic
for i = 1:n
% 判断种子点是否被访问过
if vist(i) == 0
% 当前点如果没被访问过,则vist定为1,被访问
vist(i) = 1;
% 种子点未被访问,则聚类个数增加
lab = lab + 1;
% 为当前种子点归类
idx(i) = lab;
% 提取当前种子点集合的点
neig = d{i};
% 设置指针
k = 1;
while true
% 提取第i个点邻域集合中的第k个点
j = neig(k);
% 判断k点是否被访问过
if vist(j) == 0
% 没有被访问过,则设置被访问1,
vist(j) = 1;
% 为当前点归类
idx(j) = lab;
% 提取当前点的领域集合点
neig2 = d{j};
neig2 = setdiff(neig2,neig);
neig = [neig,neig2];
% else
% neig(k) = [];
end
% 指针往前
k=k+1;
% 集合不在变化时聚类完成
if k > numel(neig)
break
end
end
end
end
time=toc
gscatter(data(:,1),data(:,2),idx);
title('聚类之后')