Determine accuracy of a model in matlab - matlab

I am currently trying to make some plot showing that GMM is better at modeling data than MNN (multi model normal distribution), but can't make a plot in which both fits are in. Here is my current code:
MU1 = [1 2];
SIGMA1 = [2 0; 0 .5];
MU2 = [4 6];
SIGMA2 = [1 0; 0 1];
rng(1); % For reproducibility
X = [mvnrnd(MU1,SIGMA1,1000);
mvnrnd(MU2,SIGMA2,1000)];
figure;
scatter(X(:,1),X(:,2),10,'.')
options = statset('Display','final');
gm = fitgmdist(X,2,'Options',options); % GMM fit
G = fitgmdist(X,1) % fit MNN - only 1 component are being used
gmPDF = #(x,y)pdf(gm,[x y]);
F = #(x,y) pdf(G,[x y])
hold on
%h = ezcontour(gmPDF,[-3 10],[-3 10]);
d = ezcontour(F,[-3 10],[-3 10]);
title('Scatter Plot and PDF Contour')
hold off
%%
close all
I am able to see the plots, but can i somehow print the accuracy of both?
Something like number of outliers or something else?

Related

Gaussian mixture model - get the contour of given probability value : Matlab

I need to identify the 99% probability contour of a GMM fitted to data. Following this example, I'd like to be able to specify which contours to plot, and the x,y, of them.
mu1 = [1 2]; Sigma1 = [2 0; 0 0.5];
mu2 = [-3 -5]; Sigma2 = [1 0;0 1];
X = [mvnrnd(mu1,Sigma1,1000); mvnrnd(mu2,Sigma2,1000)];
GMModel = fitgmdist(X,2);
figure
y = [zeros(1000,1);ones(1000,1)];
h = gscatter(X(:,1),X(:,2),y);
hold on
gmPDF = #(x,y) arrayfun(#(x0,y0) pdf(GMModel,[x0 y0]),x,y);
g = gca;
fcontour(gmPDF,[g.XLim g.YLim])
title('{\bf Scatter Plot and Fitted Gaussian Mixture Contours}')
legend(h,'Model 0','Model1')
hold off
So, in the following figure, I'd like to to be able to plot the 99% in dashed black line "k". Any idea how to accomplish this?
You can display and get the coordinates of the given contour line specifying the LevelList property of fcontour, and then reading the ContourMatrix property of the contour handle:
% Random function, insert here yours
f = #(x,y) arrayfun(#(x0,y0) x0.^2 + y0.^2 - 0.1,x,y);
% The function value you want to get the contour for
lvl = 0.99;
% Plot the contour line
cHandle = fcontour(f, '--k', 'LevelList', [lvl]);
hold on
% Get the coordinates
lvlX = cHandle.ContourMatrix(1, 2:end);
lvlY = cHandle.ContourMatrix(2, 2:end);
% For a check:
plot(lvlX, lvlY, '--r')

Plotting linear hyperplane using primal vector in Matlab

