How to use matlab contourf to draw two-dimensional decision boundary - matlab

I finished an SVM training and got data like X, Y. X is the feature matrix only with 2 dimensions, and Y is the classification labels. Because the data is only in two dimensions, so I would like to draw a decision boundary to show the surface of support vectors.
I use contouf in Matlab to do the trick, but really find it hard to understand how to use the function.
I wrote like:
#1 try:
contourf(X);
#2 try:
contourf([X(:,1) X(:,2) Y]);
#3 try:
Z(:,:,1)=X(Y==1,:);
Z(:,:,2)=X(Y==2,:);
contourf(Z);
all these things do not correctly. And I checked the Matlab help files, most of them make Z as a function, so I really do not know how to form the correct Z matrix.

If you're using the svmtrain and svmclassify commands from Bioinformatics Toolbox, you can just use the additional input argument (...'showplot', true), and it will display a scatter plot with a decision boundary and the support vectors highlighted.
If you're using your own SVM, or a third-party tool such as libSVM, what you probably need to do is to:
Create a grid of points in your 2D input feature space using the meshgrid command
Classify those points using your trained SVM
Plot the grid of points and the classifications using contourf.
For example, in kind-of-MATLAB-but-pseudocode, assuming your input features are called X1 and X2:
numPtsInGrid = 100;
x1Range = linspace(x1lower, x1upper, numPtsInGrid);
x2Range = linspace(x2lower, x2upper, numPtsInGrid);
[X1, X2] = meshgrid(x1Range, x2Range);
Z = classifyWithMySVMSomehow([X1(:), X2(:)]);
contourf(X1(:), X2(:), Z(:))
Hope that helps.

I know it's been a while but I will give it a try in case someone else will come up with that issue.
Assume we have a 2D training set so as to train an SVM model, in other words the feature space is a 2D space. We know that a kernel SVM model leads to a score (or decision) function of the form:
f(x) = sumi=1 to N(aiyik(x,xi)) + b
Where N is the number of support vectors, xi is the i -th support vector, ai is the estimated Lagrange multiplier and yi the associated class label. Values(scores) of decision function in way depict the distance of the observation x frοm the decision boundary.
Now assume that for every point (X,Y) in the 2D feature space we can find the corresponding score of the decision function. We can plot the results in the 3D euclidean space, where X corresponds to values of first feature vector f1, Y to values of second feature f2, and Z to the the return of decision function for every point (X,Y). The intersection of this 3D figure with the Z=0 plane gives us the decision boundary into the two-dimensional feature space. In other words, imagine that the decision boundary is formed by the (X,Y) points that have scores equal to 0. Seems logical right?
Now in MATLAB you can easily do that, by first creating a grid in X,Y space:
d = 0.02;
[x1Grid,x2Grid] = meshgrid(minimum_X:d:maximum_X,minimum_Y:d:maximum_Y);
d is selected according to the desired resolution of the grid.
Then for a trained model SVMModel find the scores of every grid's point:
xGrid = [x1Grid(:),x2Grid(:)];
[~,scores] = predict(SVMModel,xGrid);
Finally plot the decision boundary
figure;
contour(x1Grid,x2Grid,reshape(scores(:,2),size(x1Grid)),[0 0],'k');
Contour gives us a 2D graph where information about the 3rd dimension is depicted as solid lines in the 2D plane. These lines implie iso-response values, in other words (X,Y) points with same Z value. In our occasion contour gives us the decision boundary.
Hope I helped to make all that more clear. You can find very useful information and examples in the following links:
MATLAB's example
Representation of decision function in 3D space

Related

Levenberg-Marquardt algorithm for 3D data

