考虑以下游戏:在每个试验中,您将看到 x 红色和 y 蓝点。你必须决定是否有更多的红点而不是蓝点。对于每个试验,给定颜色的最小点数为10,最大值为50.红色和蓝色点遵循相同的多项分布(为简单起见,我们考虑每个整数在10到50之间出现的概率是相似的)。
我想建立300个试验。为此,我从每个多项分布中抽取300个样本。重要的是,我想指定(先验)来自第一个分布的300个样本与来自第二个分布的300个样本之间的相关性。我想在五对样本集中找到-0.8,-0.5,0,0.5和0.8的相关性。
优选地,我还想对这些集合进行采样,以便在每个集合(X,Y)中具有任何指定的相关性,X样本中的一半将大于Y(x(i) > y(i)
),并且另一半将小于Y(x(i) < y(i)
)。
我怎么能在python,R或MATLAB中做到这一点?
答案 0 :(得分:1)
基本上你问如何create 2 vectors with a specified correlation,所以它比编程问题更多的统计数据,但它可以通过以下方式完成:
第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
,如果需要某些特定的分布,则可以获取using the it's 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
{1}}。这是一个示例 - 首先是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
足够接近你想。