% iterations = plot_perceptron(Input,TrainingRate,Pause) % shows the process of perceptron on 2-d data where Input is a set of input % vectors of the form % [X0 X1 X2 Class] % such that X0 is a constant 1, X1 and X2 are the data and Class is either % -1 for Class 0 or 1 for Class 1 and given TrainingRate (0-1] function k = plot_perceptron(I,n,p) if nargin == 2 p = 0.3; end % seperate the two classes c0 and c1 by Class % then get X1 and X2 for both c0 = I(find(I(:,end) == -1),2:3); c1 = I(find(I(:,end) == 1),2:3); c0x1 = c0(:,1); c0x2 = c0(:,2); c1x1 = c1(:,1); c1x2 = c1(:,2); % plot the sample points, let class 0 be a green '+' and % class1 a blue '*' plot(c0x1,c0x2,'g+',c1x1,c1x2,'b*'); % scale the x and y axis - add 0.2 to the bounding area so we see all % points maxx1 = max(I(:,2)) + 0.2; minx1 = min(I(:,2)) - 0.2; maxx2 = max(I(:,3)) + 0.2; minx2 = min(I(:,3)) - 0.2; axis([minx1 maxx1 minx2 maxx2]); % legend legend('Class 0','Class 1','Location','Best'); title('Perceptron'); % disp('Press any key to Start'); % pause; % start the perceptron % NOTE: the book sets w0 to -1 automatically % such as w{1} = [-1 randn(1,cols-1)]'; Ip = I(:,1:end-1); % Ip: the sample x's c = I(:,end); % c: vector of corresponding classes [rows,cols] = size(Ip); % cols: number of columns in Ip w{1} = randn(1,cols)'; % create random weight vector of size cols k = 2; % using 1-based indexing set k to 2 % x1 and x2 for w x1 = 0; x2 = 0; % plot w{1} hold on x2 = minx2:.1:maxx2; % make the line cover the figure x1 = (-w{1}(1) - w{1}(3)*x2) / w{1}(2); h = plot(x1,x2,'k-'); set(h,'EraseMode','xor','MarkerSize',18); hold off % while there exist input vectors in Ip that are missclassifed by % w{k-1} pick a missclassfiied Ij in Ip and adjust w{k-1} by delta w % to get w{k} i = is_misclassified(Ip,w{k-1},c,rows); % should combine these two M = misclassified(Ip,w{k-1},c,rows); hold on h1 = plot(M(:,1),M(:,2),'mo'); set(h1,'EraseMode','xor','MarkerSize',8); % set the title set_title(w{k-1},k-1,length(M(:,1))); % assumes some are misclassified hold off while i % compute new weight vector xk = (c(i)*Ip(i,1:end))'; w{k} = w{k-1} + n*xk; k = k + 1; i = is_misclassified(Ip,w{k-1},c,rows); M = misclassified(Ip,w{k-1},c,rows); % draw the new computation drawnow; x1 = (-w{k-1}(1) - w{k-1}(3)*x2) / w{k-1}(2); pause(p); set(h,'XData',x1,'YData',x2); % circle misclassfied if ~isempty(M) set(h1,'XData',M(:,1),'YData',M(:,2)); m = length(M(:,1)); else set(h1,'XData',[],'YData',[]); m = 0; end % do the title set_title(w{k-1},k-1,m); end k = k-1; % result = is_misclassified(I,w,c) % returns the index of the first misclassified input vector % in I if no input vectors in I are misclassifed returns 0 function result = is_misclassified(I,w,c,r) result = 0; ij = I * w; for i = 1:r if (ij(i) <= 0 && c(i) ~= -1) || (ij(i) > 0 && c(i) ~= 1) result = i; return; end end %NOTE: not the best way of doing but this is a quick fix % should combine this with is_misclassifed % M = misclassified(I,w,c) % M is a list of missclassfied samples function M = misclassified(I,w,c,r) ij = I * w; M = []; for i = 1:r if (ij(i) <= 0 && c(i) ~= -1) || (ij(i) > 0 && c(i) ~= 1) M = [M ; I(i,2:end)]; end end % set_title(w) % sets the title to the equation specified by w % and the next line, k = num iterations, m = num misclassifications function set_title(w,k,m) % given w = [w0 ,w1 w2], set the title to the equation % w1x1 + w2x2 = w0 or w1x1 - w2x2 = w0 % depending on whether w2 is > 0 or < 0 op = ' + '; if w(3) < 0 op = ' - '; end % for w1 and w2: if they're 1 (-1) simplify % not worrying about 0 right now if abs(w(2)) == 1 if w(2) > 0 w1 = ''; else wi = '-'; end else w1 = num2str(w(2)); end % for w2 if abs(w(3)) == 1 w2 = ''; else w2 = num2str(abs(w(3))); end % for w0, move w(1) to the right of the equation w0 = num2str(-w(1)); title(['Perceptron: ',w1,'x_1',op,w2,'x_2 = ',w0,char(10), ... 'k = ',num2str(k),' m = ',num2str(m)]);