I have a point cloud in 3D whose coordinates are stored in a 3D vector, and I would like to fit a nonlinear function to the point cloud.
Do you know if the lsqcurvefit algorithm implemented in MATLAB works for 3D data as well?
Do you have any example data that uses 'levenberg-marquardt' for 3D data using MATLAB?
options = optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt');
Yes, you can still use lsqcurvefit in 3D, but if you want to keep your code as simple as possible (see edit) I suggest the lsqnonlin function for multivariate nonlinear data fitting. The linked documentation page shows several examples, one of which uses the Levenberg-Marquardt algorithm in 2D. In 3D or higher, the usage is similar.
For instance, suppose you have a cloud of points in 3D whose coordinates are stored in the arrays x, y and z. Suppose you are looking for a fitting surface (no longer a curve because you are in 3D) of the form z = exp(r1*x + r2*y), where r1 and r2 are coefficients to be found. You start by defining the following inline function
fun = #(r) exp(r(1)*x + r(2)*y) - z;
where r is an unknown 1x2 array whose entries will be your unknown coefficients (r1 and r2). We are ready to solve the problem:
r0 = [1,1]; % Initial guess for r
options = optimoptions(#lsqnonlin, 'Algorithm', 'levenberg-marquardt');
lsqnonlin(fun, r0, [], [], options)
You will get the output on the command window.
Tested on MATLAB 2018a.
Hope that helps.
EDIT: lsqcurvefit vs lsqnonlin
lsqcurvefit is basically a special case of lsqnonlin. The discussion on whichever is better in terms of speed and accuracy is wide and is beyond the scope of this post. There are two reasons why I have suggested lsqnonlin:
You are free to take x, y, z as matrices instead of column vectors, just make sure that the dimensions match. In fact, if you use lsqcurvefit, your fun must have an additional argument xdata defined as [x, y] where x and y are taken in column form.
You are free to choose your fitting function fun to be implicit, that is of the form f(x,y,z)=0.

3d plot with ksdensity in matlab

I have a problem in matlab.
I used a ksdensity function on a vector of deltaX, which was my computed X minus actual X.
And I did the same on deltaY.
Then I used plot on that data. This gave me two 2d plots.
As I have two plots showing how (in)accurate was my system in computing X and Y (something like gaussian bell it was). Now I would like to have one plot but in 3d.
The code was just like that:
[f,xi] = ksdensity(deltaX);
figure;
plot(xi,f)
Ok what I'm about to show is probably not the correct way to visualize your problem, mostly because I'm not quite sure I understand what you're up to. But this will show you an example of how to make the Z matrix as discussed in the comments to your question.
Here's the code:
x = wgn(1000,1,5);%create x and y variables, just noise
y = wgn(1000,1,10);
[f,xi] = ksdensity(x);%compute the ksdensity (no idea if this makes real-world sense)
[f2,xi2] = ksdensity(y);
%create the Z matrix by adding together the densities at each x,y pair
%I doubt this makes real-world sense
for z=1:length(xi)
for zz = 1:length(xi2)
Z(z,zz) = f(z)+f2(zz);
end
end
figure(1)
mesh(xi,xi2,Z)
Here's the result:
I leave it up to you to determine the correct way to visualize your density functions in 3D, this is just how you could make the Z matrix. In short, the Z matrix contains the plot elevation at each x,y coordinate. Hope this helps a little.

how to do clustering when the input is 3D matrix, MATLAB

i am having 3D matrix in which most of the values are zeros but there are some nonzeros values.
when I am plotting this 3D matrix in matlab I am getting plot like as below
here u can see there are two groups of points are nearer to each other(that's why the color became dark) and two individual group of points is far away....
so my objective is to cluster that two nearer group of points and make it as one cluster1 and other two will be called as cluster2 and cluster3 ....
I tried kmeans clustering, BIC clustering...but as kmeans clustering is basically build up for 2D data input, I faced hurdle there ...then I reshape 3D matrix into 2D matrix but still I am getting another error Subscripted assignment dimension mismatch
so could u plz come out with some fruitful idea to do this......
Based on your comment that you used vol3d I assume that your data has to interpreted this way. If your data-matrix is called M, try
[A,B,C] = ind2sub(size(M),find(M));
points = [A,B,C];
idx = kmeans(points,3);
Here, I assumed that M(i,j,k) = 1 means that you have measured a point with properties i,j and k, which in your case would be velocity, angle and range.

matlab: cdfplot of relative error

The figure shown above is the plot of cumulative distribution function (cdf) plot for relative error (attached together the code used to generate the plot). The relative error is defined as abs(measured-predicted)/(measured). May I know the possible error/interpretation as the plot is supposed to be a smooth curve.
X = load('measured.txt');
Xhat = load('predicted.txt');
idx = find(X>0);
x = X(idx);
xhat = Xhat(idx);
relativeError = abs(x-xhat)./(x);
cdfplot(relativeError);
The input data file is a 4x4 matrix with zeros on the diagonal and some unmeasured entries (represent with 0). Appreciate for your kind help. Thanks!
The plot should be a discontinuous one because you are using discrete data. You are not plotting an analytic function which has an explicit (or implicit) function that maps, say, x to y. Instead, all you have is at most 16 points that relates x and y.
The CDF only "grows" when new samples are counted; otherwise its value remains steady, just because there isn't any satisfying sample that could increase the "frequency".
You can check the example in Mathworks' `cdfplot1 documentation to understand the concept of "empirical cdf". Again, only when you observe a sample can you increase the cdf.
If you really want to "get" a smooth curve, either 1) add more points so that the discontinuous line looks smoother, or 2) find any statistical model of whatever you are working on, and plot the analytic function instead.

