今天看了譜聚類算法綜述(主要最近看的論文好像中心都偏在聚類分割這裏),具體看了一種算法,實現起來也很簡單,有點晚了,省去原理部分(明天補上),貼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;
實驗結果