1
votes

Say I want to randomly select 3 rows from matrix m

m = [1 2 1; 1 1 1; 1 1 1; 2 1 1; 2 2 1; 1 1 1; 1 1 1; 2 1 1];
sample = m(randsample(1:length(m),3),:)

However, I want to randomly select rows with weights. So I need a vector that corresponds to each row of m. I want to apply a weighting to each row depending on the number (or ratio) of 1 and 2 that are present in each row.

Perhaps something like this?

w1 = 0.6;                 %weight of 1
w2 = 0.4;                 %weight of 2
w = m;
w(w == 1) = w1;
w(w == 2) = w2;
w = (sum(w,2))*0.1        %vector of weights

But this is wrong:

sample = m(randsample(1:length(m),2),:,true,w)

Please help.

1
Presumably it's because your syntax is wrong, and you need m(randsample(1:length(m),2,true,w),:). - Phil Goddard

1 Answers

2
votes

Staying with your code, I think you were needed to normalize the weights and then select rows based on the random samples calculated from randsample using the normalized weights. So, the following changes are needed for your code -

w = sum(w,2)./sum(sum(w,2)) %// Normalize weights
sample = m(randsample([1:size(m,1)], 3, true, w) ,:)

Or if I can start-over and want to make the code concise, I could do like so -

%// Inputs
m = [1 2 1; 1 1 1; 1 1 1; 2 1 1; 2 2 1; 1 1 1; 1 1 1; 2 1 1]
w1 = 0.6;                 %// weight of 1
w2 = 0.4;                 %// weight of 2

%// Scale each row of w according to the weights assigned for 1 and 2.
%// Thus, we will have weights for each row
sum_12wts = sum(w1.*(m==1),2) + sum(w2.*(m==2),2)

%// Normalize the weights, so that they add upto 1, as needed for use with
%// randsample
norm_weights = sum_12wts./sum(sum_12wts)

%// Get 3 random row indices from m using randsample based on normalized weights
row_ind = randsample([1:size(m,1)], 3, true, norm_weights) 

%// Index into m to get the desired output
out = m(row_ind,:)