java - Apache 独立 Gamma 分布

标签 java apache math distribution random

您好,我注意到 Apache Maths 库(版本 2.2)中有一些奇怪的行为,特别是在 org.apache.commons.math.distribution.GammaDistributionImpl 类中,尽管我认为这可能适用于其他发行版也是如此。

我想从不同的 Gamma 分布中提取样本,如下所示:

public static final double[] gammaSamples(final double[] shapeParameters)
{
    double[] samples = new double[shapeParameters.length];
    for (int i = 0; i < shapeParameters.length; i++)
    {
        GammaDistributionImpl gd = new GammaDistributionImpl(shapeParameters[i], 1.0d);
        try
        {
            samples[i] = gd.sample();
        }
        catch (MathException e)
        {
            e.printStackTrace();
        }
    }
    return samples;
}

然而,当运行代码时,我发现样本都非常相似,即给定

public static void main(String[] args)
{
    System.out.println(Arrays.toString(gammaSamples(new double[] { 2.0d, 2.0d, 2.0d})));
}

一些示例输出是:

[0.8732612631078758, 0.860967116242789, 0.8676088095186796]
[0.6099133517568643, 0.5960661621756747, 0.5960661621756747]
[2.1266766239021364, 2.209383544840242, 2.209383544840242]
[0.4292184700011395, 0.42083613304362544, 0.42083613304362544]

我认为问题是由于默认的随机数生成器对每个分布使用相同/相似的种子,我测试如下:

public static final double[] gammaSamples(final double[] shapeParameters, final Random random)
{
    double[] samples = new double[shapeParameters.length];
    for (int i = 0; i < shapeParameters.length; i++)
    {
        GammaDistributionImpl gd = new GammaDistributionImpl(shapeParameters[i], 1.0d);
        gd.reseedRandomGenerator(random.nextLong());
        try
        {
            samples[i] = gd.sample();
        }
        catch (MathException e)
        {
            e.printStackTrace();
        }
    }
    return samples;
}

这似乎解决了问题,即给定

public static void main(String[] args)
{
    System.out.println(Arrays.toString(gammaSamples(new double[] { 2.0d, 2.0d, 2.0d }, new Random())));
}

一些示例输出是:

[2.7506981228470084, 0.49600951917542335, 6.841476090550152]
[1.7571444623500108, 1.941865982739116, 0.2611420777612158]
[6.043421570871683, 0.8852269293415297, 0.6921033738466775]
[1.3859078943455487, 0.8515111736461752, 3.690127105402944]

我的问题是:

这是怎么回事?这是一个错误还是 Apache Maths 发行版旨在以这种方式运行?

我觉得奇怪的是,如果我创建单独的分发对象,我必须担心它们被赋予什么种子并确保它们足够不同。

另一个小烦恼是,我似乎无法将这些分布传递给我自己的 Random 对象,而是它们只允许通过 reseedRandomGenerator(long seed) 方法更改种子。能够将我自己的 Random 对象传递给它们在尝试重现结果时会非常有用。

感谢您的帮助。

最佳答案

通过查看 javadoc :

我看到有方法 public double[] sample(int sampleSize) throws MathException

Generates a random sample from the distribution. The default implementation generates the sample by calling sample() in a loop.

你试过吗?

double[] samples = sample(shapeParameters.length);

编辑:抱歉,我看到您每次使用新的alpha 参数计算新的GammaDistributionImpl。我猜这是因为种子值是从具有有限分辨率的系统时钟派生的,并且对构造函数的关闭调用将产生相同的结果。看看这个SO question .

这里有一些输入可以让您进行更深入的调查:

关于java - Apache 独立 Gamma 分布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14537824/

相关文章:

java - 如何向 FCM(Firebase 云消息传递) token 的特定用户发送消息?

apache 服务器 - 如何将 http 重定向到 https

python django wsgi 多线程 - 如何在 django 中使用多线程

java - 我是否正确地将这段伪代码翻译成Java?

javascript - 如何在保持最小值的同时缩放一组值?

c# - 如何计算特定方向垂直于多边形表面的3D矢量

java - 在Android设备上实现RTP流媒体播放器

java - 为什么我能够在 Java 中将更大的数组传递给更小的数组?

java - 将 Java 日期转换为 UTC 字符串

linux - 有人可以向初学者提供有关 Hadoop 工作原理的高级、简单的解释吗?