forked from PRML/PRMLT
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathkmedoids.m
29 lines (29 loc) · 989 Bytes
/
kmedoids.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function [label, energy, index] = kmedoids(X, init)
% Perform k-medoids clustering.
% Input:
% X: d x n data matrix
% init: k number of clusters or label (1 x n vector)
% Output:
% label: 1 x n cluster label
% energy: optimization target value
% index: index of medoids
% Written by Mo Chen ([email protected]).
[d,n] = size(X);
if numel(init)==1
k = init;
label = ceil(k*rand(1,n));
elseif numel(init)==n
label = init;
end
X = bsxfun(@minus,X,mean(X,2)); % reduce chance of numerical problems
v = dot(X,X,1);
D = bsxfun(@plus,v,v')-2*(X'*X); % Euclidean distance matrix
D(sub2ind([d,d],1:d,1:d)) = 0; % reduce chance of numerical problems
last = 0;
while any(label ~= last)
[u,~,label(:)] = unique(label); % remove empty clusters
[~, index] = min(D*sparse(1:n,label,1,n,numel(u),n),[],1); % find k medoids
last = label;
[val, label] = min(D(index,:),[],1); % assign labels
end
energy = sum(val);