Working on an assignment from Coursera Machine Learning. I'm curious how this works... From an example, this much simpler code:
% K is the number of classes.
K = num_labels;
Y = eye(K)(y, :);
seems to be a substitute for the following:
I = eye(num_labels);
Y = zeros(m, num_labels);
for i=1:m
Y(i, :)= I(y(i), :);
end
and I have no idea how. I'm having some difficulty Googling this info as well.
Thanks!
Your variable y in this case must be an m-element vector containing integers in the range of 1 to num_labels. The goal of the code is to create a matrix Y that is m-by-num_labels where each row k will contain all zeros except for a 1 in column y(k).
A way to generate Y is to first create an identity matrix using the function eye. This is a square matrix of all zeroes except for ones along the main diagonal. Row k of the identity matrix will therefore have one non-zero element in column k. We can therefore build matrix Y out of rows indexed from the identity matrix, using y as the row index. We could do this with a for loop (as in your second code sample), but that's not as simple and efficient as using a single indexing operation (as in your first code sample).
Let's look at an example (in MATLAB):
>> num_labels = 5;
>> y = [2 3 3 1 5 4 4 4]; % The columns where the ones will be for each row
>> I = eye(num_labels)
I =
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
>> Y = I(y, :)
Y =
% 1 in column ...
0 1 0 0 0 % 2
0 0 1 0 0 % 3
0 0 1 0 0 % 3
1 0 0 0 0 % 1
0 0 0 0 1 % 5
0 0 0 1 0 % 4
0 0 0 1 0 % 4
0 0 0 1 0 % 4
NOTE: Octave allows you to index function return arguments without first placing them in a variable, but MATLAB does not (at least, not very easily). Therefore, the syntax:
Y = eye(num_labels)(y, :);
only works in Octave. In MATLAB, you have to do it as in my example above, or use one of the other options here.
The first set of code is Octave, which has some additional indexing functionality that MATLAB does not have. The second set of code is how the operation would be performed in MATLAB.
In both cases Y is a matrix generated by re-arranging the rows of an identity matrix. In both cases it may also be posible to calculate Y = T*y for a suitable linear transformation matrix T.
(The above assumes that y is a vector of integers that are being used as an indexing variables for the rows. If that's not the case then the code most likely throws an error.)
This question already has answers here:
Finding islands of zeros in a sequence
(6 answers)
Closed 7 years ago.
I'm a new matlab user and in my case i have a vector let say:
v = [0 0 0 0.1 0.2 0.3 0.4 0.5 0 0 0 0 0 0 0.1 0.2]
I want to count consecutive non zero values i.e in my vector have first five nonzero values [0.1 0.2 0.3 0.4 0.5] and two last nozeros values [0.1 0.2]
what I want is:
count the consecutive non zero values and put a condition i.e. if the length of nonzeros is greater then 3 (count>3) then the respective values of vector V(i) remain v(i) if the length consecutive values is less than three (count<3) then respective values of v(i) = 0
I want to get a new vector let say v1 derivated from vector v where:
v1 = [0 0 0 0.1 0.2 0.3 0.4 0.5 0 0 0 0 0 0 0 0]
Any help would be appreciated.
If you have the MATLAB Image Processing Toolbox, you can use the power of morphological operations. The morphological opening (imopen) removes objects which are smaller than the structuring element from an image. We can use this in 2D and use [1,1,1] as structuring element to remove objects, i.e. sequences of nonzero elements, which are shorter than 3:
First we make the sequence binary: zero or nonzero.
w = v~=0;
Then we zero-pad the sequence, so short nonzero sequences at the borders get eliminated. As we use [1,1,1] as structuring element, zero-padding by 1 is sufficient:
w = [0,w,0];
Now we do the opening to remove all small nonzero sequences
w1 = imopen(w, [1,1,1]);
The vector w1 now contains 0 if the corresponding element in v is or should be set to 0 and 1 if the value should be kept. To get the result v1, we can ignore the first and last entry (those are the elements from the zero-padding), and multiply that by the input, as e.g. 1 * 0.1 = 0.1:
v1 = w1(2:end-1) .* v;
Which gives the correct result without any for loop, if statement or such stuff! Only 4 simple operations: morphology and a bit of multiplication and zero-padding.
buffer=0 %Buffer to remember non zero values
v=[0 0 0 0.1 0.2 0.3 0.4 0.5 0 0 0 0 0 0 0.1 0.2];
v1=[];
for i=1:length(v)
if v(i)~=0
buffer=buffer+1;
v1(i)=v(i);
end
if v(i)==0
switch buffer
case 1 % case 1 corresponds to only 1 non zero value in a single sequence
v1(i-1)=0;
buffer=0;
case 2 % case 2 corresponds to only 2 non zero value in a single sequence
v1(i-1)=0;
v1(i-2)=0;
buffer=0;
otherwise
buffer=0;
end
end
end
switch buffer % Test for the last two values
case 1
v1(length(v))=0;
case 2
v1(length(v))=0;
v1(length(v)-1)=0;
end
This should do the trick.
I have a matrix including 1 and 0 elements like below which is used as a network adjacency matrix.
A =
0 1 1 1
1 1 0 1
1 1 0 1
1 1 1 0
I want to simulate an attack on the network, so I must replace some specific percent of 1 elements randomly with 0. How can I do this in MATLAB?
I know how to replace a percentage of elements randomly with zeros, but I must be sure that the element that is replaced randomly, is one of the 1 elements of matrix not zeros.
If you want to change each 1 with a certain probability:
p = 0.1%; % desired probability of change
A_ones = find(A); % linear index of ones in A
A_ones_change = A_ones(rand(size(A_ones))<=p); % entries to be changed
A(A_ones_change) = 0; % apply changes in those entries
If you want to randomly change a fixed fraction of the 1 entries:
f = 0.1; % desired fraction
A_ones = find(A);
n = round(f*length(A_ones));
A_ones_change = randsample(A_ones,n);
A(A_ones_change) = 0;
Note that in this case the resulting fraction may be different to that intended, because of the need to round to an integer number of entries.
#horchler's point is a good one. However, if we keep it simple, then you can just multiple your input matrix to a mask matrix.
>> a1=randint(5,5,[0 1]) #before replacing 1->0
a1 =
1 1 1 0 1
0 1 1 1 0
0 1 0 0 1
0 0 1 0 1
1 0 1 0 1
>> a2=random('unif',0,1,5,5) #Assuming frequency distribution is uniform ('unif')
a2 =
0.7889 0.3200 0.2679 0.8392 0.6299
0.4387 0.9601 0.4399 0.6288 0.3705
0.4983 0.7266 0.9334 0.1338 0.5751
0.2140 0.4120 0.6833 0.2071 0.4514
0.6435 0.7446 0.2126 0.6072 0.0439
>> a1.*(a2>0.1) #And the replacement prob. is 0.1
ans =
1 1 1 0 1
0 1 1 1 0
0 1 0 0 1
0 0 1 0 1
1 0 1 0 0
And other trick can be added to the mask matrix (a2). Such as a different freq. distribution, or a structure (e.g. once a cell is replaced, the adjacent cells become less likely to be replaced and so on.)
Cheers.
The function find is your friend:
indices = find(A);
This will return an array of the indices of 1 elements in your matrix A and you can use your method of replacing a percent of elements with zero on a subset of this array. Then,
A(subsetIndices) = 0;
will replace the remaining indices of A with zero.
Given four binary vectors which represent "classes":
[1,0,0,0,0,0,0,0,0,0]
[0,0,0,0,0,0,0,0,0,1]
[0,1,1,1,1,1,1,1,1,0]
[0,1,0,0,0,0,0,0,0,0]
What methods are available for classifying a vector of floating point values into one of these "classes"?
Basic rounding works in most cases:
round([0.8,0,0,0,0.3,0,0.1,0,0,0]) = [1 0 0 0 0 0 0 0 0 0]
But how can I handle some interference?
round([0.8,0,0,0,0.6,0,0.1,0,0,0]) != [1 0 0 0 0 1 0 0 0 0]
This second case should be a better match for 1000000000, but instead, I have lost the solution entirely as there is no clear match.
I want to use MATLAB for this task.
Find the SSD (sum of squared differences) of your test vector with each "class" and use the one with the least SSD.
Here's some code: I added a 0 to the end of the test vector you provided since it was only 9 digits whereas the classes had 10.
CLASSES = [1,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,1
0,1,1,1,1,1,1,1,1,0
0,1,0,0,0,0,0,0,0,0];
TEST = [0.8,0,0,0,0.6,0,0.1,0,0,0];
% Find the difference between the TEST vector and each row in CLASSES
difference = bsxfun(#minus,CLASSES,TEST);
% Class differences
class_diff = sum(difference.^2,2);
% Store the row index of the vector with the minimum difference from TEST
[val CLASS_ID] = min(class_diff);
% Display
disp(CLASSES(CLASS_ID,:))
For illustrative purposes, difference looks like this:
0.2 0 0 0 -0.6 0 -0.1 0 0 0
-0.8 0 0 0 -0.6 0 -0.1 0 0 1
-0.8 1 1 1 0.4 1 0.9 1 1 0
-0.8 1 0 0 -0.6 0 -0.1 0 0 0
And the distance of each class from TEST looks like this, class_diff:
0.41
2.01
7.61
2.01
And obviously, the first one is the best match since it has the least difference.
This is the same thing as Jacob did, only with four different distance measures:
Euclidean distance
City-block distance
Cosine distance
Chebychev distance
%%
CLASSES = [1,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,1
0,1,1,1,1,1,1,1,1,0
0,1,0,0,0,0,0,0,0,0];
TEST = [0.8,0,0,0,0.6,0,0.1,0,0,0];
%%
% sqrt( sum((x-y).^2) )
euclidean = sqrt( sum(bsxfun(#minus,CLASSES,TEST).^2, 2) );
% sum( |x-y| )
cityblock = sum(abs(bsxfun(#minus,CLASSES,TEST)), 2);
% 1 - dot(x,y)/(sqrt(dot(x,x))*sqrt(dot(y,y)))
cosine = 1 - ( CLASSES*TEST' ./ (norm(TEST)*sqrt(sum(CLASSES.^2,2))) );
% max( |x-y| )
chebychev = max( abs(bsxfun(#minus,CLASSES,TEST)), [], 2 );
dist = [euclidean cityblock cosine chebychev];
%%
[minDist classIdx] = min(dist);
Pick the one you like :)
A simple Euclidean distance algorithm should suffice. The class with the minimum distance to the point would be your candidate.
http://en.wikipedia.org/wiki/Euclidean_distance