1

Java の特定の領域と特定のポリゴンの二変量正規分布の確率を計算しようとしています。

数学的説明は、特定の複雑な領域で二変量正規分布の確率密度関数 ( pdf ) を積分することです。

私の最初のアプローチは、ライブラリを利用して 2 つNormalDistributionのオブジェクトを使用することでした。apache-commons-math次元 1 のデータセット x と次元 2 のデータセット y を指定して、それぞれの平均と標準偏差を計算しましたNormalDistribution

のメソッド public double probability(double x0, double x1)org.​apache.​commons.​math3.​distribution.​NormalDistribution使用すると、各次元に個別の間隔を設定できます。つまり、長方形の領域を定義して、次の方法で確率を取得できます。

NormalDistribution normalX = new NormalDistribution(means[0], stdDeviation_x);
NormalDistribution normalY = new NormalDistribution(means[1], stdDeviation_y);

double probabilityOfRect = normalX.probability(x1, x2) * normalY.probability(y1, y2);

標準偏差が十分に小さく、定義された領域が十分に大きい場合、確率は予想される 1.0 (0.99999999999) の数値に近づきます。

特定の領域を計算する必要があると述べたように、長方形の領域しか定義できないため、最初のアプローチはこの方法では機能しません。

したがって、私の 2 番目のアプローチはMultivariateNormalDistribution、 にも実装されている class を使用することでしたapache-commons-math

MultivariateNormalDistributionベクトル平均と共分散行列を使用することpublic double density(double[] vals)で、説明が言っているように、特定の点 x の pdf を取得できます。

指定された点 x で評価されたこの分布の確率密度関数 (PDF) を返します。

http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/distribution/MultivariateNormalDistribution.html#density(double[])

このアプローチでは、複雑な領域をポイントの ArrayList に変換し、その後、次のように ArrayList を反復処理してすべての密度を合計します。

MultivariateNormalDistribution mnd = new MultivariateNormalDistribution(means, covariances);
double sum = 0.0;
    for(Point p : complexArea) {
    double[] pos = {p.x, p.y};
    sum += mnd.density(pos);
}
return sum;

しかし、標準偏差を非常に低い値に設定すると、呼び出している位置に 1 を超えるピークが pdf に含まれるようになると、精度が不足するという問題が発生しましたmnd.density(pos)。したがって、合計は値 > 1 になります。

これらのピークを回避するために、現在のポイントの倍精度で周囲のポイントである合計値の平均を合計しようとしています

MultivariateNormalDistribution mnd = new MultivariateNormalDistribution(means, covariances);
double sum = 0.0;
for(Point p : surfacePoints) {
    double tmpRes = 0.0;

    for(double x = p.x - 0.5; x < p.x + 0.5; x+=0.1) {
        for(double y = p.y - 0.5; y < p.y + 0.5; y+=0.1) {
            double[] pos = {x, y};
            tmpRes += mnd.density(pos);
        }
    }
    sum += tmpRes / 100.0;
}

return sum;

これは明らかに機能します。

全体として、私のアプローチが根本的に正しいかどうかはよくわかりません。別のアプローチは、数値積分で確率を計算することですが、Javaでこれを達成する方法がわかりません。

これを達成する他の可能性はありますか?

編集: 精度が不足しているという事実に加えて、主な問題は次のとおりです。「密度を合計する」2番目のアプローチは、二変量正規分布の領域で確率を取得する有効な方法ですか? public double density(double[] vals)1 次元の正規分布について考えると、ある特定の点の確率は常に 0です。Apache 数学ライブラリのメソッドはどのようにして有効な値を取得するのでしょうか?

4

1 に答える 1