2009-09-03 5 views
7

J'ai une matrice de A (369x10) que je veux regrouper en 19 groupes. J'utilise cette méthodeMatlab: K-means clustering

[idx ctrs]=kmeans(A,19) 

qui donne IDX (369x1) et DOE (19x10)

Je reçois le point jusqu'à here.All mes lignes dans un cluster est en 19 groupes.

Maintenant, j'ai un tableau B (49x10). Je veux savoir où les lignes de ce B correspond dans les 19 groupes donnés.

Comment est-ce possible dans MATLAB?

Nous vous remercions à l'avance

+0

quelle sortie espérez-vous? – SilentGhost

+0

Disons que mes clusters sont p1..p19. et j'ai un point de données de test que je choisis au hasard parmi les données de test que j'utilise en cluster. Je veux voir ça comme ça; "mes données de test appartiennent à p5" – tguclu

+2

J'ai trouvé un moyen mais je ne suis pas sûr que ce soit correct. ctrs contient les centres de chaque cluster. Si je calcule la distance euclidienne btw éléments de ctrs et mes données de test et obtenir l'indice du minimum puis il me donnera l'indice de cluster auquel mes données de test appartient. des idées? – tguclu

Répondre

4

Je ne peux pas penser à une meilleure façon de le faire que ce que vous avez décrit. Une fonction intégrée permettrait d'économiser une ligne, mais je ne pouvais pas en trouver un. Voici le code que je voudrais utiliser:

[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

pour petite quantité de données, vous pouvez faire

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

mais c'est un peu obscur; le bsxfun avec les ctrs permutés crée un tableau de booléens de 49 x 10 x 19, qui est alors 'tout-ed' dans la seconde dimension, permuté en retour et ensuite les identifiants de ligne sont trouvés. encore une fois, probablement pas pratique pour de grandes quantités de données.

1

En supposant que vous utilisez distance au carré de métrique euclidienne, essayez ceci:

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) 

prédit devrait contenir alors l'indice des plus proches barycentre, et les distances doivent contenir les distances le plus proche barycentre.

Jetez un oeil à l'intérieur de la fonction kmeans, à la sous-fonction 'distfun'. Cela vous montre comment faire ce qui précède, et contient également les équivalents pour d'autres métriques de distance.

11

Voici un exemple complet sur le regroupement:

%% 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

Je ne sais pas si je reçois votre sens droit, mais si vous voulez savoir quels grappe vos points appartiennent, vous pouvez utiliser facilement la fonction KnnSearch. Il a deux arguments et cherchera dans le premier argument pour le premier d'entre eux qui est le plus proche de l'argument deux.