function [patterns, targets, label] = kernel_k_means(train_patterns, train_targets, params, plot_on) %Reduce the number of data points using the kernel k-means algorithm %Inputs: % train_patterns - Input patterns % train_targets - Input targets % params - [Number of output data points, Kernel type, kernel parameter] % Kernel can be one of: Gauss, RBF (Same as Gauss), Poly, Sigmoid, or Linear % The kernel parameters are: % RBF kernel - Gaussian width (One parameter) % Poly kernel - Polynomial degree % Sigmoid - The slope and constant of the sigmoid (in the format [1 2], with no separating commas) % Linear - None needed % plot_on - Plot stages of the algorithm % %Outputs % patterns - New patterns % targets - New targets % label - The labels given for each of the original patterns if (nargin < 4), plot_on = 0; end %Get parameters [Nmu, kernel, kernel_params] = process_params(params); max_iter= 1000; [D,L] = size(train_patterns); dist = zeros(Nmu,L); label = zeros(1,L); %Kernelize the training patterns y = kernelize(kernel, kernel_params, train_patterns, train_patterns); %Use Nmu random points as the start points for the algorithm in = randperm(L); mu = train_patterns(:, in(1:Nmu)); %Start iterating iter = 0; assignment_changed = 1; while assignment_changed & (iter < max_iter) old_label = label; iter = iter + 1; %Find the distance of each cluster center from each data point y_mu = kernelize(kernel, kernel_params, mu, mu); y_cross = kernelize(kernel, kernel_params, train_patterns, mu); dist = ones(Nmu, 1)*diag(y)' - 2*y_cross + diag(y_mu)*ones(1,L); %Label the points [m, label] = min(dist); %Recompute the mu's for i = 1:Nmu, in_pat = find(label == i); switch length(in_pat) case 0, mu(:, i) = zeros(D, 1); case 1, mu(:, i) = train_patterns(:, in_pat); otherwise mu(:,i) = mean(train_patterns(:,in_pat)')'; end end %Plot the centers during the process plot_process(mu, plot_on) assignment_changed = any(old_label ~= label); end %Classify the patterns targets = zeros(1,Nmu); Uc = unique(train_targets); for i = 1:Nmu, if (length(unique(train_targets(:,find(label == i)))) == 1) targets(i) = unique(train_targets(:,find(label == i))); else N = hist(train_targets(:,find(label == i)), Uc); if (~isempty(N)) [m, max_l] = max(N); targets(i) = Uc(max_l); end end end patterns = mu; %END kernel k-means function y = kernelize(kernel, kernel_params, patterns, base_patterns) Nf = size(patterns, 2); Nb = size(base_patterns, 2); y = zeros(Nb, Nf); switch kernel, case {'Gauss','RBF'}, for i = 1:Nf, y(:,i) = exp(-sum((base_patterns-patterns(:,i)*ones(1,Nb)).^2)'/(2*kernel_params^2)); end case {'Poly', 'Linear'} if strcmp(kernel, 'Linear') kernel_params = 1; end for i = 1:Nf, y(:,i) = (base_patterns'*patterns(:,i) + 1).^kernel_params; end case 'Sigmoid' kernel_params = str2num(kernel_params); if (length(kernel_params) ~= 2) error('This kernel needs two parameters to operate!') end for i = 1:Nf, y(:,i) = tanh(base_patterns'*patterns(:,i)*kernel_params(1)+kernel_params(2)); end otherwise error('Unknown kernel. Can be Gauss, Linear, Poly, or Sigmoid.') end