今天看了谱聚类算法综述(主要最近看的论文好像中心都偏在聚类分割这里),具体看了一种算法,实现起来也很简单,有点晚了,省去原理部分(明天补上),贴Matlab代码。
%%%补上一点综述(每次都要转成PDF、、、)
NJW算法
function U=NJW(data,k)
%%NJW算法 选取拉氏矩阵的前K个最大特征值对应的特征向量,使其在R(k)空间中构成与原数据一一对应的表述,并在该空间内进行聚类
%%data n*m n样本个数 m 维度
%% k 选择前k个最大特征值对应的特征向量
%计算相似矩阵
affinity = CalculateAffinity(data);
% 计算对角矩阵
D=eye(size(affinity,1));
for i=1:size(affinity,1)
D(i,i) = sum(affinity(i,:));
end
%计算拉普拉斯矩阵,采用非规范化矩阵
% L=D-affinity;
% 规范化
for i=1:size(affinity,1)
for j=1:size(affinity,2)
L(i,j) = affinity(i,j) / (sqrt(D(i,i)) * sqrt(D(j,j)));
end
end
%计算特征值特征向量
[eigVectors,eigValues] = eig(L);
% 选取前K个最大特征值
[eigValues, ind] = sort(diag(eigValues), 'descend');
nEigVec =eigVectors(:,ind(1:k));
% 构造归一化矩阵U从获得的特征向量
U=zeros(size(nEigVec,1),k);
for i=1:size(nEigVec,1)
n = sqrt(sum(nEigVec(i,:).^2));
U(i,:) = nEigVec(i,:) ./ n;
end
end
function [affinity] = AffinityMatrix(data)
sigma = 1;
for i=1:size(data,1)
a=ones(size(data,1),1)*data(i,:)-data;
for j=1:size(data,1)
dist=norm(a(j,:));
affinity(i,j)= exp(-dist/(2*sigma^2));
end
end
end
算法测试
data = rand(30,2);
figure(1);
plot(data(:,1), data(:,2),'r+');
title('Original Data Points');
grid on;
U=NJW(data,3);
[IDX,C] = kmeans(U,3);
figure(2),
hold on; %保持当前
for i=1:size(IDX,1)
if IDX(i,1) == 1
plot(data(i,1),data(i,2),'m+');
elseif IDX(i,1) == 2
plot(data(i,1),data(i,2),'g+');
else
plot(data(i,1),data(i,2),'b+');
end
end
hold off;
title('Clustering Results using K-means');
grid on;
实验结果