1

我需要在 excel 中生成泊松分布并找到一种方法(逆变换方法

在 excel 中完成,然后在 sas 中完成(只是为了好玩,所以我不需要快速回答)与ranpoisas 函数进行比较。这是我的代码(有效):

data Poisson(keep=mean Poisson PoissonSas);
mean=0.2;
confronta=exp(-mean);
do obs=1 to 100;
    found=0;
    Poisson=0;
    ranuni=1;
    do until(found=1);
        ranuni=ranuni*ranuni(12547);
        if ranuni<confronta then found=1;
        else Poisson=Poisson+1;
    end;
    PoissonSas=ranpoi(012584,mean);
    output;
end;
run;

proc means data=Poisson(drop=mean);run;

所以我在两个随机函数中初始化了种子来复制结果。奇怪的是,根据我是使用两种方法还是仅使用其中一种方法(评论另一种方法)提交数据步骤,我会得到不同的结果,但每种类型的提交都会一遍又一遍地得到相同的结果。我总是期待同样的结果!为什么不是这样?(我使用的是 sas 9.3)谢谢! 在此处输入图像描述

4

2 回答 2

1

看起来 SAS 将对 PRNG 的调用作为单个流交错。伪随机数是一系列实际上是确定性的值。如果您在一种算法中播种并使用该序列,则每次该算法都会得到相同的结果。如果您在两个或多个算法之间交替使用序列,则该组算法将始终产生相同的一组结果(对您来说似乎就是这种情况),但是给定算法的结果会有所不同,因为某些基础它之前绘制的 PRN 现在被其他算法使用。当使用基于公共随机数的所谓方差减少技术时,这是同步要求的核心. 一般来说,如果您想要相同的结果,解决方案是拥有多个 PRNG 实例,一个用于程序中随机性的每个“源”,并为多个源彼此独立但在运行中相同地播种。看起来您试图这样做,但 SAS 的行为与您想象的不同。根据他们的文档,他们似乎根据您代码中的第一个种子条目生成了一个 PRN 流!这是其中一个示例的子集:

/* This DATA step calls the RANUNI and the RANNOR functions */
/* and produces a single stream of random numbers based on  */
/* a seed value of 7.                                       */   
data d;
   d = ranuni (7); f = ' '; output;
   d = ranuni (8); f = ' '; output;
   d = rannor (9); f = 'n'; output;
   /* they actually have more... */
run;

顺便说一句,您的泊松算法通常不被视为逆变换算法。反转是一对一的,即单个输入统一产生单个随机变量。您正在执行的循环实际上是在进行接受/拒绝,并且您使用可变数量的制服来得出每个泊松值。

于 2014-09-04T14:47:14.043 回答
0

PJS 的回答基本上是正确的,但有一些澄清。

当您按照您的方式进行操作时,SAS 确实使用了一个种子;所有我称之为“原始”随机函数的东西都来自一个 PRNG 流,只有第一个种子很重要(并且只有第一次遇到它时才重要)。

然而,RANPOI 有点不同——可能是因为 SAS 是如何创建泊松的。文档中没有明确说明,但它似乎使用了两个随机数(不确定它是否总是两个,或者只是巧合)。请参阅以下测试:

data test;
U=ranuni(7);
P=ranpoi(8,100);
put u= p=;
run;


data test2;
p=ranpoi(8,100);
u=ranuni(7);
put u= p=;
run;

data test3;
u=ranuni(8);
p=ranuni(7);
put u= p=;=
run;

data test4;
u=ranuni(7);
p=ranuni(8);
put u= p=;
run;

data test5;
do _t = 1 to 5;
 u=ranuni(8);
 put u=;
end;
run;

现在,在 test4 中,我们看到从种子 7 开始时的前两个 ranuni,并且确实第一个与 test 中的第一个匹配。但是,test3 的前两个从种子 8 开始,第二个与 test2中的不匹配!test5 显示实际上第三个匹配项,这意味着 test2 中的 ranpoi 用完了流中的 2 个数字。

无论如何,如果您想在中途更改种子,您有两个选择。

一种是使用CALL RANPOI(and CALL RANUNI),它允许您将种子存储在变量中。二是使用RAND功能,它可以CALL STREAMINIT随时设置种子。该RAND函数被认为比更原始的函数“更好” RANPOI- 它使用更好的 PRNG 算法。

于 2014-09-04T14:57:29.430 回答