java - 计算正态对数似然的数值稳定方法

标签 java numeric

我正在尝试计算由下式给出的正态对数似然:

L = l1+l2+l3+...+ln,

哪里

lk = log(1/(sqrt(2*PI)*sigma_k))-0.5*e_k*e_k

Sigma 约为 0.2e_k 呈均值 0 和单位方差的正态分布,因此大多数在 -2 到 2 之间;

我尝试了以下java代码(上面提到的sigma_k = sigmas.get(k)*Math.sqrt(dt)):

private double new1(List<Double> residuals, List<Double> sigmas, double dt) {
    double a = 0;
    for(int i=0; i<sigmas.size(); i++) {
        a += Math.log(1.0/(Math.sqrt(2*Math.PI*dt)*sigmas.get(i)));
    }
    double b = 0;
    for(int i=0; i<residuals.size(); i++) {
        b += residuals.get(i)*residuals.get(i);
    }
    return a-0.5*b;
}

但是理论最大值低于我通过数值优化得到的最大值,所以我怀疑我的方法不是最优的。

最佳答案

备注: 在某些领域,概率/统计量的计算不采用对数,例如组合的语言频率。

以下内容进行了简化,变得不太稳定,但随后将其转换回日志之和左右。

<小时/>
double a = 0;
for(int i=0; i<sigmas.size(); i++) {
    a += Math.log(1.0/(Math.sqrt(2*Math.PI*dt)*sigmas.get(i)));
}
<小时/>

log(x) + log(y) = log(x*y)

double a = 1.0;
for(int i=0; i<sigmas.size(); i++) {
    a *= 1.0/(Math.sqrt(2*Math.PI*dt)*sigmas.get(i));
}
a = Math.log(a);
<小时/>

(1/x)*(1/y) = 1/(x*y)

double a = 1.0;
for(int i=0; i<sigmas.size(); i++) {
    a *= Math.sqrt(2*Math.PI*dt)*sigmas.get(i);
}
a = Math.log(1.0/a);
<小时/>

sqrt(x)^n = (x^0.5)^n = x^(n/2)

static import Math.*;

double a = pow(2*PI*dt, sigmas.size() / 2.0);
for(int i=0; i<sigmas.size(); i++) {
    a *= sigmas.get(i);
}
a = -log(a);

关于java - 计算正态对数似然的数值稳定方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8759581/

相关文章:

r - 在 R 中,为什么 is.numeric(NaN) 打印 "TRUE"?

c++ - numeric_limits 的问题

string - 在 MATLAB 中检查字符串是否包含任何数字

java - 如何调用另一个类中的类的方法?

Java GC - 有没有办法确定收集了哪些对象

java - 响应创建elasticsearch来自文件的响应期间出错

bash - 如何让 bc 以科学(又名指数)表示法处理数字?

c++ - C++中常量整数赋值如何

java - 等待API服务器的响应

java - 如何正确施法?