การตรวจสอบความถูกต้องแบบข้าม K-fold หรือ hold-out สำหรับการถดถอยแบบสันโดยใช้ R


9

ฉันกำลังทำงานกับการตรวจสอบความถูกต้องของการทำนายข้อมูลของฉันกับ 200 วิชาและ 1,000 ตัวแปร ฉันสนใจการถดถอยตามจำนวนตัวแปร (ฉันต้องการใช้) มากกว่าจำนวนตัวอย่าง ดังนั้นฉันต้องการใช้ตัวประมาณค่าการหดตัว ข้อมูลตัวอย่างประกอบด้วยข้อมูลต่อไปนี้:

 #random population of 200 subjects with 1000 variables 
    M <- matrix(rep(0,200*100),200,1000)
    for (i in 1:200) {
    set.seed(i)
      M[i,] <- ifelse(runif(1000)<0.5,-1,1)
    }
    rownames(M) <- 1:200

    #random yvars 
    set.seed(1234)
    u <- rnorm(1000)
    g <- as.vector(crossprod(t(M),u))
    h2 <- 0.5 
    set.seed(234)
    y <- g + rnorm(200,mean=0,sd=sqrt((1-h2)/h2*var(g)))

    myd <- data.frame(y=y, M)
myd[1:10,1:10]

y X1 X2 X3 X4 X5 X6 X7 X8 X9
1   -7.443403 -1 -1  1  1 -1  1  1  1  1
2  -63.731438 -1  1  1 -1  1  1 -1  1 -1
3  -48.705165 -1  1 -1 -1  1  1 -1 -1  1
4   15.883502  1 -1 -1 -1  1 -1  1  1  1
5   19.087484 -1  1  1 -1 -1  1  1  1  1
6   44.066119  1  1 -1 -1  1  1  1  1  1
7  -26.871182  1 -1 -1 -1 -1  1 -1  1 -1
8  -63.120595 -1 -1  1  1 -1  1 -1  1  1
9   48.330940 -1 -1 -1 -1 -1 -1 -1 -1  1
10 -18.433047  1 -1 -1  1 -1 -1 -1 -1  1

ฉันต้องการจะติดตามการตรวจสอบข้าม -

(1) แบ่งข้อมูลออกเป็นสองหยุด - ใช้ครึ่งแรกเป็นการฝึกอบรมและครึ่งหลังเป็นการทดสอบ

(2) การตรวจสอบความถูกต้องข้าม K-fold (พูด 10 เท่าหรือข้อเสนอแนะเกี่ยวกับการพับที่เหมาะสมอื่น ๆ สำหรับกรณีของฉันยินดีต้อนรับ)

ฉันสามารถตัวอย่างข้อมูลเป็นสอง (การเพิ่มและทดสอบ) และใช้พวกเขา:

# using holdout (50% of the data) cross validation 
training.id <- sample(1:nrow(myd), round(nrow(myd)/2,0), replace = FALSE)
test.id <- setdiff(1:nrow(myd), training.id)

 myd_train <- myd[training.id,]
 myd_test  <- myd[test.id,]   

ฉันใช้lm.ridgeจากMASSแพ็คเกจ R

library(MASS)
out.ridge=lm.ridge(y~., data=myd_train, lambda=seq(0, 100,0.001))
plot(out.ridge)
select(out.ridge)

lam=0.001
abline(v=lam)

out.ridge1 =lm.ridge(y~., data=myd_train, lambda=lam)
hist(out.ridge1$coef)
    out.ridge1$ym
hist(out.ridge1$xm)

ฉันมีสองคำถาม -

(1) ฉันจะทำนายชุดการทดสอบและคำนวณความแม่นยำได้อย่างไร (ตามความสัมพันธ์ของการทำนายกับค่าจริง)

(2) ฉันจะทำการตรวจสอบ K-fold ได้อย่างไร? พูด 10 เท่า?


1
คำถามนี้มีประโยชน์บางส่วน - stats.stackexchange.com/questions/23548/…
Ram Sharma

4
คุณอาจจะมองไปที่การ R rmsแพคเกจols, calibrateและvalidateฟังก์ชั่นที่มีการปรับไหมกำลังสอง (ถดถอยสัน)
Frank Harrell

@ FrankHarrell ฉันพยายามที่จะขยายข้อเสนอแนะของคุณเป็นคำตอบเพื่อประโยชน์ของทุกคน กรุณาดู!
Ram Sharma

คำตอบ:


2

