2009-09-03 13 views
7

Mam macierz A (369x10), którą chcę zgrupować w 19 klastrach. I skorzystać z tej metodyMatlab: K-means clustering

[idx ctrs]=kmeans(A,19) 

co daje IDX (369x1) i CTR (19x10)

dostaję punkt aż do here.All moje wiersze w A jest skupione w 19 klastrów.

Mam teraz tablicę B (49x10). Chcę wiedzieć, gdzie znajdują się wiersze tego B w podanych 19 klastrach.

Jak to jest możliwe w MATLAB?

góry dziękuję

+0

jaka moc wyjściowa oczekujesz? – SilentGhost

+0

Załóżmy, że moje klastry to p1..p19. i mam punkt danych testowych, który losowo wybieram z danych testowych, których używam podczas klastrowania. Chcę zobaczyć coś takiego; "moje dane testowe należą do p5" – tguclu

+2

Znalazłem sposób, ale nie jestem pewien, czy to prawda. ctrs przechowuje centra każdego klastra. Jeśli obliczyć odległość euklidesowa btw elementy ctrs i moje dane testowe i uzyskać indeks minimum, to dostarczy mi indeks klastra, do którego należą moje dane testowe. jakieś pomysły? – tguclu

Odpowiedz

4

Nie mogę sobie wyobrazić lepszy sposób to zrobić niż to, co opisane. Wbudowana funkcja zapisałaby jedną linię, ale nie mogłem jej znaleźć. Oto kod użyłbym:

[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

dla małej ilości danych, można zrobić

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

ale jest to nieco niejasne; bsxfun z permutowanym ctrs tworzy tablicę boolanowską 49 x 10 x 19, która jest następnie "all-ed" w drugim wymiarze, permutowana z powrotem, a następnie identyfikatory rzędu. ponownie, prawdopodobnie niepraktyczne w przypadku dużych ilości danych.

1

Zakładając, że używasz kwadrat odległości euklidesowej metryka, spróbuj tego:

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) 

przewidział powinien następnie zawierać indeks najbliższego ciężkości oraz odległości powinien zawierać odległości do najbliższego ciężkości.

Zajrzyj do funkcji kmeans w podfunkcji "distfun". To pokazuje, jak to zrobić, a także zawiera odpowiedniki innych danych odległości.

11

Poniżej znajduje się pełna przykładów na klastry:

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

ja nie wiem, czy uzyskać prawo sens, ale jeśli chcesz wiedzieć, które skupiają twoje punkty należą można łatwo korzystać z funkcji KnnSearch. Ma dwa argumenty i wyszuka pierwszy argument dla pierwszego z nich, który jest najbliższy argumentowi dwa.