R 手动理解MLE logit估计与optim
我想了解为什么我必须对梯度函数做一点小小的改变,以获得与手动logit MLE计算相同的结果。他们得出了相同的结果,但我不清楚为什么必须做出下面指定的更改 考虑以下代码: 手工: 编辑:R 手动理解MLE logit估计与optim,r,statistics,R,Statistics,我想了解为什么我必须对梯度函数做一点小小的改变,以获得与手动logit MLE计算相同的结果。他们得出了相同的结果,但我不清楚为什么必须做出下面指定的更改 考虑以下代码: 手工: 编辑: 是因为算法的不同,梯度下降还是BFGS;下坡与爬山?你可以通过以下两种方法得到系数 最大化对数可能性,或 最小化负对数似然 通过“手动”方法,您可以最大化对数可能性;即使你在存储负对数似然,你输入梯度下降法的梯度是对数似然的梯度,你在添加你的步骤,所以它是最大化 使用optim()方法,可以最小化负对数可能性o
是因为算法的不同,梯度下降还是BFGS;下坡与爬山?你可以通过以下两种方法得到系数
optim()
方法,可以最小化负对数可能性optim()
默认情况下最小化,您给它的目标函数是负对数似然,您给它的梯度是负对数似然的梯度
如果您想像手动方法一样输入对数似然的梯度,您还需要(1)将对数似然作为目标函数;(2)将fnscale=-1
添加到控制列表中
以下是我运行原始代码时的结果:
##模拟OP中的数据
##以下是在OP中写入的binreg()的结果:
mlebin.fitt这是对optim
函数的描述:“默认情况下optim
执行最小化,但如果control$fnscale
为负值,则它将最大化”。这有帮助吗?我通过fnscale=-1将它从最小化改为最大化。考虑到这一点,它将无法正常工作(coefs已经远离)。@JohnStud“coefs已经远离”是什么意思?在这里的例子中,系数都应该是0;y
和x
之间没有关系。当我复制您的binreg()
函数时,将fnscale=-1
添加到控件
列表中,并删除negLL()
和gradient()
中的负号,我得到的结果与glm()
和手动方法基本相同
negLL<- function(b,X,y){ # b = betas
p <- as.vector(1/(1+exp(-X %*% b))) # "standard logistic function"; 1/1+exp(-X)
-sum(y*log(p) + (1-y)*log(1-p)) # cost function; y-hat = (p)
}
gradient<- function(b,X,y){
p <- as.vector(1/(1+exp(-X %*% b)))
apply(((y - p)*X),2,sum) # derivative of cost function: (p) = y-hat
}
y <- sample(c(0, 1), size =500, replace=TRUE)
x1 <- rnorm(500)
x2 <- rnorm(500)
x <- data.frame(x1, x2)
x <- data.matrix(x)
x <- cbind(1, x)
# the start
tol = 10^-6
beta = c(0,0,0) # multivariate now
maxit = 1000
iter = 0
alpha = 0.0001
eps = Inf
start = Sys.time()
while(eps > tol & iter < maxit){
# save the previous value
beta0 = beta
# calculate h, the increment
h = alpha*gradient(beta, x, y)
# update beta
beta = beta + h
# update the log likelihood
logL = negLL(beta, x, y)
# calculate the euclidean distance
eps = sqrt(sum((beta - beta0)^2))
# update the iteration number
iter = iter + 1
if(iter == maxit) warning("Iteration limit reached without convergence")
# print out info to keep track
if(floor(iter/20) == ceiling(iter/20)) cat(sprintf("Iter: %d logL: %.2f beta0: %.3f beta1: %.3f beta2: %.3f eps:%f\n",iter, logL,beta[1],beta[2],beta[3],eps))
}
binreg<- function(X,y,method="BFGS"){
#X<- cbind(1,X)
negLL<- function(b,X,y){ # b = betas
p<-as.vector(1/(1+exp(-X %*% b))) # "standard logistic function"; 1/1+exp(-X)
- sum(y*log(p) + (1-y)*log(1-p)) # cost function; y-hat = (p)
}
gradient<- function(b,X,y){
p <- as.vector(1/(1+exp(-X %*% b)))
-apply(((y - p)*X),2,sum) # derivative of cost function: (p) = y-hat
}
results<- optim (rep(0,ncol(X)),negLL,gr=gradient,
hessian=T,method=method,X=X,y=y, control=list(trace=1, REPORT=1))
list(coefficients=results$par,var=solve(results$hessian),
deviance=2*results$value,
converged=results$convergence==0)
}
mlebin.fit<-binreg(x,y)
#results
round(mlebin.fit$coefficients,2)
apply(((y - p)*X),2,sum) # derivative of cost function: (p) = y-hat # by hand
# changes to
-apply(((y - p)*X),2,sum) # so optim works right