在R中编写自己的MLE命令会引起问题

在R中编写自己的MLE命令会引起问题,r,optimization,max,stata,R,Optimization,Max,Stata,我刚刚开始尝试在R函数中编写MLE命令,并且看起来与本机R函数类似。在这次尝试中,我尝试使用 y=b0+x*b1+u 及 u~N(0,sd=s0+z*s1) 然而,即使是这样一个简单的命令,我也难以编码。我已在中编写了类似的命令 这是我到目前为止用R编写的代码 normalreg <- function (beta, sigma=NULL, data, beta0=NULL, sigma0=NULL, con1 = T, con2 =

我刚刚开始尝试在R函数中编写MLE命令,并且看起来与本机R函数类似。在这次尝试中,我尝试使用

y=b0+x*b1+u

u~N(0,sd=s0+z*s1)

然而,即使是这样一个简单的命令,我也难以编码。我已在中编写了类似的命令

这是我到目前为止用R编写的代码

  normalreg <- function (beta, sigma=NULL, data, beta0=NULL, sigma0=NULL,
                         con1 = T, con2 = T) {

    # If a formula for sigma is not specified 
    #  assume it is the same as the formula for the beta.
    if (is.null(sigma)) sigma=beta

    # Grab the call expression
    mf <- match.call(expand.dots = FALSE)

    # Find the position of each argument
    m <- match(c("beta", "sigma", "data", "subset", "weights", "na.action", 
                 "offset"), names(mf), 0L)

    # Adjust names of mf
    mf <- mf[c(1L, m)]

    # Since I have two formulas I will call them both formula
    names(mf)[2:3] <- "formula"

    # Drop unused levels
    mf$drop.unused.levels <- TRUE

    # Divide mf into data1 and data2
    data1  <- data2 <- mf
     data1 <- mf[-3]
     data2 <- mf[-2]

    # Name the first elements model.frame which will be 
    data1[[1L]] <- data2[[1L]] <- as.name("model.frame")

    data1 <- as.matrix(eval(data1, parent.frame()))
    data2 <- as.matrix(eval(data2, parent.frame()))

    y     <- data1[,1]
    data1 <- data1[,-1]
     if (con1)  data1 <- cbind(data1,1)
    data2 <- unlist(data2[,-1])
      if (con2) data2 <- cbind(data2,1)

    data1 <- as.matrix(data1) # Ensure our data is read as matrix
    data2 <- as.matrix(data2) # Ensure our data is read as matrix

    if (!is.null(beta0)) if (length(beta0)!=ncol(data1))
      stop("Length of beta0 need equal the number of ind. data2iables in the first equation")

    if (!is.null(sigma0)) if (length(sigma0)!=ncol(data2)) 
      stop("Length of beta0 need equal the number of ind. data2iables in the second equation")

    # Set initial parameter estimates
    if (is.null(beta0))  beta0   <- rep(1, ncol(data1))
    if (is.null(sigma0)) sigma0 <- rep(1, ncol(data2))

    # Define the maximization function
    normMLE <- function(est=c(beta0,sigma0), data1=data1, data2=data2, y=y) {          
      data1est <- as.matrix(est[1:ncol(data1)], nrow=ncol(data1))
      data2est <- as.matrix(est[(ncol(data1)+1):(ncol(data1)+ncol(data2))],
                              nrow=ncol(data1))

      ps <-pnorm(y-data1%*%data1est, 
                       sd=data2%*%data2est)
      # Estimate a vector of log likelihoods based on coefficient estimates
      llk <- log(ps)
      -sum(llk) 
    }

    results <- optim(c(beta0,sigma0), normMLE, hessian=T,
                     data1=data1, data2=data2, y=y)

    results
  }


  x <-rnorm(10000)
  z<-x^2
  y <-x*2 + rnorm(10000, sd=2+z*2) + 10

  normalreg(y~x, y~z)

normalregI包括一项检查,查看是否有任何标准偏差小于或等于0,如果是这样,则返回0的可能性。似乎对我有用。您可以了解将其包装到函数中的细节

#y=b0 + x*b1 + u
#u~N(0,sd=s0 + z*s1)

ll <- function(par, x, z, y){
    b0 <- par[1]
    b1 <- par[2]
    s0 <- par[3]
    s1 <- par[4]
    sds <- s0 + z*s1
    if(any(sds <= 0)){
        return(log(0))
    }

    preds <- b0 + x*b1

    sum(dnorm(y, preds, sds, log = TRUE))
}

n <- 100
b0 <- 10
b1 <- 2
s0 <- 2
s1 <- 2
x <- rnorm(n)
z <- x^2
y <- b0 + b1*x + rnorm(n, sd = s0 + s1*z)

optim(c(1,1,1,1), ll, x=x, z=z,y=y, control = list(fnscale = -1))
#y=b0+x*b1+u
#u~N(0,sd=s0+z*s1)

ll您可以使用
log()
/
exp()
技巧强制sd为正值。很明显,sd不可能是负的,所以这会抛出一个错误,这不是很有意义吗?当您将初始值提供给R时,首先对其进行log变换(例如,您认为sd=5,所以提供
log(5)
)。在MLE函数中,对sd求幂(因此
exp()
log(5)
)。这迫使它积极。当您去解释模型拟合时,再次获取估计值的
log()
。好主意。我试着使用abs(),虽然它似乎纠正了NAs的这个特殊问题,但它并没有收敛到任何接近真实参数的地方,尽管增加了样本。这向我表明我做错了什么。我认为optim()中的BFGS选项允许您设置参数约束。但是,这并不能保证会有所帮助。您可能只需要仔细查看模型和数据,看看模型是否得到了适当的表述。但是我不能肯定。那么为什么你的
Stata
代码不产生负的sd值,或者为什么它在处理这些值时不会爆炸呢?在您的
R
代码中,哪些计算或“安全检查”是不同的?我真的很想知道这个问题的答案,因为这似乎表明,尽管我更喜欢R,但我还是应该使用Stata进行分析。