2012-06-08 12 views
6

sto cercando di tracciare il gomito di k significa usando il codice seguente:K significa trovare gomito quando la trama gomito è una curva regolare

load CSDmat %mydata 
for k = 2:20 
    opts = statset('MaxIter', 500, 'Display', 'off'); 
    [IDX1,C1,sumd1,D1] = kmeans(CSDmat,k,'Replicates',5,'options',opts,'distance','correlation');% kmeans matlab 
    [yy,ii] = min(D1');  %% assign points to nearest center 

    distort = 0; 
    distort_across = 0; 
    clear clusts; 
    for nn=1:k 
     I = find(ii==nn);  %% indices of points in cluster nn 
     J = find(ii~=nn);  %% indices of points not in cluster nn 
     clusts{nn} = I;   %% save into clusts cell array 
     if (length(I)>0) 
      mu(nn,:) = mean(CSDmat(I,:));    %% update mean 
      %% Compute within class distortion 
      muB = repmat(mu(nn,:),length(I),1); 
      distort = distort+sum(sum((CSDmat(I,:)-muB).^2)); 
      %% Compute across class distortion 
      muB = repmat(mu(nn,:),length(J),1); 
      distort_across = distort_across + sum(sum((CSDmat(J,:)-muB).^2)); 
     end 
    end 
    %% Set distortion as the ratio between the within 
    %% class scatter and the across class scatter 
    distort = distort/(distort_across+eps); 

     bestD(k)=distort; 
     bestC=clusts; 
end 
figure; plot(bestD); 

I valori di bestD (entro varianza cluster/tra varianza cluster) sono

[ 
0.401970132754914 
0.193697163350293 
0.119427184084282 
0.0872681777446508 
0.0687948264457301 
0.0566215549396577 
0.0481117619129058 
0.0420491551659459 
0.0361696583755145 
0.0320384092689509 
0.0288948343304147 
0.0262373245283877 
0.0239462330460614 
0.0218350896369853 
0.0201506779033703 
0.0186757121130685 
0.0176258625858971 
0.0163239661159014 
0.0154933431470081 
] 

Il codice è stato adattato da Lihi Zelnik-Manor, marzo 2005, Caltech.

Il rapporto di trama tra la varianza del cluster e tra la varianza del cluster è una curva regolare con un ginocchio che è liscio come una curva, trama dati bestD dati sopra. Come troviamo il ginocchio per questi grafici?

+5

Puoi condividere la trama? –

+1

possibile duplicato di [trovare il miglior punto di trade-off su una curva] (http://stackoverflow.com/questions/2018178/finding-the-best-trade-off-point-on-a-curve) – Amro

+1

Vedi [ come-i-determinare-K-quando-using-k-means clustering] (http://stackoverflow.com/questions/1793532/how-do-i-determine-k-when-using-k-means -clustering) su SO. – denis

risposta

0

Penso che sia meglio utilizzare solo il vostro "all'interno di una distorsione di classe" come parametro di ottimizzazione:

%% Compute within class distortion 
muB = repmat(mu(nn,:),length(I),1); 
distort = distort+sum(sum((CSDmat(I,:)-muB).^2)); 

Utilizzare questa senza dividendo questo valore per "distort_across". Se si calcola il "derivato" di questo:

unexplained_error = within_class_distortion; 
derivative = diff(unexplained_error); 
plot(derivative) 

La derivata (k) ti dice quanto l'errore inspiegabile è diminuito con l'aggiunta di un nuovo cluster. Suggerisco di interrompere l'aggiunta di cluster quando la diminuzione di questo errore è inferiore a dieci volte la prima diminuzione ottenuta.

for (i=1:length(derivative)) 
    if (derivative(i) < derivative(1)/10) 
     break 
    end 
end 
k_opt = i+1; 

Infatti il ​​metodo per ottenere il numero ottimale di cluster dipende dall'applicazione, ma penso che si può ottenere un buon valore di k usando questo suggerimento.