function [s,R] = test_lwpr_nD(s,R) global lwprs; % test for LWPR on n-dimensional data set with 2D embedded function d = 5; n = 500; % a random training set using the CROSS function X = (rand(n,2)-.5)*2; Y = max([exp(-X(:,1).^2 * 10),exp(-X(:,2).^2 * 50),1.25*exp(-(X(:,1).^2+X(:,2).^2)*5)]'); Y = Y' + randn(n,1)*0.1; % rotate input data into d-dimensional space if ~exist('R') | isempty(R) R = randn(d); R = R'*R; R = orth(R); end Xorg = X; X = [X zeros(n,d-2)]*R; % a systematic test set on a grid Xt = []; for i=-1:0.05:1, for j=-1:0.05:1, Xt = [Xt; i j]; end end Yt = max([exp(-Xt(:,1).^2 * 10),exp(-Xt(:,2).^2 * 50),1.25*exp(-(Xt(:,1).^2+Xt(:,2).^2)*5)]'); Yt = Yt'; % rotate the test data Xtorg = Xt; Xt = [Xt zeros(length(Xt),d-2)]*R; % initialize LWPR, use only diagonal distance metric ID = 1; if ~exist('s') | isempty(s) lwpr('Init',ID,d,1,1,0,0,1e-6,50,ones(d,1),[1],'lwpr_test'); else lwpr('Init',ID,s); end % set some parameters kernel = 'Gaussian'; % kernel = 'BiSquare'; % note: the BiSquare kernel requires different values for % an initial distance metric, as in the next line % lwpr('Change',ID,'init_D',eye(d)*7); lwpr('Change',ID,'init_D',eye(d)*25); lwpr('Change',ID,'init_alpha',ones(d)*250); % this is a safe learning rate lwpr('Change',ID,'w_gen',0.2); % more overlap gives smoother surfaces lwpr('Change',ID,'meta',1); % meta learning can be faster, but numerical more dangerous lwpr('Change',ID,'meta_rate',250); % train the model for j=1:20 inds = randperm(n); mse = 0; for i=1:n, [yp,w] = lwpr('Update',ID,X(inds(i),:)',Y(inds(i),:)'); mse = mse + (Y(inds(i),:)-yp).^2; end nMSE = mse/n/var(Y,1); disp(sprintf('#Data=%d #rfs=%d nMSE=%5.3f',lwprs(ID).n_data,length(lwprs(ID).rfs),nMSE)); end % create predictions for the test data Yp = zeros(size(Yt)); for i=1:length(Xt), [yp,w]=lwpr('Predict',ID,Xt(i,:)',0.001); Yp(i,1) = yp; end ep = Yt-Yp; mse = var(ep,1); nmse = mse/var(Y,1); % get the data structure s = lwpr('Structure',ID); figure(1); clf; % plot the raw noisy data subplot(2,2,1); plot3(Xorg(:,1),Xorg(:,2),Y,'*'); title('Noisy data samples'); % plot the fitted surface axis([-1 1 -1 1 -.5 1.5]); subplot(2,2,2); [x,y,z]=makesurf([Xtorg,Yp],sqrt(length(Xtorg))); surfl(x,y,z); axis([-1 1 -1 1 -.5 1.5]); title(sprintf('The fitted function: nMSE=%5.3f',nmse)); % plot the true surface subplot(2,2,3); [x,y,z]=makesurf([Xtorg,Yt],sqrt(length(Xtorg))); surfl(x,y,z); axis([-1 1 -1 1 -.5 1.5]); title('The true function'); % plot the local models subplot(2,2,4); for i=1:length(lwprs(ID).rfs), D = R'*lwprs(ID).rfs(i).D*R; c = R*lwprs(ID).rfs(i).c; draw_ellipse(D(1:2,1:2),c(1:2),0.1,kernel); hold on; end hold off; axis('equal'); title('Projected nput space view of RFs'); % -------------------------------------------------------------------------------- function [X,Y,Z]=makesurf(data,nx) % [X,Y,Z]=makesurf(data,nx) converts the 3D data file data into % three matices as need by surf(). nx tells how long the row of the % output matrices are [m,n]=size(data); n=0; for i=1:nx:m, n = n+1; X(:,n) = data(i:i+nx-1,1); Y(:,n) = data(i:i+nx-1,2); Z(:,n) = data(i:i+nx-1,3); end; % -------------------------------------------------------------------------------- function []=draw_ellipse(M,C,w,kernel) % function draw ellipse draws the ellipse corresponding to the % eigenvalues of M at the location c. [V,E] = eig(M); E = E; d1 = E(1,1); d2 = E(2,2); steps = 50; switch kernel case 'Gaussian' start = sqrt(-2*log(w)/d1); case 'BiSquare' start = sqrt(2*(1-sqrt(w))/d1); end for i=0:steps, Xp(i+1,1) = -start + i*(2*start)/steps; switch kernel case 'Gaussian' arg = (-2*log(w)-Xp(i+1,1)^2*d1)/d2; case 'BiSquare' arg = (2*(1-sqrt(w))-Xp(i+1,1)^2*d1)/d2; end if (arg < 0), arg = 0; end; % should be numerical error Yp(i+1,1) = sqrt(arg); end; for i=1:steps+1; Xp(steps+1+i,1) = Xp(steps+1-i+1,1); Yp(steps+1+i,1) = -Yp(steps+1-i+1,1); end; % transform the rf M = [Xp,Yp]*V(1:2,1:2)'; Xp = M(:,1) + C(1); Yp = M(:,2) + C(2); plot(C(1),C(2),'ro',Xp,Yp,'c');