我需要对两个甜甜圈形状数据集进行谱聚类。(Matlab)

问题描述 投票:0回答:1

我已经尝试了几个小时,但找不到解决方案。

我有“两个甜甜圈”数据样本(变量“X”)

您可以在下面的链接下载文件

甜甜圈数据集(rings.mat)

扩展到 2D 形状,如下图所示

前 250 点位于甜甜圈内部,最后 750 点位于甜甜圈外部。

2 Donut 2D sample

我需要执行谱聚类。

我用高斯相似距离制作了(相似矩阵“W”)。

我通过“W”的每个原始值之和制作了度矩阵

然后我计算特征值(E)和特征向量(V)

而且“V”字形不好。

我的试用出了什么问题???

我想不通。

load rings.mat
[D, N] = size(X); % data stored in X
%initial plot data
figure; hold on; 
for i=1:N,
    plot(X(1,i), X(2,i),'o');
end
% perform spectral clustering
W = zeros(N,N); 
D = zeros(N,N);

sigma = 1;
for i=1:N,
    for j=1:N,
        xixj2 = (X(1,i)-X(1,j))^2 + (X(2,i)-X(2,j))^2 ;
        W(i,j) =  exp(  -1*xixj2 / (2*sigma^2) ) ;   % compute weight here
%          if (i==j)
%              W(i,j)=0;
%          end;
    end;
     D(i,i) = sum(W(i,:))    ;
end;

L = D - W ;
normL = D^-0.5*L*D^-0.5;
[u,s,v] = svd(normL);

Image

matlab cluster-analysis spectral-clustering
1个回答
1
投票

如果您像在代码中一样使用拉普拉斯算子(“真正的”拉普拉斯算子),那么要将您的点聚类为两个集合,您将需要与第二小的特征值相对应的特征向量。

直观的想法是用弹簧将所有点彼此连接起来,如果点彼此靠近,弹簧就更硬,而对于远离的点,弹簧就更硬。如果您用锤子敲击弹簧网络并观察其振荡,拉普拉斯算子的特征向量就是振动模式 - 较小的特征值对应于较低频率的“整体”模式,较大的特征值对应于较高频率的振荡。您想要与第二小的特征值相对应的特征值,这就像鼓中的第二模式,正部分聚集在一起,负部分聚集在一起。

现在关于是否使用最大或最小特征值的评论中存在一些混乱,这是因为戴夫链接的论文中的拉普拉斯略有不同,是恒等式减去拉普拉斯算子。所以他们想要最大的,而你想要最小的。论文中的聚类也更先进一些,也更好一些,但实现起来并不那么容易。

这是您的代码,经过修改后可以工作:

load rings.mat
[D, N] = size(X); % data stored in X
%initial plot data
figure; hold on; 
for i=1:N,
    plot(X(1,i), X(2,i),'o');
end
% perform spectral clustering
W = zeros(N,N); 
D = zeros(N,N);

sigma = 0.3; % <--- Changed to be smaller
for i=1:N,
    for j=1:N,
        xixj2 = (X(1,i)-X(1,j))^2 + (X(2,i)-X(2,j))^2 ;
        W(i,j) =  exp(  -1*xixj2 / (2*sigma^2) ) ;   % compute weight here
%          if (i==j)
%              W(i,j)=0;
%          end;
end;
     D(i,i) = sum(W(i,:))    ;
end;

L = D - W ;
normL = D^-0.5*L*D^-0.5;
[u,s,v] = svd(normL);

% New code below this point
cluster1 = find(u(:,end-1) >= 0);
cluster2 = find(u(:,end-1) < 0);

figure
plot(X(1,cluster1),X(2,cluster1),'.b')
hold on
plot(X(1,cluster2),X(2,cluster2),'.r')
hold off
title(sprintf('sigma=%d',sigma))

结果如下:

现在请注意,我将 sigma 更改得更小 - 从 1.0 更改为 0.3。当我将其保留为 1.0 时,我得到以下结果:

我认为这是因为当 sigma=1 时,内部簇中的点能够足够“拉动”外部簇(它们距离外部簇大约距离 1),这样在能量上更有利于将两个圆分开一半像实心振动鼓,而不是有两个不同的圆圈。

© www.soinside.com 2019 - 2024. All rights reserved.