2013-02-11 3 views
1

Итак, позвольте мне сказать, что у меня нет инструментария статистики для Matlab, поэтому я пытаюсь найти способ обойти это. В любом случае, что я пытаюсь сделать, это реплицировать функцию R sample. Например, в RОтбор проб в Matlab

> x = sample(1:5,20,replace=T,prob=c(.1,.1,.1,.1,.6)) 
> x 
[1] 5 5 5 4 5 2 5 5 1 5 5 5 5 5 5 3 5 1 5 5 

поэтому я отбираю целые числа 1,2,3,4,5 с заменой. Но кроме того, я отбираю каждое целое число с определенной долей, т. Е. Целое число 5 следует отбирать около 60% времени.

Итак, мой вопрос, который я хотел бы найти, заключается в том, как добиться этого в Matlab?

+0

Самое простое решение: купить панель инструментов; назовите 'randsample'. http://www.mathworks.co.uk/help/stats/randsample.html :) –

+0

Еще проще (и дешевле): используйте R. Если вы не можете или не хотите избегать Matlab, вы можете [интегрировать R-скрипты в Matlab] (http://rwiki.sciviews.org/doku.php?id=tips:callingr:matlab). – Roland

+0

@ RichieCotton: фактически, «randsample» Matlab не поддерживает взвешенную выборку без замены. – Jonas

ответ

4

Вот как вы можете выполнить взвешенную выборку с заменой (что-то от Matlab randsample не поддерживает, кстати);

function r = sample(pop,n,weights) 
%# each weight creates a "bin" of defined size. If the value of a random number 
%# falls into the bin, we pick the value 

%# turn weights into a normed cumulative sum 
csWeights = cumsum(weights(:))/sum(weights); 
csWeights = [0;csWeights(1:end-1)]; 

%# for each value: pick a random number, check against weights 
idx = sum(bsxfun(@ge,rand(1,n),csWeights),1); 

r = pop(idx); 
+0

Удивительный! Благодаря! – 2013-02-11 16:37:38

+0

@ user2005253: Обратите внимание, что этот подход временно создает массив по длине (поп). Если это означает, что у вас может закончиться нехватка памяти, вы должны предварительно присвоить 'r', создать вектор случайных чисел длины' n', а затем выполнить команду r (i) = pop (sum (randVec (i)> = csWeights) ' внутри цикла. – Jonas

3

Невзвешенный корпус легко использовать randi.

function r = sample(pop, n) 

imax = length(pop); 
index = randi(imax, n, 1); 
r = pop(index); 

end 

В весовом случае, что-то вроде этого следует сделать трюк:

function r = sample(pop, n, prob) 

cumprob = cumsum(prob); 
r = zeros(1, n); 
for i = 1:n 
    index = find(rand < cumprob, 1, 'last'); 
    r(i) = pop(index); 
end 

end 
+0

На данный момент нет MATLAB, поэтому код полностью не тестирован. –

1

Вот один из способов сделать свою собственную sample функцию:

function x = sample(v, n, p) 

pc = cumsum(p)/sum(p); 
r = rand(1,n); 
x = zeros(1,n); 
for i = length(pc):-1:1 
    x(r<pc(i)) = v(i); 
end 

Это не совсем эффективно, но это не то, что вы хотите. Назовите его так:

v = [1 2 3 4 5]; 
p = [.1 .1 .1 .1 .6]; 
n = 20; 
x = sample(v,n,p); 
Смежные вопросы