我希望通过直接最小化负对数似然(不使用glm)来获得适合某些比例数据的累积正态曲线的最大似然参数(MLE)。对于引入optim()的一些初始值,没有问题:
x <- c(-0.250, -0.056, 0.137, 0.331, 0.525, 0.719, 0.912, 1.100, 1.300)
k <- c(0, 0, 5, 11, 12, 12, 12, 12, 12)
n <- c(12, 12, 12, 12, 12, 12, 12, 12, 12)
nll <- function(p) {
phi <- pnorm(x, p[1], p[2])
-sum(k * log(phi) + (n - k) * log(1 - phi))
}
para<- optim(c(0.5, 0.1), nll)$par
xseq <- seq(-.5, 1.5, len = 100)
yseq <- pnorm(xseq, para[1],para[2])
curve <- data.frame(xseq, yseq)
dat <- data.frame(x, k, n)
library(ggplot2)
ggplot(dat,aes(x = x, y = k / n)) +
geom_point()+
geom_line(data = curve, aes(x = xseq, y = yseq))
但是,如果我使用实际上更接近MLE参数的初始值
para<- optim(c(0.1, 0.1), nll)$par
我收到了以下错误:
Error in optim(c(0.1, 0.1), nll) : function cannot be evaluated at initial parameters
似乎错误是由负对数可能性的评估中的一些无穷大引起的。我发现如果我使用pnorm的log.p
选项增加精度,我就不会忽略错误
nll <- function(p) {
logphi1 <- pnorm(x, p[1], p[2], lower.tail = T, log.p = T)
logphi2 <- pnorm(x, p[1], p[2], lower.tail = F, log.p = T)
-sum(k * logphi1 + (n - k) * logphi2)
}
para<- optim(c(0.1, 0.1), nll)$par
但问题是,除了pnorm
之外,我还希望将a + b * pnorm
的曲线与a
和b
常量拟合,在这些情况下我无法使用{ {1}}以提高精确度。
答案 0 :(得分:1)
似乎用机器epsilon替换非常小的数字并且数字非常接近1乘1 - (机器epsilon),错误不会发生并且拟合似乎合理。
x <- c(-0.250, -0.056, 0.137, 0.331, 0.525, 0.719, 0.912, 1.100, 1.300)
k <- c(0, 0, 5, 11, 12, 12, 12, 12, 12)
n <- c(12, 12, 12, 12, 12, 12, 12, 12, 12)
nll <- function(p) {
phi <- pnorm(x, p[1], p[2])
phi[phi < .Machine$double.eps] <- .Machine$double.eps
phi[phi > (1 - .Machine$double.eps)] <- 1 - .Machine$double.eps
-sum(k * log(phi) + (n - k) * log(1 - phi))
}
para<- optim(c(0.1, 0.1), nll)$par
xseq <- seq(-.5, 1.5, len = 100)
yseq <- pnorm(xseq, para[1],para[2])
curve <- data.frame(xseq, yseq)
dat <- data.frame(x, k, n)
library(ggplot2)
ggplot(dat,aes(x = x, y = k / n)) +
geom_point()+
geom_line(data = curve, aes(x = xseq, y = yseq))
答案 1 :(得分:0)
问题出在第8个数据点&amp;参数值;他们在评估可能性时会导致NaN,因为pnorm
评估为1(数字):
p <- c(0.1,0.1)
pnorm(x[8], p[1], p[2])
## 1
1-pnorm(x[8], p[1], p[2])
## 0
pnorm(x[8], p[1], p[2], lower.tail=FALSE)
## 7.6e-24
后一个值位于machine-epsilon之下,所以即使你写出1 - pnorm(x[8], p[1], p[2], lower.tail=FALSE)
的可能性,也不会避免下溢。