"прогнозировать" ошибку при выполнении N-кратной перекрестной проверки для моего GLM

Я запускаю эту функцию для выполнения перекрестной проверки n-fold. Скорость неправильной классификации не меняется в течение складок, например, если я выполняю 10 или 50. Я также получаю предупреждение:

«Предупреждающее сообщение:

у ‘newdata’ было 19 строк, но у найденных переменных 189 строк»

Если я выполняю код, не будучи частью функции, он делает want I want -> например, для folds==1, он вытаскивает 10%, запускает модель на 90% данных и предсказывает другие 10%.
Есть ли у кого-нибудь идеи о том, почему он не показывает вариацию по переменной и количеству складок?

library("MASS")  
data(birthwt)
data=birthwt

n.folds=10

jim = function(x,y,n.folds,data){

  for(i in 1:n.folds){
    folds <- cut(seq(1,nrow(data)),breaks=n.folds,labels=FALSE)      
    testIndexes <- which(folds==i,arr.ind=TRUE)
    testData <- data[testIndexes, ]
    trainData <- data[-testIndexes, ]
    glm.train <- glm(y ~ x, family = binomial, data=trainData)
    predictions=predict(glm.train, newdata =testData, type='response')
    pred.class=ifelse(predictions< 0, 0, 1)
    }

  rate=sum(pred.class!= y) / length(y)
  print(head(rate))
  }

jim(birthwt$smoke, birthwt$low, 10, birthwt)

1 ответ

  1. Теперь я превращаю свои комментарии в ответ.

    jim <- function(x, y, n.folds, data) {   
    
      pred.class <- numeric(0)  ## initially empty; accumulated later
      for(i in 1:n.folds){
        folds <- cut(seq(1,nrow(data)), breaks = n.folds, labels = FALSE)  
        testIndexes <- which(folds == i)  ## no need for `arr.ind = TRUE`
        testData <- data[testIndexes, ]
        trainData <- data[-testIndexes, ]
        ## `reformulate` constructs formula from strings. Read `?reformulate`
        glm.train <- glm(reformulate(x, y), family = binomial, data = trainData)
        predictions <- predict(glm.train, newdata = testData, type = 'response')
        ## accumulate the result using `c()`
        ## change `predictions < 0` to `predictions < 0.5` as `type = response`
        pred.class <- c(pred.class, ifelse(predictions < 0.5, 0, 1))
        }
    
      ## to access a column with string, use `[[]]` not `$`
      rate <- sum(pred.class!= data[[y]]) / length(data[[y]])
      rate  ## or `return(rate)`
      }
    
    jim("smoke", "low", 10, birthwt)
    # [1] 0.3121693
    

    Замечание:

    1. Не нужно ставить arr.ind = TRUEсюда, хотя и не имеет побочного эффекта.
    2. Что-то не так с вашей классификацией. Вы устанавливаетеtype = "response", то вы используете ifelse(predictions < 0, 0, 1). Подумайте об этом, вы всегда получаете 1 за pred.class.
    3. Каждая итерация forцикла перезаписывает pred.class. Я думаю, что вы хотите накопить результат. Так делают pred.class <- c(pred.class, ifelse(predictions < 0.5, 0, 1));
    4. Неправильное использование glmИ.predict Неправильно вводить $формулу модели. Пожалуйста, прочитайте Predict () — может быть, я не понимаю . Здесь я изменил вашу функцию, чтобы принимать имена переменных (как строку) и использовать правильную формулу модели внутри glm. Обратите внимание, что это изменение требуется разместить yс data[[y]]in rate = sum(pred.class!= y) / length(y).
    5. Вы, вероятно, хотите вернутьсяrate, а не просто печатать его на экране. Поэтому замените printстроку на явную return(rate)или неявную rate.
    6. Вы можете заменить ifelse(predictions < 0.5, 0, 1)наas.integer(predictions < 0.5), хотя я не менял его выше.