Самодельный заказанный пробит в R - PullRequest
0 голосов
/ 27 мая 2019

Я пытаюсь сделать упорядоченную функцию пробита с нуля.

У меня есть кое-что, что приближает меня к результатам функции clm, но не совсем.

probit <- function(df, yvar) {
  # include only complete cases
  df <- df[complete.cases(df),]

  # Make the data matrix
  X <- df %>% select(-yvar)

  # get variable names
  names <- names(X)

  # take out the y column and convert X to a matrix
  y <- df[yvar]
  X <- X %>% as.matrix()

  # number of categories to be estimated
  names(y) <- c("y")
  M <- filter(y, !is.na(y)) %>% unique() %>% nrow()

  # (neg) log likelihood function
  negLL <- function(par, X, y) {
    b <- par[1:ncol(X)]
    t <- par[(ncol(X) + 1):(ncol(X) + M - 1)]

    # Make y numeric
    y <- as.numeric(y$y)

    # Set the upper and lower categories to negative and positive infinity
    t <- c(-Inf, t, Inf)

    # Apply the normal CDF transformation to each observation's covariates,
    # cycling through each threshold level with the indicator function.
    mu <- matrix(NA, nrow = nrow(X), ncol = M)
    for(i in 1:nrow(X)){
      for(j in 2:(M+1)) { #R won't index starting at 0, so have to + 1
        mu[i, j - 1] <-  ifelse(y[i] == j - 1,
            1 *  (log(pnorm(t[j - 1] - X[i,] %*% b) -
                        pnorm(t[j - 2] - X[i,] %*% b))),
            0)
        }}

    # Now compute the log likelihood by summing above
    LL <- sum(mu, na.rm = T)

    # Negative log likelihood
    return(-LL)
  }

  # optimize
  results <- optim(par = c(rep(0, ncol(X)), c(1:(M-1))), fn = negLL, 
                   y = y, X = X, hessian = T)
  parameters <- results$par[1:ncol(X)] %>% as.numeric()
  names(parameters) <- names
  thresholds <- results$par[(ncol(X)+1):(length(results$par))] %>% 
    as.numeric()
  list(coefs = parameters, thresholds = thresholds,
       varcovar = solve(results$hessian),
       se = sqrt(diag(solve(results$hessian))),
       deviance = 2*results$value,
       converged = results$convergence == 0,
       loglik = -results$value,
       iterations = results$counts[[1]]) %>% 
    return()
}

Я проверял это на этом документе: https://onlinelibrary.wiley.com/doi/full/10.1111/ajps.12290

С этими данными репликации: https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/Q8CSU8

Например, для "соблазня"результат (объясняющая переменная = "интервьюl"), я должен получить коэффициент 0,47, но я получаю 0,38.Может кто-нибудь найти проблему в моем коде?Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...