我正在尝试计算曲线下面积的正态分布。通常,我可以参考计算器或z表。但是,我该如何编码呢?我有z,mu,sigma和边界的值。我在网上看到了多个代码,但没有一个代码解释它背后的逻辑。我想学习它是如何工作的,而不是使用外部方法,然后为它编写代码。
如果有人可以使用z,mu,sigma和边界来计算曲线下的面积,而没有任何复杂的细节,那将是一个很好的帮助。
由于
答案 0 :(得分:3)
您可以像使用其他任何语言一样进行操作!
正态分布定义为具有如下概率:
您需要做的是整合它。首先,将概率分布转化为方法。我们可以通过使用mu = 0和sigma = 1来简化它。
/**
* Returns the height of the normal distribution at the specified z-score
*/
double getNormalProbabilityAtZ(double z) {
return Math.exp(-Math.pow(z, 2) / 2) / Math.sqrt(2 * Math.PI);
}
接下来,我们需要一种方法来进行整合。我们的想法是将它分成一堆微小部分,在每个部分得到y值,然后乘以矩形的宽度。 Here's more reading on Riemann Sums,以防您不熟悉。
/**
* Returns the area under the normal curve between the z-scores z1 and z2
*/
double getAreaUnderNormalCurve(double z1, double z2) {
double area = 0.0;
final int rectangles = 100000; // more rectangles = more precise, less rectangles = quicker execution
final double width = (z2 - z1) / rectangles;
for(int i = 0; i < rectangles; i++)
area += width * getNormalProbabilityAtZ(width * i + z1);
return area;
}
你有它!
如果您需要找到正态分布下的区域,让我们说z分数为1到无穷大,只需像getAreaUnderNormalCurve(1, 5)
那样执行1到5之类的操作。为什么?因为在z=3
之后,钟形曲线下面积非常小。在z=5
之后,它甚至可以忽略不计甚至不值得整合。
免责声明:如果您需要最快的速度和精确度,您不应该自己实施。使用已存在的库,例如Apache Commons Error Function。您可以通过以下关系normalCdf(x) = 1/2 + 1/2 * erf(x / sqrt(2))
快乐编码OP,如果仍然没有意义,请发表评论,我很乐意编辑我的答案。