7

首先,我必须说我是 matlab 的新手(和这个网站......),所以请原谅我的无知。

我正在尝试在 matlab 中编写一个函数,该函数将使用光谱聚类将一组点分成两个簇。

我的代码如下

function Groups = TrySpectralClustering(data)
dist_mat = squareform(pdist(data));

W=  zeros(length(data),length(data));

for i=1:length(data),
    for j=(i+1):length(data),
    W(i,j)=10^(-dist_mat(i,j));
    W(j,i)=W(i,j);
    end
end
D = zeros(length(data),length(data));
for i=1:length(W),
D(i,i)=sum(W(i,:));
end
L=D-W;
L=D^(-0.5)*L*D^(-0.5);
[ V E ] = eig(L);
disp ('V:');
disp (V);

如果我理解正确,那么通过使用第二小的特征向量,我应该能够将数据划分为两个集群 - 如果第二个特征向量的第 i 个成员为正,则第 i 个数据点将在一个集群中,否则它将在另一个集群中。

但是,当我尝试以下

f=[1,1;0,0;1,0;0,1;100,100;100,101;101,101;101,100]
TrySpectralClustering(f)

我希望前四个点会形成一个集群,而后四个点会形成另一个集群。

但是,我收到

V:
   -0.0000   -0.5000    0.0000   -0.5777    0.0000    0.4078   -0.0000    0.5000
   -0.0000   -0.5000    0.0000    0.5777    0.0000   -0.4078   -0.0000    0.5000
   -0.0000   -0.5000    0.0000    0.4078    0.0000    0.5777   -0.0000   -0.5000
   -0.0000   -0.5000    0.0000   -0.4078    0.0000   -0.5777   -0.0000   -0.5000
   -0.5000   -0.0000   -0.0000   -0.0000   -0.7071   -0.0000    0.5000   -0.0000
   -0.5000   -0.0000    0.7071    0.0000   -0.0000   -0.0000   -0.5000   -0.0000
   -0.5000    0.0000   -0.0000    0.0000    0.7071    0.0000    0.5000    0.0000
   -0.5000         0   -0.7071         0         0         0   -0.5000         0

取第二个特征向量

  -0.0000   -0.5000    0.0000    0.5777    0.0000   -0.4078   -0.0000    0.5000

我发现一个集群包括点 1,0;0,1;100,100;101,100,而另一个集群由点 1,1;0,0;100,101;101,101 组成

我想知道我做错了什么。

注意:作为家庭作业项目的一部分,我正在处理上述内容。

提前致谢!

4

3 回答 3

4

你得到的是正确的。令 U 为包含如上所示特征向量的矩阵,并让它们排列成第一列对应于最小特征值,渐进列对应于升序特征值。然后,通过保留与较小特征值相对应的特征向量来获取 U 列的子集。现在,将这些列逐行读取到一组新的向量中,称为 Y。集群 Y 以获得光谱集群。所以,让我们假设我们的子集只是第一列。我们清楚地看到,如果您要对第一列进行聚类,您会将前 4 列放入 1 个集群中,然后将接下来的 4 列放入另一个集群中,这就是您想要的。

于 2013-03-19T09:10:20.473 回答
3

看一下J. Shi教授网页上的实现。密切关注discretisation.m功能。

此外,您的代码效率非常低。您需要更多地利用 Matlab 的矢量化:

W = 10.^( - dist_mat ); % single liner of nested loop for comuting W
% computing the symmetric laplacian
d = sum( W, 2 ); % sum each row
d( d == 0 ) = 1; % avoid division by zero
d_half = 1./sqrt( d );
L = eye( n ) - bsxfun( @times, bsxfun( @times, W, d_half' ),  d_half );
于 2013-03-19T09:48:56.373 回答
2

两个观察:

  1. L=D-W; L=D^(-0.5)*L*D^(-0.5); 为什么让他计算单位矩阵?只需使用单位矩阵 eye(n) 并从中减去 D^(-0.5) * W * D^(-0.5) 即可计算拉普拉斯 L

  2. eig 将特征向量作为列返回,为什么要取行?您是否检查了 E 中相应特征值的值,因此您可以确定您正在查看与第二个最小特征值相对应的特征向量?

于 2013-03-19T08:47:14.797 回答