Matlab plot function defined on a complex coordinate

I would like to plot some figures like this one:
-axis being real and imag part of some complex valued vector(usually either pure real or imag)
-have some 3D visualization like in the given case
First, define your complex function as a function of (Re(x), Im(x)). In complex analysis, you can decompose any complex function into its real parts and imaginary parts. In other words:
F(x) = Re(x) + i*Im(x)
In the case of a two-dimensional grid, you can obviously extend to defining the function in terms of (x,y). In other words:
F(x,y) = Re(x,y) + i*Im(x,y)
In your case, I'm assuming you'd want the 2D approach. As such, let's use I and J to represent the real parts and imaginary parts separately. Also, let's start off with a simple example, like cos(x) + i*sin(y) which is based on the very popular Euler exponential function. It isn't exact, but I modified it slightly as the plot looks nice.
Here are the steps you would do in MATLAB:
Define your function in terms of I and J
Make a set of points in both domains - something like meshgrid will work
Use a 3D visualization plot - You can plot the individual points, or plot it on a surface (like surf, or mesh).
NB: Because this is a complex valued function, let's plot the magnitude of the output. You were pretty ambiguous with your details, so let's assume we are plotting the magnitude.
Let's do this in code line by line:
% // Step #1
F = #(I,J) cos(I) + i*sin(J);
% // Step #2
[I,J] = meshgrid(-4:0.01:4, -4:0.01:4);
% // Step #3
K = F(I,J);
% // Let's make it look nice!
mesh(I,J,abs(K));
xlabel('Real');
ylabel('Imaginary');
zlabel('Magnitude');
colorbar;
This is the resultant plot that you get:
Let's step through this code slowly. Step #1 is an anonymous function that is defined in terms of I and J. Step #2 defines I and J as matrices where each location in I and J gives you the real and imaginary co-ordinates at their matching spatial locations to be evaluated in the complex function. I have defined both of the domains to be between [-4,4]. The first parameter spans the real axis while the second parameter spans the imaginary axis. Obviously change the limits as you see fit. Make sure the step size is small enough so that the plot is smooth. Step #3 will take each complex value and evaluate what the resultant is. After, you create a 3D mesh plot that will plot the real and imaginary axis in the first two dimensions and the magnitude of the complex number in the third dimension. abs() takes the absolute value in MATLAB. If the contents within the matrix are real, then it simply returns the positive of the number. If the contents within the matrix are complex, then it returns the magnitude / length of the complex value.
I have labeled the axes as well as placed a colorbar on the side to visualize the heights of the surface plot as colours. It also gives you an idea of how high and how long the values are in a more pleasing and visual way.
As a gentle push in your direction, let's take a slice out of this complex function. Let's make the real component equal to 0, while the imaginary components span between [-4,4]. Instead of using mesh or surf, you can use plot3 to plot your points. As such, try something like this:
F = #(I,J) cos(I) + i*sin(J);
J = -4:0.01:4;
I = zeros(1,length(J));
K = F(I,J);
plot3(I, J, abs(K));
xlabel('Real');
ylabel('Imaginary');
zlabel('Magnitude');
grid;
plot3 does not provide a grid by default, which is why the grid command is there. This is what I get:
As expected, if the function is purely imaginary, there should only be a sinusoidal contribution (i*sin(y)).
You can play around with this and add more traces if you need to.
Hope this helps!