Using svmtrain and svmmodel, we're supposed to plot a hyperplane to separate two collections of data. Through the sample, I have the data:
c = [1 1; 2 1.5; 2 1;3 1.5];
N = 10; X = []; sigma = 0.2;
for i = 1:4
X = [X; sigma*randn(N,2) + repmat(c(i,:),N,1)];
end
Y = [ones(1,2*N) -ones(1,2*N)];
plot(X(1:end/2,1),X(1:end/2,2),'+')
hold all
plot(X(end/2+1:end,1),X(end/2+1:end,2),'o')
hold on
So, from my understanding, I have to use the primal vector to obtain the hyperplane as: y = w'x + b, which is the following:
model = svmtrain(Y',X,'-s 0 -t 0 -c 1')
w = model.SVs' * model.sv_coef;
b = -model.rho;
if model.Label(1) == -1
w = -w;
b = -b;
end
However, when I add
plot(w+b)
I get:
Which is not the desired hyperplane. I've played with the values as much as I can and looked up different samples of this kind, but I can't figure out how I'm supposed to use the primal and bias to produce the proper hyperplane.

Plot step response without using step function

I want to plot the step response. I know that I can use step function with state space equations, but I try to get same results using plot function. Here is my sample of code:
for i=1:201
u(i) = 1;
x1(i+1) = (-(b/J)*x1(i) + (K/J)*x2(i));
x2(i+1) = (-(K/L)*x1(i) - (R/L)*x2(i) + (1/L)*u(i));
y(i) = x1(i);
end
and this is the state space equations:
A = [-b/J K/J
-K/L -R/L];
B = [0
1/L];
C = [1 0];
D = 0;
If i do:
t = 0:1:200;
plot(t, y)
it is not working and I want to have the same results like the step function below:
sys = ss(A,B,C,D);
step(sys)
You can find my state space equation here.
The reason for the mismatch is that sys is a continuous time model, whereas the computation of y treats it as a discrete-time system.
The following is a way of estimating the step-response of a continuous-time system in the discrete-time domain:
% Given from the problem statement
A = [-b/J K/J
-K/L -R/L];
B = [0
1/L];
C = [1 0];
D = 0;
% this is your continuous-time model
sys = ss(A,B,C,D);
% define the sample rate of the equivalent discrete-time model
Ts = 1/10;
% this needs to be something smaller than the time-constants in your model,
% so that you have enough resolution to represent the continuous-time
% signal.
% convert the system to the equivalent discrete-time model
sysd = c2d(sys,Ts);
% define how long a step response you'd like to compute
T = 7;
% this should be long enough to cover the length of the step response
t = 0:Ts:T; % time-grid for the plot
nSmp = length(t); % total number of samples to be computed
% initializations
y = NaN(1, nSmp); % output vector
u = ones(1, nSmp); % unit step input
X = [0; 0]; % state vector, initialized to 0
% compute the samples of the step-response
% (i prefer to use vectorized form to keep the code concise)
for i=1:nSmp
y(i) = sysd.C * X + sysd.D * u(i);
X = sysd.A * X + sysd.B * u(i);
end
% plot continous-time step response
figure;
step(sys);
% plot simulated discrete-time step response
figure;
plot(t, y, 'r')
xlabel('Time (s)');
ylabel('Amplitude');
title('Simulated Step Response');

How to plot a matlab function for different parameters using hold on command

I have a matlab function that contain some constant parameter, I want to draw that function, on say same figure, using hold on (probably) while changing the value of that constant.
This my code:
close all
clear all
clc
m = 5;
x = 1:1:10;
y = m*x + 10;
h1 = figure;
plot(x,y)
m = 10;
figure(h1);
hold on
plot(x,y,': r')
When I tried using this code, I got two lines coincident on each others; and it looks matlab just used last value for the parameter m how can I make it use different values.
I found some stuff here, but doesn't fulfill my needs.
Any suggestions?
You need to recalculate y as well:
m = 5;
x = 1:1:10;
y = m*x + 10;
h1 = figure;
plot(x,y); hold on;
m = 10;
y = m*x + 10;
figure(h1);
plot(x,y,': r')
Or create an anonymous function:
x = 1:1:10;
f = #(m) m*x + 10;
%// and then:
h1 = figure;
plot(x,f(5) ); hold on;
plot(x,f(10),': r');
Currently, you're only updating m but you also have to calculate y again. This is why it plots exactly the same y (i.e. m is still 5) function when you issue the second plot.
You might want to use a simple for loop for that, like:
m = 5;
x = 1:1:10;
figure;
hold on;
for m=1:1:10
y = m*x + 10;
plot(x,y,': r')
end
In addition to the short answer - improving the plot..
%% Data Preparations
x = 1:10;
ms = 3; % number of different slopes
%% Graph Preparations
hold on;
% Prepare the string cell array
s = cell(1, ms);
% Handle storage
h = zeros(1, ms);
% Plot graphs
for m=1:ms
y = m*x + 10;
h(m)= plot(x,y,'Color',[1/m rand() rand()]);
s{m} = sprintf('Plot of y(m=%d)', m);
end
% Plot all or select the plots to include in the legend
ind = [ms:-1:1] .* ones(1,ms); % plot all
%ind = [ 1 3 4 ]; % plot selected
% Create legend for the selected plots
legend(h(ind), s{ind});
Additional advice: When working with MATLAB and you try to improve the performance of your code, you shoud try to avoid using for-loops since MATLAB is MATrix manipulation and that's what it can do best. Ones you've taken this philosophy in, you'll create the most beautiful code one-liners! ;)
This script is an adoption of Steve Lord's post.

Splitting data into two classes visually in matlab

I have two clusters of data each cluster has x,y (coordinates) and a value to know it's type(1 class1,2 class 2).I have plotted these data but i would like to split these classes with boundary(visually). what is the function to do such thing. i tried contour but it did not help!
Consider this classification problem (using the Iris dataset):
As you can see, except for easily separable clusters for which you know the equation of the boundary beforehand, finding the boundary is not a trivial task...
One idea is to use the discriminant analysis function classify to find the boundary (you have a choice between linear and quadratic boundary).
The following is a complete example to illustrate the procedure. The code requires the Statistics Toolbox:
%# load Iris dataset (make it binary-class with 2 features)
load fisheriris
data = meas(:,1:2);
labels = species;
labels(~strcmp(labels,'versicolor')) = {'non-versicolor'};
NUM_K = numel(unique(labels)); %# number of classes
numInst = size(data,1); %# number of instances
%# visualize data
figure(1)
gscatter(data(:,1), data(:,2), labels, 'rb', '*o', ...
10, 'on', 'sepal length', 'sepal width')
title('Iris dataset'), box on, axis tight
%# params
classifierType = 'quadratic'; %# 'quadratic', 'linear'
npoints = 100;
clrLite = [1 0.6 0.6 ; 0.6 1 0.6 ; 0.6 0.6 1];
clrDark = [0.7 0 0 ; 0 0.7 0 ; 0 0 0.7];
%# discriminant analysis
%# classify the grid space of these two dimensions
mn = min(data); mx = max(data);
[X,Y] = meshgrid( linspace(mn(1),mx(1),npoints) , linspace(mn(2),mx(2),npoints) );
X = X(:); Y = Y(:);
[C,err,P,logp,coeff] = classify([X Y], data, labels, classifierType);
%# find incorrectly classified training data
[CPred,err] = classify(data, data, labels, classifierType);
bad = ~strcmp(CPred,labels);
%# plot grid classification color-coded
figure(2), hold on
image(X, Y, reshape(grp2idx(C),npoints,npoints))
axis xy, colormap(clrLite)
%# plot data points (correctly and incorrectly classified)
gscatter(data(:,1), data(:,2), labels, clrDark, '.', 20, 'on');
%# mark incorrectly classified data
plot(data(bad,1), data(bad,2), 'kx', 'MarkerSize',10)
axis([mn(1) mx(1) mn(2) mx(2)])
%# draw decision boundaries between pairs of clusters
for i=1:NUM_K
for j=i+1:NUM_K
if strcmp(coeff(i,j).type, 'quadratic')
K = coeff(i,j).const;
L = coeff(i,j).linear;
Q = coeff(i,j).quadratic;
f = sprintf('0 = %g + %g*x + %g*y + %g*x^2 + %g*x.*y + %g*y.^2',...
K,L,Q(1,1),Q(1,2)+Q(2,1),Q(2,2));
else
K = coeff(i,j).const;
L = coeff(i,j).linear;
f = sprintf('0 = %g + %g*x + %g*y', K,L(1),L(2));
end
h2 = ezplot(f, [mn(1) mx(1) mn(2) mx(2)]);
set(h2, 'Color','k', 'LineWidth',2)
end
end
xlabel('sepal length'), ylabel('sepal width')
title( sprintf('accuracy = %.2f%%', 100*(1-sum(bad)/numInst)) )
hold off