这是一个有趣的:我需要生成在给定值Pearson product moment correlation coefficient, or Pearson r下相关的随机x / y对。您可以将其想象为两个数组,即数组X和数组Y,其中必须重新生成,重新排序或转换数组X和数组Y的值,直到它们在给定的Pearson r级别彼此相关。这是踢球者:数组X和数组Y必须是统一的分布。
我可以用正态分布做到这一点,但转换值而不会扭曲分布让我感到难过。我尝试重新排序数组中的值以增加相关性,但我永远不会通过排序使数组在1.00或-1.00处相关。
有什么想法吗?
-
这是随机相关高斯人的AS3代码,让车轮转动:
public static function nextCorrelatedGaussians(r:Number):Array{
var d1:Number;
var d2:Number;
var n1:Number;
var n2:Number;
var lambda:Number;
var r:Number;
var arr:Array = new Array();
var isNeg:Boolean;
if (r<0){
r *= -1;
isNeg=true;
}
lambda= ( (r*r) - Math.sqrt( (r*r) - (r*r*r*r) ) ) / (( 2*r*r ) - 1 );
n1 = nextGaussian();
n2 = nextGaussian();
d1 = n1;
d2 = ((lambda*n1) + ((1-lambda)*n2)) / Math.sqrt( (lambda*lambda) + (1-lambda)*(1-lambda));
if (isNeg) {d2*= -1}
arr.push(d1);
arr.push(d2);
return arr;
}
答案 0 :(得分:6)
我最后写了short paper on this
它不包括你的排序方法(虽然在实践中我认为它与我的第一种方法类似,以迂回的方式),但确实描述了两种不需要迭代的方法。
答案 1 :(得分:1)
从模型y = x + e
开始,其中e
是错误(正常的随机变量)。 e
的平均值应为0,方差为k。
当我可以访问某些纸张时,我会尝试回来编辑这篇文章,以包含一个封闭的表单解决方案。
编辑:好的,我有一个手动波浪的解决方案,可能是正确的(但需要测试确认)。现在,假设期望Pearson = p > 0
(您可以找出p < 0
案例)。就像我之前提到的那样,设置Y = X + E
的模型(X
是统一的,E
是正常的)。
(1/(rsd(x)))^2 - var(x)
E
p < 0
,设置Y = -X + E
。相应地进行。
基本上,这是从Pearson的定义得出的:cov(x,y)/ var(x)* var(y)。当你向x(Y = X + E
)添加噪声时,预期的协方差cov(x,y)不应该从没有噪声的那个改变。 var(x)不会改变。 var(y)是var(x)和var(e)的总和,因此我的解决方案。
第二次编辑:好的,我需要更好地阅读定义。 Pearson的定义是cov(x,y)/(sd(x) sd(y))。从那以后,我认为var(E)的真值应该是(1 /(r sd(x)))^ 2 - var(x)。看看是否有效。
答案 2 :(得分:1)
以下是使用Actionscript 3编写的twolfe18算法的实现:
for (var j:int=0; j < size; j++) {
xValues[i]=Math.random());
}
var varX:Number = Util.variance(xValues);
var varianceE:Number = 1/(r*varX) - varX;
for (var i:int=0; i < size; i++) {
yValues[i] = xValues[i] + boxMuller(0, Math.sqrt(varianceE));
}
boxMuller
只是一个使用参数(mean,stdDev)生成随机Gaussian的方法。
size
是分发的大小。
示例输出
Target p: 0.8
Generated p: 0.04846346291280387
variance of x distribution: 0.0707786253165176
varianceE: 17.589920412141158
正如你所看到的,我还有一段路要走。有什么建议吗?
答案 3 :(得分:1)
从昨天晚上开始,这个看似简单的问题一直在搞乱我的想法!我查找了使用依赖项模拟分布的主题,我发现的最好的是:simulate dependent random variables。它的要点是,您可以使用给定的相关性轻松模拟2个法线,并且它们概述了转换这些非独立法线的方法,但这不会保留相关性。可以说,变换的相关性是相关的,但不相同。参见“秩相关系数”一节。
编辑:从我从文章的第二部分收集到的内容,copula方法将允许您模拟/生成具有等级相关性的随机变量。
答案 4 :(得分:1)
要获得1的相关性,X和Y应该相同,因此将X复制到Y并且您的相关性为1.要获得-1相关,请使Y = 1 - X.(假设X值为[0,1])
答案 5 :(得分:1)
一个奇怪的问题需要一个奇怪的解决方案 - 这就是我解决它的方法。
- 生成数组X
- 克隆数组X来创建数组Y
-Sort array X(你可以使用你想要的任何方法对数组X进行排序 - 快速排序,将任何稳定的东西捆绑出来。)
- 测量皮尔逊R的起始等级,数组X排序,数组Y未排序。
WHILE the correlation is outside of the range you are hoping for
IF the correlation is to low
run one iteration of CombSort11 on array Y then recheck correlation
ELSE IF the correlation is too high
randomly swap two values and recheck correlation
就是这样! Combsort是真正的关键,它具有缓慢而稳定地增加相关性的作用。查看Jason Harrison's demo以了解我的意思。要获得负相关,您可以在整个过程完成后反转排序或反转其中一个数组。
这是我在AS3中的实现:
public static function nextReliableCorrelatedUniforms(r:Number, size:int, error:Number):Array {
var yValues:Array = new Array;
var xValues:Array = new Array;
var coVar:Number = 0;
for (var e:int=0; e < size; e++) { //create x values
xValues.push(Math.random());
}
yValues = xValues.concat();
if(r != 1.0){
xValues.sort(Array.NUMERIC);
}
var trueR:Number = Util.getPearson(xValues, yValues);
while(Math.abs(trueR-r)>error){
if (trueR < r-error){ // combsort11 for y
var gap:int = yValues.length;
var swapped:Boolean = true;
while (trueR <= r-error) {
if (gap > 1) {
gap = Math.round(gap / 1.3);
}
var i:int = 0;
swapped = false;
while (i + gap < yValues.length && trueR <= r-error) {
if (yValues[i] > yValues[i + gap]) {
var t:Number = yValues[i];
yValues[i] = yValues[i + gap];
yValues[i + gap] = t;
trueR = Util.getPearson(xValues, yValues)
swapped = true;
}
i++;
}
}
}
else { // decorrelate
while (trueR >= r+error) {
var a:int = Random.randomUniformIntegerBetween(0, size-1);
var b:int = Random.randomUniformIntegerBetween(0, size-1);
var temp:Number = yValues[a];
yValues[a] = yValues[b];
yValues[b] = temp;
trueR = Util.getPearson(xValues, yValues)
}
}
}
var correlates:Array = new Array;
for (var h:int=0; h < size; h++) {
var pair:Array = new Array(xValues[h], yValues[h]);
correlates.push(pair);}
return correlates;
}