【问题标题】:I need to spectral clustering for two donuts shape dataset.(Matlab)我需要对两个甜甜圈形状数据集进行光谱聚类。(Matlab)
【发布时间】:2016-02-22 10:54:48
【问题描述】:

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

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

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

donut dataset(rings.mat)

如下图所示的二维形状

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

我需要进行谱聚类。

我用高斯相似距离制作(相似矩阵“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);

【问题讨论】:

  • “V 形不好”——这到底是什么意思?错误是什么?
  • 不是错误。但我无法从 V 中找到清晰的形状。你能试试我的代码吗?我也上传了数据集。
  • 所以,跟随 Ng 等人。你有几个问题:1)你没有标准化拉普拉斯算子。 2)您永远不会进行聚类...如果您愿意,您当然可以采用 SVD,但使用 k=2 的 k-means 可能更容易。你为什么不看看这个的第 2 节:ai.stanford.edu/~ang/papers/nips01-spectral.pdf
  • 原始模板具有相似矩阵 (W) 的 SVD 代码。我已经访问了这篇论文。但我无法理解。如果我能理解,我不会上传这个问题。无论如何,我应该做的是计算 D^-0.5 * W * D^-0.5 ???。什么是拉普拉斯算子的归一化?
  • 所以,第 2 节非常清楚,i.m.o.您成功创建了相似度矩阵。您现在需要:1) 采用 归一化 拉普拉斯算子而不是未归一化,2) 采用顶部特征向量,然后 3) 应用 k-means 来获得集群名称。

标签: matlab cluster-analysis spectral


【解决方案1】:

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

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

现在 cmets 对于是否使用最大或最小特征值存在一些混淆,这是因为 dave 链接的论文中的拉普拉斯算子略有不同,即恒等式减去您的拉普拉斯算子。所以他们想要最大的,而你想要最小的。论文中的聚类也更高级,更好,但实现起来并不容易。

这是你的代码,修改后可以工作:

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 的距离)上,因此分裂两者在能量上更有利像一个实心的振动鼓一样对半圈,而不是有两个不同的圈。

【讨论】:

  • 感谢您的回复。我替换了使用 svd(W) 的方式并获得第一个/第二个特征向量图。然后对这些特征向量进行聚类。使用 svd(L) 似乎更好,因为阈值仅为 0。
猜你喜欢
  • 2014-12-07
  • 2013-04-11
  • 2012-01-18
  • 2019-10-13
  • 1970-01-01
  • 1970-01-01
  • 2023-02-23
  • 1970-01-01
  • 2023-03-14
相关资源
最近更新 更多