在Matlab中创建聚类

4
假设我在Matlab中生成了以下数据:
n = 100;

x = randi(n,[n,1]);
y = rand(n,1);
data = [x y];

plot(x,y,'rx')
axis([0 100 0 1])

现在我想生成一个算法,将所有这些数据分类到某些集群中(这些集群是任意的),使得一个点成为集群的成员仅当该点与集群的至少一个成员之间的距离小于10。我该如何生成代码?

3个回答

3
你所描述的聚类方法是DBSCAN。请注意,由于数据集中很难存在一个点与所有其他点的距离大于10,因此此算法将在提供的数据中仅找到一个聚类。如果这确实是您想要的,您可以使用DBSCAN,或者如果您使用的是早于2019a版本,则可以使用FE发布的那个聚类算法
% Generating random points, almost similar to the data provided by OP 
data = bsxfun(@times, rand(100, 2), [100 1]);
% Adding more random points
for i=1:5
    mu = rand(1, 2)*100 -50;
    A = rand(2)*5;
    sigma = A*A'+eye(2)*(1+rand*2);%[1,1.5;1.5,3];
    data = [data;mvnrnd(mu,sigma,20)];
end
% clustering using DBSCAN, with epsilon = 10, and min-points = 1 as 
idx = DBSCAN(data, 10, 1);
% plotting clusters
numCluster = max(idx);
colors = lines(numCluster);
scatter(data(:, 1), data(:, 2), 30, colors(idx, :), 'filled')
title(['No. of Clusters: ' num2str(numCluster)])
axis equal

enter image description here

上图中的数字显示了任意两个不同聚类之间最近点对之间的距离。

2
Matlab内置函数clusterdata()非常适合您的要求。
以下是如何将其应用于您的示例:
% number of points
n = 100; 

% create the data
x = randi(n,[n,1]);
y = rand(n,1);
data = [x y]; 

% the number of clusters you want to create
num_clusters = 5; 

T1 = clusterdata(data,'Criterion','distance',...
'Distance','euclidean',...
'MaxClust', num_clusters)

scatter(x, y, 100, T1,'filled')

在这个案例中,我使用了5个聚类,并使用欧几里得距离作为度量来对数据点进行分组,但您可以随时更改(请参阅 clusterdata()的文档)。
下面是一些随机数据的5个聚类的结果。

enter image description here

请注意,数据存在偏斜(x值从0到100,而y值从0到1),因此结果也会存在偏差,但您可以始终对数据进行归一化处理。

2

以下是使用图的连通分量的方法:

D = pdist2(x, y) < 10;
D(1:size(D,1)+1:end) = 0;
G = graph(D);
C = conncomp(G);

连接组件是一个向量,显示群集编号。
  • 使用 pdist2 计算 xy 的距离矩阵。
  • 使用距离矩阵创建逻辑邻接矩阵,如果它们之间的距离小于 10,则两个点是相邻的。
  • 将邻接矩阵的对角线元素设为 0,以消除自环。
  • 从邻接矩阵创建一个图形
  • 计算图形的连接组件
  • 请注意,对于大型数据集使用 pdist2 可能不适用,您需要使用其他方法来形成稀疏邻接矩阵。

我在发布答案后通知到,@saastn 提供的答案建议使用几乎遵循相同方法的 DBSCAN 算法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接