suppose I have w and b, then how to draw the classifier in Matlab? suppose the nodes are in 2-D space, that is to say, x=(x1,x2).
I've tried several methods, but can't draw the classifier y=w^T x+b? Any help?
In that case, w is a 2d vector as well.
Say that you have the following data:
datawX = [1,1,3,2,0,0,0]
datawY = [2,0,1,4,2,1,0]
databX = [1,0,2,5,4,4,2]
databY = [1,0,2,2,4,4,4]
Then you calculate the classifier using the Support-vector machine method.
Say the result is w=[3,1] and b=1.5, in that case the direction of the vector is perpendicular to w so d=[-w(2),w(1)]. So you can define two points p1 and p2.
after performing the svm:
p1=-b*w
p2=d-b*w
w=[3,1]
b=1.5
d=[-w(2),w(1)]
p1=-b*w
p2=d-b*w
scatter(dataw, 'r')
hold on
scatter(datab, 'g')
hold on
plot([p1;p2],'b');
Related
I have 7 classes within my training examples (labeled 1-7). I'm running logistic regression and I want to create my ROC curve for each of my classes.
To train my model and make a prediction, I have the following code:
Theta = zeros(k, n+1); %initialize theta
[Theta, costs] = gradientDescent(Theta, #(t)(CostFunc(t, X, Y, lambda)),...
#(t)(DerivOfCostFunc(t, X, Y, lambda)), alpha, iter_num);
%Make prediction with trained model
[scores,prediction] = predict(Theta, X_test); %X_test is the design matrix (ones on the first col)
Within the predict script, I have
scores = g(X*all_theta'); %this is the sigmoid function
[p_max, IndexOfMax]=max(scores, [], 2);
prediction = IndexOfMax;
Note that scores is a m by k matrix, where m is the number of training examples and k is the number of classes. Prediction is a m by 1 vector with numbers going from 1-7, based on the predicted class.
To create the ROC curve, for class 3 for example,
classNum=3;
for i=1:size(scores,1)
temp=scores(i,:);
diffscore(i,:)=temp(classNum)-max([temp(:,1:classNum-1),temp(:,classNum+1:end)]);
end
This last part I did because I read that I had to establish my class 3 as positive and the others as negative.
At last, I made my curve with the following code:
[xROC,yROC,~,auc] = perfcurve(y_test,diffscore,classNum);
%y_test contains my true labels, m by 1 column vector
However, when running the ROC curve for each of my classes, I get the same plot for all. They all have an AUC of 1. Based on some analysis, I know this is not correct but can't figure out in which part of the code I went wrong! Is there additional code I should add or should I need to modify any of my existing code?
I am converting numpy code to matlab. tensor is a 3D matrix of 6 x 2D matrices of the tensor components. This code appears to then split them back into those 6 separate 2D matrices.
gxx, gxy, gxz, gyy, gyz, gzz = tensor
Can I do this as eloquently in matlab?
re OmG: gxx, etc are the six tensor components of a gravity grid. xx for 2nd derivative of x in the x direction, xy is the 2nd derivative of x in the y direction, etc. Those components will be put through a simple equation to calculate the invariants which will then calculate the depth of the gravity anomaly.
As #Div-iL says, you could simply assign each variable to a slice of the 3D array:
tensor = rand(5,3,6); % Random data to play with
gxx = tensor(:,:,1);
gxy = tensor(:,:,2);
% etc
However if you really wanted to do it automatically you could generate a cell-array of 2D arrays (using mat2cell) and then assign them to variables using a comma-separated list assignment:
[nx,ny,nz] = size(tensor);
ca = mat2cell(tensor, nx, ny, ones(1,nz));
[gxx, gxy, gxz, gyy, gyz, gzz] = ca{:};
However, that all feels a bit hairy to me. If you're looking for a natively-supported one-liner (like your example) then I think you're out of luck.
I have started to learn Machine Learning, and programming in matlab.
I want to plot a matrix sized m*d where d=3 and m are the number of points.
with y binary vector I'd like to color each point with blue/red.
and plot a plane which is described with the vertical vector to it w.
The problem I trying to solve is to give some kind of visual representation of the data and the linear predictor.
All I know is how to single points with plot3, but no any number of points.
Thanks.
Plot the points using scatter3()
scatter3(X(y,1),X(y,2),X(y,3),'filled','fillcolor','red');
hold on;
scatter3(X(~y,1),X(~y,2),X(~y,3),'filled','fillcolor','blue');
or using plot3()
plot(X(y,1),X(y,2),X(y,3),' o','MarkerEdgeColor','red','MarkerFaceColor','red');
hold on;
plot(X(~y,1),X(~y,2),X(~y,3),' o','MarkerEdgeColor','blue','MarkerFaceColor','blue');
There are a few ways to plot a plane. As long as w(3) isn't very close to 0 then the following will work okay. I'm assuming your plane is defined by x'*w+b=0 where b is a scalar and w and x are column vectors.
x1min = min(X(:,1)); x2min = min(X(:,2));
x1max = max(X(:,1)); x2max = max(X(:,2));
[x1,x2] = meshgrid(linspace(x1min,x1max,20), linspace(x2min, x2max, 20));
x3 = -(w(1)*x1 + w(2)*x2 + b)/w(3);
surf(x1,x2,x3,'FaceColor',[0.6,0.6,0.6],'FaceAlpha',0.7,'EdgeColor',[0.4,0.4,0.4],'EdgeAlpha',0.4);
xlabel('x_1'); ylabel('x_2'); zlabel('x_3'); axis('vis3d');
Resulting plot
Suppose I have 3+ coplanar but not collinear points in R^4. To find the 2D plane (not hyperplane) in which they all lie, I used the following plane fit algorithm from MatlabCentral:
function [n,V,p] = affine_fit(X)
% Computes the plane that fits best (least square of the normal distance
% to the plane) a set of sample points.
% INPUTS:
% X: a N by 3 matrix where each line is a sample point
%OUTPUTS:
%n : a unit (column) vector normal to the plane
%V : a 3 by 2 matrix. The columns of V form an orthonormal basis of the plane
%p : a point belonging to the plane
%NB: this code actually works in any dimension (2,3,4,...)
%Author: Adrien Leygue
%Date: August 30 2013
% the mean of the samples belongs to the plane
p = mean(X,1);
% The samples are reduced:
R = bsxfun(#minus,X,p);
% Computation of the principal directions of the samples cloud
[V,D] = eig(R'*R);
% Extract the output from the eigenvectors
n = V(:,1);
V = V(:,2:end);
end
I employed the algorithm in a higher dimension than specified, so X is a 4x4 matrix which holds 4 points in 4 coordinate dimensions. The generated output is something like this.
[n,V,p] = affine_fit(X);
n = -0.0252
-0.0112
0.9151
-0.4024
V = 0.9129 -0.3475 0.2126
0.3216 0.2954 -0.8995
0.1249 0.3532 0.1493
0.2180 0.8168 0.3512
p = -0.9125 1.0526 0.2325 -0.0621
What I want to do now is find out if other points of my choosing are part of the plane, too. I'm sure it's fairly easy given the information above, yet at this point I only know that I need two linear equations to describe a 2D plane in 4D or parametric equations of two variables. I can set them up in theory, but writing up the code has been problematic. Perhaps there is a more straightforward way to test this in matlab?
You can use the Matlab function pca (see for example here). For example, you can determine the basis of your plane, the normal vectors to your plane and a point m on the plane as follows:
coeff = pca(X);
basis = coeff(:,1:2);
normals = coeff(:,3:4);
m = mean(X);
To check if a point p lies in this plane, it suffices to verify that m-p is orthogonal (dot product equal to zero) to the normal vectors onto the plane using dot.
I am just wondering, how would I go about fitting a line to histogram, using the z-counts as weights? An example of this is shown below (although this post just discusses overlaying multiple plots), taken from Scatter plot with density in Matlab).
My initial thought is to make an array consisting of each pixel from the density plot, repeated n times to make a scatter plot (n == the number of counts), then do a linear polyfit. This seems awfully redundant though.
The other approach is to do a weighted least squares solution. You need the (x,y) location of each pixel and the number of counts n within each pixel. Then, I think that you'd do the weighted least-squares this way:
%gather your known data...have x,y, and n all in the same order as each other
A = [x(:) ones(length(x),1)]; %here are the x values from your histogram
b = y(:); %here are the y-values from your histogram
C = diag(n(:)); %counts from each pixel in your 2D histogram
%Define polynomial coefficients as p = [slope; y_offset];
%usual least-squares solution...written here for reference
% b = A*p; %remember, p = [slope; y_offset];
% p = inv(A'*A)*(A'*b); %remember, p = [slope; y_offset];
%We want to apply a weighting matrix, so incorporate the weighting matrix
% A' * b = A' * C * A * p;
p = inv(A' * C * A)*(A' * b); %remember, p = [slope; y_offset];
The biggest uncertainty for me with this solution is whether the C matrix should be made up of n or n.^2, I can never remember. Hopefully, someone can correct me in the comments, if needed.
If you have the original data, which is a collection of (x,y) points, you simply do a polyfit on the original data:
p = polyfit(x(:),y(:),1); %linear fit
That will give you a best fit (in the least-squares sense) to the original data, which is what you want.
If you do not have the original data, and you only have the 2D histogram, the approach that you defined (which basically recreates a facsimile of the original data) will give a similar answer as if you did the polyfit on the original data.