1. 程式人生 > >MATLAB學習之路(一) 實現簡單的基於歐式距離的新型聚類演算法(Clustering by fast search and find of density peaksd)

MATLAB學習之路(一) 實現簡單的基於歐式距離的新型聚類演算法(Clustering by fast search and find of density peaksd)

大學本科三年,眨眼而已,對於一個考研黨來說,本科時間已所剩不多,大三上學期初次接觸到MATLAB。的確如大牛們所說,強大的計算能力,充足的數學工具,帶來使用者極大的便利。

在大資料的學習過程中,MATLAB提供了莫大的幫助,由此開始,我將記錄其中的點點滴滴,提供給自己一個回憶的空間,也提供給一起學習的朋友們一個互相幫助平臺,你們的意見和建議我都會認真思考,諸君莫嫌,有不足之處,萬望斧正。

接下來進入正題吧,在進行了一些簡單的演算法實踐後(如KNN演算法,KMEANS演算法,DBscan演算法,Apriori演算法),對matlab有了一些初步的靈感,於是著手實現簡單的新型聚類(Clustering by fast search and find of density peaksd

)演算法(我個人簡稱為‘CFSFDP’演算法),在CSDN論壇中,我查閱了不少程式大牛們對CFSFDP演算法的獨家解讀,以及程式碼構思,對我的幫助很大,再次,對大牛們致謝!!(PS:國內的大牛真多而且還各有神通,羨慕ing~QAQ~

首先對CFSFDP演算法的理論理解,CFSFDP演算法的聚類過程主要是計算資料集中每個資料點的密度ρ(i)和距離δ(i)ρ(i)為資料點x(i)到其餘各點距離小於dc(截斷距離)的個數,δ(i)為比其密度值大的資料點的距離最小值,最後選取密度和距離值都較大的資料點作為聚類中心點。

對於一個規模為N=2^n的資料集X,利用CFSFDP演算法進行聚類的步驟如下:

1)、對於所有的資料點x(i)∈X,計算每個點到其餘各店的距離d(ij)(i,j=1...N)並儲存;

2)、對於所有的資料點x(i)∈X,利用公式如下計算其密度ρ(i)

                                                                                                 ρ(i)=Σβ(d(ij)-dc))

             其中β(x)為符號函式,定義如如下公式所示:

                                                                                                 β(x)=1 if x<0

                                                                                                 β(x)=0 if x>=0

3)、查詢ρ(i)具有最大值的點,其距離δ(i)利用以下公式計算:

                                                                                                  δ(i)=max(j)(dij)

4)、對於其他各資料點,其距離δ(i)按照如下計算:

                                                                                                  δ(i)=min(j:ρ(i)>ρ(j))(dij)

5)、將ρ(i)δ(i)值都比較大的資料點x(i)判定為聚類中心點

啊哈~以上就是對CFSFDP演算法的理論描述,其實用通俗一點的語言來解釋的話:就是現有一個好大好大的資料集,維度不限,元素不限,需要計算出其中每個點之間的距離,這裡我取歐式距離(euclidean metric 歐幾里得度量,也稱歐式距離)。再取截斷距離dc,在實現過程中,我的dc是自己取的,但是在CFSFDP演算法原作者給出的開源工具包中,dc是由資料集的大小確定的,適合運算龐大的資料量,為了儘量簡化(嘿嘿,其實是偷懶),我就自己取啦!在計算出各個點之間的歐式距離(d(ij)ij指點i到點j的歐式距離)後,與dc相比較,如果d(ij)小於dc的話,那麼該點的ρ(i)累計加1,如果d(ij)大於dc的話,那麼該點的ρ(i)不累加。

至於δ嘛,我的理解是比某點的區域性密度值(ρ)大的資料點的距離的最小值,比如現有點a,點b,點c,而d(ab)=10d(ac)=12d(dc)=15ρ(a)=5ρ(b)=6ρ(c)=7;那麼δ(a)=10ρ(a)<ρ(b)<ρ(c),點c與點bρ值都大於點a,而d(ab)<d(ac),所以取最小值d(ab),以此推算其他的點。

可以想象的出,最後繪製的影象,應該是大部分點集中在一起,少數個別點離大部分點較遠,這些點的共同特性是擁有較大的ρδ值,這意味著,在截斷距離中,這些點周圍聚集的點比較多,故而可以當作聚類中心,達到演算法目的。

原始碼如下:

close all;
clear all;
clc;
disp('請輸入資料集:');
disp('需要輸入一個txt檔名(如:XX.txt):');
Odata = input('檔名為:\n','s');
disp('請等待讀取檔案');
oo=load(Odata);%原始資料集矩陣
oeuclidean = pdist(oo,'euclidean');%只有點與點間歐式距離的矩陣

marknum1=[]; 
marknum2=[];
topnum=size(oo);
num = topnum(1);
for i=1:num
    for j=(i+1):num
        marknum1=[marknum1,i];
        marknum2=[marknum2,j];
    end
end

marknum = [marknum1;marknum2];

markoeuclidean=[marknum;oeuclidean];

%%截斷距離可以任意改變
dc=0.5;

%%計算ρ
orho=[];
ooeuclidean=[];
for i=1:num
    a=find(markoeuclidean(1,:)==i);
    b=find(markoeuclidean(2,:)==i);
    Q=[a,b];
    P=markoeuclidean(3,Q);
    orho(i)=numel(find(P<dc)); 
    if(i==1)
        P=[nan,P];
    else
    P=[P(1:i-1),nan,P(i:num-1)];
    end
    ooeuclidean(i,:)=P;
end

%%計算δ

for i = 1:num
    if (orho(i)==max(orho))
        oocount(i,:)=max(ooeuclidean(i,:));
    else
        oocount(i,:)=min(ooeuclidean(i,find(orho>orho(i))));
    end
end

%%畫圖
figure;
scatter(orho,oocount,'*');
title('聚類中心圖');
x1=xlabel('ρ');
x2=ylabel('δ');
hold on
for i=1:num
    c=num2str(i);
    text(orho(i),oocount(i),c);
end
hold off

figure;
scatter(oo(:,1),oo(:,2),'k');
title('原始資料集圖');
x1=xlabel('x');
x2=ylabel('y');
for i=1:num
    c=num2str(i);
    text(oo(i,1),oo(i,2),c);
end
hold off