0

Я пытаюсь получить ошибки из ступенчатых функций, но я получаю сообщение об ошибке:Cross Validating ступенчатые функции в R

library(boot) 
library(ISLR) 
attach(Wage) 
set.seed(5082) 
cv.error <- rep (0,12) 
for (i in 2:13){ 
    step.fit = glm(wage~cut(age,i), data = Wage) 
    cv.error[i] <- cv.glm(Wage ,step.fit, K= 10)$delta [1] 
} 

Error in model.frame.default(Terms, newdata, na.action = na.action, xlev = object$xlevels) : 
cut(age, i) has new levels (17.9,43.5], (43.5,69.1] 

я могу получить ошибку из cv.glm()$delta [1] если вместо автоматической генерации индекса cut() я использовать специальные перерывы :

fit <- glm(wage~cut(age,breaks=c(17.9,33.5,49,64.5,80.1)), data = Wage) 
cv.error <- cv.glm(Wage ,step.fit, K= 10)$delta [1]' 

Даже если они точно такие же разрывы cut(age,4) делает.

Может кто-нибудь объяснить, что происходит или как исправить ошибку.

Моя цель - попытаться найти ошибки с 12 различных моделей шагов и выбрать лучший на основе ошибки cv.glm()$delta.

ответ

0

Проблема была в том, что cut(age, i) существовал только как встроенное создание в пределах вашего glm() и не был частью набора данных Wage, который вы использовали для проверки. Мы можем исправить это так:

library(boot) 
library(ISLR) 
data(Wage) # using attach is a bad practice 
set.seed(5082) 
cv.error <- rep (0,12) 
for (i in 2:13){ 
    Wage$tmp <- cut(Wage$age,i) 
    step.fit = glm(wage~tmp, data = Wage) 
    cv.error[i] <- cv.glm(Wage ,step.fit, K= 10)$delta [1] 
} 

cv.error 

[1] 0,000 1733,815 1682,731 1637,200 1631,049 1623,069 1613,099 1600,413 1613,127 1603,581 1603,601 1604,730 1602,462

Обратите внимание, что первое значение 0 только потому, что значения i начинаются с 2, поэтому ничто никогда не было написано в первый элемент.

+1

Спасибо для объяснения этого ясно! –

+0

@OPolakunnil Вы вполне приветствуете –

0

Я посмотрел в том, чтобы получить этикетки от cut продукции и нашел полезную записку в конце документации (??cut)

## one way to extract the breakpoints 
labs <- levels(cut(aaa, 3)) 
cbind(lower = as.numeric(sub("\\((.+),.*", "\\1", labs)), 
     upper = as.numeric(sub("[^,]*,([^]]*)\\]", "\\1", labs))) 

Так положить, что использовать:

library(boot) 
library(ISLR) 
data(Wage) 
set.seed(5082) 
cv.error <- rep (0,12) 
for (i in 2:13){ 
    labs <- levels(cut(age, i)) 
    breaks <- unique(c(as.numeric(sub("\\((.+),.*", "\\1", labs)), 
        as.numeric(sub("[^,]*,([^]]*)\\]", "\\1", labs)))) 
    step.fit <- glm(wage~cut(age,unique(breaks)), data = Wage) 
    cv.error[i] <- cv.glm(Wage ,step.fit, K=10)$delta[1] 
} 

cv.error 
[1] 0.000 1733.815 1682.731 1637.200 1631.049 1623.069 1613.099 1600.413 1613.127 1603.581 1603.601 
[12] 1604.730 1602.462