這幾天在實現一篇多體非剛體重構以及分割的論文。利用ADMM迭代生成了對軌跡進行自我表達的一個仿射矩陣。論文中對這個仿射矩陣進行了一個譜聚類,對其各個特徵點進行了分類。主要用到的論文爲:《On Spectral Clustering: Analysis and an algorithm》。在這裏我對自己目前對譜聚類的學習做一個自我總結。
1. 譜聚類概述
譜聚類是從圖論中演化出來的算法,後來在聚類中得到了廣泛的應用。它的主要思想是把所有的數據看做空間中的點,這些點之間可以用邊連接起來。距離較遠的兩個點之間的邊權重值較低,而距離較近的兩個點之間的邊權重值較高,通過對所有數據點組成的圖進行切圖,讓切圖後不同的子圖間邊權重和儘可能的低,而子圖內的邊權重和儘可能的高,從而達到聚類的目的。
2. 譜聚類的算法流程
在上述的論文中,譜聚類的流程如下:
翻譯過來,可以作如下表達:
輸入:n個樣本點和聚類簇的數目k;
輸出:聚類簇
(1)使用下面公式計算的相似度矩陣A;
A爲Sij組成的相似度矩陣。我在做的那篇論文中,通過約束,迭代求得C1,並將A = abs(C1) + abs(C1')
(2)使用下面公式計算矩陣D;
,即相似度矩陣A的每一行元素之和
D爲di組成的d * d對角矩陣。
(3) 求得矩陣L ,其中 L = D^(-1/2) * A * D^(-1/2)。
(4) 計算L的特徵值,將特徵值從大到小排序,取前k個特徵值,並計算前k個特徵值對應的特徵向量{X1,X2,X3,........Xk}∈R,R爲n✖️k。
(5) 將第四步得到的特徵向量組合成一個新的矩陣X,同時設Y矩陣,其中,Yi是X的第i行向量。
(6) 通過K-mean或者其他有效的聚類算法對新的矩陣聚類爲:
(7) 最後,輸出其中,
MATLAB代碼如下(因爲實現論文中的非剛體目前是兩個,所以我將K默認爲了2)
function [idx,result] = SC(A)
%第一步,建立一個D矩陣,是一個對角線矩陣。其中D(i,i)= A的第i行的總和。
D = zeros(size(A,1));
L = zeros(size(A,1));
for i = 1:size(A,1)
sum = 0;
for j = 1:size(A,1)
%給對角線矩陣D賦值
sum = sum + A(i,j);
end;
D(i,i) = sum;
end;
L = D^-(1/2)* A * D^-(1/2);
%求出前K個最大特徵值對應的特徵向量。該論文中都是對兩個數據進行分割,所以K=2
[X,Y] = eig(L);
Y = diag(Y);
[Y,I] = sort(Y,'descend');
x = X(:,I(1:2));
%計算一個Y矩陣
y = zeros(size(x));
for i = 1:size(x,1)
sum = 0;
for j = 1:size(x,2)
sum = sum + x(i,j)^2;
end;
sum = sum^(1/2);
for k = 1:size(x,2)
y(i,k) = x(i,k)/sum;
end;
end
%最後一步,K-means
[idx,c]=kmeans(y,2);
最後,通過SC,對論文中迭代求出的仿射矩陣進行了聚類,效果如下:
圖一:仿射矩陣的顯示: 圖二:對仿射矩陣進行SC後的顯示:
從圖一中,較爲明顯的看到兩個對角矩陣,進行SC後,可以很好的顯示這兩個非剛體運動的分割。