2009-09-03 8 views
7

Ho una matrice di A (369x10) che voglio raggruppare in 19 cluster. Io uso questo metodoMatlab: K-significa clustering

[idx ctrs]=kmeans(A,19) 

che produce IDX (369x1) e CTR (19x10)

Ho capito fino a here.All mie righe in un cluster è in 19 cluster.

Ora ho un array B (49x10). Voglio sapere dove corrispondono le righe di questo B tra i 19 cluster dati.

Come è possibile in MATLAB?

Grazie in anticipo

+0

quale output ti aspetti? – SilentGhost

+0

Diciamo che i miei cluster sono p1..p19. e ho un punto dati di test che seleziono a caso dai dati di test che utilizzo durante il clustering. Voglio vedere sth così; "I miei dati di test appartengono a p5" – tguclu

+2

Ho trovato un modo ma non sono sicuro che sia corretto. ctrs contiene i centri di ciascun cluster. Se calcoli la distanza euclidea tra gli elementi di ctr e i miei dati di test e ottengo l'indice del minimo, questo mi darà l'indice del cluster a cui appartengono i miei dati di test. qualche idea? – tguclu

risposta

4

Non riesco a pensare ad un modo migliore per farlo che quello che hai descritto. Una funzione incorporata salverebbe una riga, ma non riuscivo a trovarne una. Ecco il codice userei:

[ids ctrs]=kmeans(A,19); 
D = dist([testpoint;ctrs]); %testpoint is 1x10 and D will be 20x20 
[distance testpointID] = min(D(1,2:end)); 
0

per piccole quantità di dati, si potrebbe fare

[testpointID,dum] = find(permute(all(bsxfun(@eq,B,permute(ctrs,[3,2,1])),2),[3,1,2])) 

ma questo è un po 'oscuro; il bsxfun con i ctr permutati crea una matrice di booleani 49 x 10 x 19, che viene quindi "tutto-edito" attraverso la seconda dimensione, permuta indietro e quindi vengono trovati gli id ​​delle righe. di nuovo, probabilmente non è pratico per grandi quantità di dati.

1

Supponendo che si sta utilizzando distanza euclidea quadratica metrica, provate questo:

for i = 1:size(ctrs,2) 
d(:,i) = sum((B-ctrs(repmat(i,size(B,1),1),:)).^2,2); 
end 
[distances,predicted] = min(d,[],2) 

predetto dovrebbe quindi contenere l'indice del baricentro più vicino, e le distanze dovrebbero contenere le distanze il baricentro più vicino.

Dai uno sguardo all'interno della funzione kmea, alla sottofunzione 'distfun'. Questo ti mostra come fare quanto sopra, e contiene anche gli equivalenti per altre metriche di distanza.

11

Il seguente è un un esempio completo su di clustering:

%% generate sample data 
K = 3; 
numObservarations = 100; 
dimensions = 3; 
data = rand([numObservarations dimensions]); 

%% cluster 
opts = statset('MaxIter', 500, 'Display', 'iter'); 
[clustIDX, clusters, interClustSum, Dist] = kmeans(data, K, 'options',opts, ... 
    'distance','sqEuclidean', 'EmptyAction','singleton', 'replicates',3); 

%% plot data+clusters 
figure, hold on 
scatter3(data(:,1),data(:,2),data(:,3), 50, clustIDX, 'filled') 
scatter3(clusters(:,1),clusters(:,2),clusters(:,3), 200, (1:K)', 'filled') 
hold off, xlabel('x'), ylabel('y'), zlabel('z') 

%% plot clusters quality 
figure 
[silh,h] = silhouette(data, clustIDX); 
avrgScore = mean(silh); 


%% Assign data to clusters 
% calculate distance (squared) of all instances to each cluster centroid 
D = zeros(numObservarations, K);  % init distances 
for k=1:K 
    %d = sum((x-y).^2).^0.5 
    D(:,k) = sum(((data - repmat(clusters(k,:),numObservarations,1)).^2), 2); 
end 

% find for all instances the cluster closet to it 
[minDists, clusterIndices] = min(D, [], 2); 

% compare it with what you expect it to be 
sum(clusterIndices == clustIDX) 
2

Non so se ho destra significato, ma se volete sapere che a grappolo tuoi punti appartengono è possibile utilizzare la funzione KnnSearch facilmente. Ha due argomenti e cercherà nel primo argomento il primo di essi che è il più vicino al secondo argomento.