我正在尝试计算由下式给出的正态对数似然:
L = l1+l2+l3+...+ln,
哪里
lk = log(1/(sqrt(2*PI)*sigma_k))-0.5*e_k*e_k
Sigma 约为 0.2
,e_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/