Java 生成相关数

Java 生成相关数,java,actionscript-3,statistics,random,random-sample,Java,Actionscript 3,Statistics,Random,Random Sample,这里有一个有趣的例子:我需要生成随机的x/y对,它们在给定的值为时相关。您可以将其想象为两个数组,数组X和数组Y,其中数组X和数组Y的值必须重新生成、重新排序或转换,直到它们在给定的Pearson r级别上相互关联。关键在于:数组X和数组Y必须是均匀分布的 我可以用正态分布来实现这一点,但在不使分布倾斜的情况下变换值让我感到困惑。我尝试对数组中的值重新排序以增加相关性,但我永远不会通过排序将数组关联为1.00或-1.00 有什么想法吗 -- 以下是随机相关高斯的AS3代码,以使车轮转动: pub

这里有一个有趣的例子:我需要生成随机的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;
    }
公共静态函数nextCorrelatedGaussians(r:Number):数组{
变量d1:数字;
变量d2:数字;
变量n1:数量;
变量n2:数值;
var lambda:数值;
var r:数字;
var arr:Array=new Array();
var-isNeg:布尔型;

如果(r从模型
y=x+e
开始,其中
e
是误差(一个正态随机变量)。
e
的平均值应为0,方差为k

长话短说,你可以写一个关于Pearson的期望值的公式,用k来求解。注意,你不能随机生成Pearson完全等于特定值的数据,只能用特定值的期望Pearson

我会试着回来编辑这篇文章,当我有机会看到一些论文时,我会把一个封闭的解决方案包括进去

编辑:好的,我有一个波浪形的解决方案,可能是正确的(但需要测试才能确认)。现在,假设所需的
Pearson=p>0
(你可以找出
p<0
的情况)。就像我前面提到的,为
Y=X+E
设置模型(
X
是统一的,
E
是正常的)

  • 获取x的样本
  • 计算var(x)
  • E的方差应为:
    (1/(rsd(x))^2-var(x)
  • 根据x和正态随机变量的样本生成y
  • 对于
    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/(rsd(x))^2-var(x)。看看这是否有效。

    下面是用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));
    }
    

    正如你所看到的,我还有很长的路要走。有什么建议吗?

    从昨天晚上开始,这个看似简单的问题就一直困扰着我!我在寻找用依赖关系模拟分布的主题,我发现最好的是:。其要点是,你可以很容易地模拟两个具有给定相关性的正态分布,它们勾勒出轮廓转换这些非独立法线的方法,但这不会保持相关性。可以说,转换的相关性将是相关的,但不完全相同。请参阅“秩相关系数”一段


    编辑:根据我从文章第二部分收集的信息,copula方法允许您模拟/生成具有秩相关性的随机变量。

    要获得1的相关性,X和Y应该是相同的,所以将X复制到Y,则相关性为1。要获得-1相关性,请使Y=1-X(假设X值为[0,1])一个奇怪的问题需要一个奇怪的解决方案——我就是这样解决的

    -生成数组X

    -克隆阵列X以创建阵列Y

    -对数组X进行排序(您可以使用任何想要对数组X进行排序的方法——快速排序、堆排序或任何稳定的方法)

    -使用数组X排序和数组Y未排序测量皮尔逊R的起始水平

    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是真正的关键,它具有缓慢而稳定地增加相关性的效果。请查看我的意思。要获得负相关性,可以在整个过程完成后反转排序或反转其中一个数组

    以下是我在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;
        }
    
    公共静态函数nextReliableCorrelatedUniforms(r:Number,size:int,error:Number):数组{
    var yValues:数组=新数组;
    var xValues:Array=新数组;
    var coVar:数值=0;
    对于(vare:int=0;e错误){
    if(trueR=r+错误){
    变量a:int=Random.randomUniformIntegerBetwe
    
    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;
        }