คุณสามารถใช้caret แพ็คเกจ (vignnettes , paper ) สำหรับสิ่งต่าง ๆ ประเภทนี้ซึ่งสามารถห่อโมเดลการเรียนรู้ของเครื่องจำนวนมากหรือคุณสามารถใช้โมเดลที่คุณกำหนดเองก็ได้ ในขณะที่คุณสนใจในการถดถอยของสันเขาที่นี่เป็นเพียงรหัสที่กำหนดเองสำหรับการถดถอยของสันเขาคุณอาจต้องการนำมาใช้กับสถานการณ์ของคุณอย่างแม่นยำมากขึ้น

สำหรับการแบ่งข้อมูลอย่างง่าย:

set.seed(107)
# stratified random split of the data
inTrain <- createDataPartition(y = myd$y, p = .5,list = FALSE)
training <- myd[ inTrain,]
testing <- myd[-inTrain,]

สำหรับการตรวจสอบ K-fold และ CV ประเภทอื่นรวมถึงการบูตที่เป็นค่าเริ่มต้น

ridgeFit1 <- train(y ~ ., data = training,method = 'ridge', 
preProc = c("center", "scale"), metric = "ROC")
plot(ridgeFit1)

นี่คือการอภิปรายเกี่ยวกับวิธีการใช้trainฟังก์ชั่น หมายเหตุวิธีการสันขึ้นอยู่กับelasticnetฟังก์ชั่นแพคเกจ(และการพึ่งพาของlarsควรหรือจำเป็นต้องติดตั้ง) หากไม่ได้ติดตั้งในระบบจะถามว่าคุณต้องการทำเช่นนั้นหรือไม่

ประเภทของการ resampling ที่ใช้ bootstrap ง่าย ๆ จะถูกใช้โดยค่าเริ่มต้นในการปรับเปลี่ยนวิธี resampling จะมีการใช้ฟังก์ชัน trainControl

วิธีตัวเลือกจะควบคุมประเภทของการสุ่มใหม่และค่าเริ่มต้นเป็น "boot" อีกวิธีหนึ่งคือ "repeatcv" ถูกใช้เพื่อระบุการตรวจสอบความถูกต้อง K – fold cross – – (และอาร์กิวเมนต์จะควบคุมจำนวนการทำซ้ำซ้ำ) K ถูกควบคุมโดยอาร์กิวเมนต์ number และค่าเริ่มต้นที่ 10

 ctrl <- trainControl(method = "repeatedcv", repeats = 5)

 ridgeFit <- train(y ~ ., data = training,method = 'ridge',
preProc = c("center", "scale"),trControl = ctrl, metric = "ROC")

plot(ridgefit)

สำหรับการทำนาย:

plsClasses <- predict(ridgeFit, newdata = testing)

4

นี่คือส่วนขยายของข้อเสนอแนะโดย Frank ในความคิดเห็น Dr. Harrel โปรดแก้ไขถ้าฉันผิด (ขอบคุณการแก้ไข)

ข้อมูลของคุณ:

#random population of 200 subjects with 1000 variables 
    M <- matrix(rep(0,200*100),200,1000)
    for (i in 1:200) {
    set.seed(i)
      M[i,] <- ifelse(runif(1000)<0.5,-1,1)
    }
    rownames(M) <- 1:200

    #random yvars 
    set.seed(1234)
    u <- rnorm(1000)
    g <- as.vector(crossprod(t(M),u))
    h2 <- 0.5 
    set.seed(234)
    y <- g + rnorm(200,mean=0,sd=sqrt((1-h2)/h2*var(g)))

    myd <- data.frame(y=y, M)

ติดตั้งrmsแพ็คเกจและโหลด

require(rms)

ols ฟังก์ชั่นใช้สำหรับการประมาณตัวแบบเชิงเส้นโดยใช้กำลังสองน้อยที่สุดซึ่งสามารถระบุเทอมการลงโทษได้

ตามที่แนะนำด้านล่างในความคิดเห็นที่ฉันเพิ่มpetraceฟังก์ชั่น ฟังก์ชั่นนี้ติดตาม AIC และ BIC กับการลงโทษ

# using holdout (50% of the data) cross validation 
training.id <- sample(1:nrow(myd), round(nrow(myd)/2,0), replace = FALSE)
test.id <- setdiff(1:nrow(myd), training.id)

 myd_train <- myd[training.id,]
 myd_test  <- myd[test.id,] 

frm <- as.formula(paste("y~",paste(names(myd_train)[2:100],collapse="+")))

หมายเหตุสำคัญฉันไม่สามารถใช้ตัวแปรทั้งหมด 1,000 ตัวได้เนื่องจากโปรแกรมบ่นว่าจำนวนตัวแปรเกิน 100 ตัวแปรการy~.กำหนดสูตรประเภทไม่ทำงาน ดังนั้นดูวิธีการสร้างวัตถุสูตรเดียวกันข้างต้นfrm

