R 手动理解MLE logit估计与optim

R 手动理解MLE logit估计与optim,r,statistics,R,Statistics,我想了解为什么我必须对梯度函数做一点小小的改变,以获得与手动logit MLE计算相同的结果。他们得出了相同的结果,但我不清楚为什么必须做出下面指定的更改 考虑以下代码: 手工: 编辑: 是因为算法的不同,梯度下降还是BFGS;下坡与爬山?你可以通过以下两种方法得到系数 最大化对数可能性,或 最小化负对数似然 通过“手动”方法,您可以最大化对数可能性;即使你在存储负对数似然,你输入梯度下降法的梯度是对数似然的梯度,你在添加你的步骤,所以它是最大化 使用optim()方法,可以最小化负对数可能性o

我想了解为什么我必须对梯度函数做一点小小的改变,以获得与手动logit MLE计算相同的结果。他们得出了相同的结果,但我不清楚为什么必须做出下面指定的更改

考虑以下代码:

手工: 编辑:
是因为算法的不同,梯度下降还是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