Обычно вы спрашиваете, как создать 2 вектора с заданной корреляцией, так что это больше статистика, чем вопрос программирования, но это можно сделать следующим образом:
шаг 1 - создание двух векторов с желаемой корреляцией
r = 0.75; % r is the desired correlation
M = rand(10000,2); % two vectors from uniform distribution between 0 to 1
R = [1 r; r 1];
L = chol(R); % this is Cholesky decomposition of R
M = M*L; % when multiplied by M it gives the wanted correlation
M = (M+abs(min(M(:)))); % shift the vector to only positive values
M = M./max(M(:)); % normalize the vector...
M = round(40*M)+10; % ...to values between 10 to 50
disp([min(M(:)) max(M(:))])
first_r = corr( M(:,1), M(:,2)); % and check the resulted correlation
Функцию rand
можно заменить на любую функцию случайных сгенерированных чисел, например randi
или randn
, и, если требуется какое-то конкретное распределение, его можно получить используя его cdf.
шаг 2 - выборка этих векторов для двух наборов выборок, один с x> y, а другой с y> x.
x = M(:,1);
y = M(:,2);
Xy = x>y; % logical index for all x > y
Yx = y>x; % logical index for all y > x
xy1 = datasample([x(Xy) y(Xy)],150,'Replace',false); % make a 1/2 sample like Xy
xy2 = datasample([x(Yx) y(Yx)],150,'Replace',false); % make a 1/2 sample like Yx
x = [xy1(:,1);xy2(:,1)]; % concat the smaples back to x
y = [xy1(:,2);xy2(:,2)]; % concat the smaples back to y
checkx = sum(x>y) % how many times x is bigger than y
checky = sum(y>x) % how many times y is bigger than x
final_r = corr(x,y) % and check the new correlation
шаг 3 - исправление корреляции
Как вы увидите, final_r
не похож на желаемый r
, поэтому, чтобы получить его, вам нужно сместить первый r
на расстояние от final_r
. Вот пример - сначала вывод, когда r = 0.75
:
10 50
checkx =
150
checky =
150
final_r =
0.67511
мы видим, что final_r
сдвигается вниз на 0,074886, поэтому мы хотим сдвинуть исходный r
вверх на это значение, чтобы получить правильное final_r
. Итак, если мы снова запустим его с r = 0.75+0.074886
, мы получим:
10 50
checkx =
150
checky =
150
final_r =
0.76379
что довольно близко к желаемому r
. Я бы запустил цикл по процессу, скажем, 1000 раз, чтобы найти самый близкий r
к желаемому, или просто установил бы порог, который продолжал бы поиск, пока final_r
не станет достаточно близким к тому, что вы хотите.
person
EBH
schedule
26.07.2016