f <- ols(frm, data = myd_train, method="qr", x=TRUE, y=TRUE)


p <- pentrace(f, seq(.2,1,by=.05))

Error in array(x, c(length(x), 1L), if (!is.null(names(x))) list(names(x),  : 
'data' must be of a vector type, was 'NULL'

 plot(p)

"สำหรับแบบธรรมดาที่ไม่ได้รับอนุญาตจาก lrm หรือ ols และสำหรับเวกเตอร์หรือรายการของการลงโทษเหมาะกับชุดของโมเดลโลจิสติกหรือเชิงเส้นโดยใช้การประมาณค่าความน่าจะเป็นที่ถูกลงโทษสูงสุดและบันทึกองศาที่มีประสิทธิภาพอย่างอิสระ Information Criterion (BIC) และ Hurvich และ Tsai ที่แก้ไข AIC (AIC_c) ของ Tsai ทางเลือก Pentrace สามารถใช้ฟังก์ชั่น nlminb เพื่อแก้หาค่าปรับที่เหมาะสมหรือการรวมกันของปัจจัยที่ทำผิดเงื่อนไขในรูปแบบต่าง ๆ " จากrmsคู่มือแพคเกจ

calibrateฟังก์ชั่นใช้สำหรับการปรับเทียบโมเดลการสอบเทียบซ้ำและใช้การจัดวางข้อมูลแบบข้ามหรือการตรวจสอบความถูกต้องเพื่อรับการประมาณค่าอคติ (แก้ไขเกินจริง) ของการคาดการณ์กับค่าที่สังเกตได้ validateฟังก์ชั่นไม่ resampling การตรวจสอบของรูปแบบการถดถอยมีหรือไม่มีการย้อนกลับการลบตัวแปรขั้นตอนลง B = จำนวนการทำซ้ำ สำหรับ method = "crossvalidation" คือจำนวนกลุ่มของการสังเกตที่ถูกละเว้น

cal <- calibrate(f, method = "cross validation", B=20)  
plot(cal)

คุณสามารถใช้Predictฟังก์ชั่นในการคำนวณค่าที่คาดการณ์และขีด จำกัด ของความเชื่อมั่น ฉันไม่แน่ใจว่าสิ่งนี้ทำงานได้ในสถานการณ์ทดสอบ


ดูดี. ใช้pentraceฟังก์ชั่น
Frank Harrell

@ FrankHarrell ขอบคุณที่ดู โปรดดูที่รุ่นปัจจุบันของฉันฉันตีปัญหาไม่กี่รวมถึงข้อผิดพลาดในขณะที่penetranceฟังก์ชั่นการดำเนินงาน
Ram Sharma

คุณไม่ได้ระบุไปx=TRUE, y=TRUE olsแต่มีปัญหากับpentraceเมื่อแบบจำลองมีความสมบูรณ์แบบเกิน (ข้อผิดพลาด df เป็นศูนย์) ซึ่งpentraceพยายามตรวจสอบแบบจำลองที่ไม่ผ่านการเปิดซึ่งมีR2=1.0. สำหรับรุ่นถัดไปของrmsฉันได้เพิ่มอาร์กิวเมนต์ใหม่ไปที่pentrace: noaddzero=TRUEเพื่อไม่เพิ่มศูนย์ลงในรายการบทลงโทษที่จะลอง โปรดทราบว่าตัวอย่างของคุณไม่ใช่ตัวอย่างที่ดีที่สุดเนื่องจากการลงโทษที่เหมาะสมคือ.
Frank Harrell

3

แพคเกจ R glmnet( บทความสั้น ) มีฟังก์ชั่นกระดาษห่อที่ทำสิ่งที่คุณต้องการเรียกว่าcv.glmnet( doc ) ฉันเพิ่งใช้เมื่อวานนี้มันทำงานเหมือนฝัน


เราจะทำการถดถอยเชิงเส้นทั่วไปในแพ็คเกจนี้ได้อย่างไร?
rdorlearn

สำหรับการถดถอยเชิงเส้นมีcv.lmในpackage:DAAGและ GLM มีเป็นในcv.glm package:bootแต่ผมเพิ่งตระหนักแฟรงก์ Harrell rmsปัญหา โดยทั่วไปคุณควรทำสิ่งที่เขาบอกคุณ มันก็ดูเหมือนว่ามันเป็นกรอบทั่วไปมากกว่าชิ้นส่วนที่ฉันแนะนำอยู่แล้ว
shadowtalker

glmnetดูเหมือนแพ็คเกจที่น่าสนใจขอบคุณสำหรับข้อมูล
rdorlearn

1
@rdorlearn การถดถอยเชิงเส้นเป็นเพียง GLM พร้อมฟังก์ชันลิงก์ตัวตน
Joe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.