我想在MATLAB中计算log(N(x | mu, sigma))
x是数据矢量(尺寸D×1),μ(尺寸D×1)是平均值,西格玛(尺寸D×D)是协方差。
我目前的实施是
function [loggaussian] = logmvnpdf(x,mu,Sigma)
[D,~] = size(x);
const = -0.5 * D * log(2*pi);
term1 = -0.5 * ((x - mu)' * (inv(Sigma) * (x - mu)));
term2 = - 0.5 * logdet(Sigma);
loggaussian = const + term1 + term2;
end
function y = logdet(A)
y = log(det(A));
end
在某些情况下,我收到错误
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
NaN
我知道你会指出我的数据不一致,但我需要实现这个功能,这样我才能得到最好的近似值而不是发出警告。 。我如何确保始终获得价值。
我认为警告来自使用inv(Sigma)
。根据documentation,你应该避免使用inv
,它的用途可以被\
(mldivide
)取代。这将为您提供更好的速度和准确性。
对于您的代码,而不是inv(Sigma) * (x - mu)
使用Sigma \ (x - mu)
。
以下方法应该(稍微)对协方差矩阵的病态调节不太敏感:
function logpdf = logmvnpdf (x, mu, K)
n = length (x);
R = chol (K);
const = 0.5 * n * log (2 * pi);
term1 = 0.5 * sum (((R') \ (x - mu)) .^ 2);
term2 = sum (log (diag (R)));
logpdf = - (const + term1 + term2);
end
如果K
是单数或近似单数,则在调用chol
时仍然可能有警告(或错误)。