在为我的GLM进行n次交叉验证时,“预测”错误

时间:2016-11-04 14:38:57

标签: r regression glm cross-validation predict

我正在运行此功能来进行n次交叉验证。错误分类率不会因折叠而变化,例如如果我跑10或50,我也会收到警告:

  

“警告信息:

     

'newdata'有19行,但找到的变量有189行“

如果我在不成为函数一部分的情况下运行代码,那就是我想要的 - >例如对于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 个答案:

答案 0 :(得分:0)

我现在正在回答我的意见。

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)。想一想,pred.class总是得到1。
  3. for循环的每次迭代都会覆盖pred.class。我想你想累积结果。 pred.class <- c(pred.class, ifelse(predictions < 0.5, 0, 1));
  4. 也是如此
  5. 错误地使用glmpredict。将$放在模型公式中是错误的。请阅读Predict() - Maybe I'm not understanding it。在这里,我已将您的函数更改为接受变量名称(作为字符串),并在glm中使用正确的模型公式。请注意,此更改需要将ydata[[y]]放在rate = sum(pred.class!= y) / length(y)
  6. 您可能希望返回rate而不是仅将其打印到屏幕上。因此,请使用显式print或隐式return(rate)替换您的rate行。
  7. 您可以将ifelse(predictions < 0.5, 0, 1)替换为as.integer(predictions < 0.5),但我没有在上面更改它。