forked from PRML/PRMLT
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkmedoids.m
28 lines (28 loc) · 936 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
function [label, index, energy] = 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 sample labels
% index: index of medoids
% energy: optimization target value
% 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 = X-mean(X,2); % reduce chance of numerical problems
v = dot(X,X,1);
D = v+v'-2*(X'*X); % Euclidean distance matrix
D(sub2ind([d,d],1:d,1:d)) = 0; % reduce chance of numerical problems
last = zeros(1,n);
while any(label ~= last)
[~,~,last(:)] = unique(label); % remove empty clusters
[~, index] = min(D*sparse(1:n,last,1),[],1); % find k medoids
[val, label] = min(D(index,:),[],1); % assign labels
end
energy = sum(val);