R語言 | N次K折交叉驗證(基于邏輯回歸)

歡迎大家關(guān)注我的公眾號:一只勤奮的科研喵

N次K折交叉驗證

目 錄

  1. K折交叉驗證簡介
  2. R語言N次K折交叉驗證
  3. 不同K取值的比較

1. 交叉驗證基本介紹

通常在建立模型后需要使用外部進行驗證,以評估模型的外部可用性。然而,獲取外部數(shù)據(jù)并不容易,這時交叉驗證(Cross Validation)則是一種較好的可替代方案。交叉驗證的方法很多,這里我們介紹最常用的k折交叉驗證

簡單解釋一下:
  • 假如原始數(shù)據(jù)為100例患者,建模后我們使用K折交叉驗證(K一般取3-10折)。
  • 若取K=10,則:將原始數(shù)據(jù)分為10份(K值):
  • 9份做訓(xùn)練,1份做驗證,這樣循環(huán)10次(因為這樣的組合有10種)。
  • 取10次評價指標的平均值(如AUC值)作為模型的驗證結(jié)果。

即【數(shù)據(jù)分為K個子集,1個子集做驗證,K-1個子集做訓(xùn)練,這樣的取法有K種,所以會產(chǎn)生K個新數(shù)據(jù)集(訓(xùn)練集+訓(xùn)練集)。我們進行K次訓(xùn)練和驗證得到的平均評價指標可能較為準確


為了保證數(shù)據(jù)分割的影響,目前的k折交叉驗證一般會進行多次重復(fù)(200-1000次)。即進行200次的10折交叉驗證。這樣做出的結(jié)果可能會更加準確。
如文獻所示:

參考文獻:Alexia Iasono et al. How To Build and Interpret a Nomogram for Cancer Prognosis.png

參考文獻:Development and validation of NTCP models for acute side-effects resulting from proton beam therapy of brain tumours.png

2. R語言:K折交叉驗證

1.載入R包和數(shù)據(jù)

library(caret)#做交叉驗證用
library(pROC)#畫ROC曲線用
#清理運行環(huán)境
rm(list = ls()) 
#載入R包
aa<- read.csv('交叉驗證示例.csv')
#查看變量性質(zhì)
str(aa)
#批量數(shù)值轉(zhuǎn)因子
for (i in names(aa)[c(4:9)]){aa[,i] <- as.factor(aa[,i])}
#再次檢查變量性質(zhì)
str(aa)
  • 載入數(shù)據(jù)后查看數(shù)據(jù)類型、有無缺項等是做數(shù)據(jù)分析很重要的一步,很大一部分錯誤都是原始數(shù)據(jù)轉(zhuǎn)換出錯造成的。
  • 分類變量是factor形式而不是num/int
    2.png

2-1 數(shù)據(jù)分割(K折)

#設(shè)置隨機種子,使數(shù)據(jù)分割可重復(fù)
set.seed(1)
#多次K折交叉驗證,如5折400次交叉驗證
folds <-createMultiFolds(y=aa$status,k=5,times=400)
#folds會產(chǎn)生5*400=2000個數(shù)據(jù)組合
#取fold 1數(shù)據(jù)為訓(xùn)練集,
train <- aa[folds[[1]],]
#其余為驗證集
test <- aa[-folds[[1]],]
3.png
  • 可以發(fā)現(xiàn),Rstudio右邊生成了2000個數(shù)據(jù)集是5折交叉驗證重復(fù)的400次。
  • 訓(xùn)練集310或311人,滿足K-1組人做訓(xùn)練,1組做驗證

2-2 取1個數(shù)據(jù)集做一次訓(xùn)練和驗證

#構(gòu)建邏輯回歸模型
model<-glm(status~age+n+hr+lvi+g+rt,
          family = binomial(link=logit), 
          data=train )
#驗證隊列做預(yù)測
model_pre<-predict(model,
                   type='response',
                   newdata=test)
#查看AUC值、敏感性、特異性
roc1<-roc((test$status),model_pre)
round(auc(roc1),3)
roc1$sensitivities
round(roc1$specificities,3)
#ROC可視化
plot(roc1, 
     print.auc=T, 
     auc.polygon=T, 
     auc.polygon.col="skyblue",
     grid=c(0.1, 0.2),
     grid.col=c("green", "red"), 
     max.auc.polygon=T,
     print.thres=T)

4.png

2-3 批量計算AUC值

上述過程重復(fù)2000次,得到2000個auc值,取平均值即可得到模型400次5折交叉驗證的auc校準值。

#建一個放auc值的空向量
auc_value<-as.numeric()
#上述步驟2000次
for(i in 1:2000){
  train<- aa[ folds[[i]],] #folds[[i]]作為測試集
  test <- aa[-folds[[i]],] #剩下的數(shù)據(jù)作為訓(xùn)練集
  model<- glm(status~age+n+hr+lvi+g+rt,family=binomial(link=logit),data=train)
  model_pre<-predict(model,type='response', newdata=test)
  auc_value<- append(auc_value,as.numeric(auc(as.numeric(test[,1]),model_pre)))
}
#查看auc值分及平均auc
summary(auc_value)
mean(auc_value) 
# AUC=0.8901765



3. 不同交叉驗證比較

結(jié)果

    1. 無交叉驗證AUC值:0.906
    1. 400次5折交叉驗證平均AUC :0.89047
    1. 200次10折交叉驗證平均AUC:0.89092
    1. 單純10折交叉驗證平均AUC :0.88537
      因此交叉驗證是十分必要的,推薦N次K折交叉驗證

1. 400次5折交叉驗證
平均AUC=0.890468(代碼見上)
2. 不做交叉驗證
AUC=0.906

model1<-glm(status~age+n+hr+lvi+g+rt,
            family = binomial(link = logit),
            data=aa)
model_pre1<-predict(model1,type='response')
roc2<-roc((aa$status),model_pre1);auc(roc2)

3. 200次10折交叉驗證
平均AUC=0.8909152

set.seed(1)
folds <-createMultiFolds(y=aa$status,k=10,times=200)
#2000次批量訓(xùn)練與驗證
#做成循環(huán)
auc_value<-as.numeric()
for(i in 1:2000){
  train<- aa[ folds[[i]],] 
  test <- aa[-folds[[i]],] 
  model<- glm(status~age+n+hr+lvi+g+rt,family=binomial(link=logit),data=train)
  model_pre<-predict(model,type='response', newdata=test)
  auc_value<- append(auc_value,as.numeric(auc(as.numeric(test[,1]),model_pre)))
}
mean(auc_value)

4. 單純10折交叉驗證
平均AUC=0.8853679

set.seed(1)
#單純10折交叉驗證,time=1
folds <-createMultiFolds(y=aa$status,k=10,times=1)
#10次批量訓(xùn)練與驗證
#做成循環(huán)
auc_value<-as.numeric()
for(i in 1:10){
  train<- aa[ folds[[i]],] 
  test <- aa[-folds[[i]],] 
  model<- glm(status~age+n+hr+lvi+g+rt,
              family=binomial(link=logit),data=train)
  model_pre<-predict(model,type='response', newdata=test)
  auc_value<- append(auc_value,
                     as.numeric(auc(as.numeric(test[,1]),model_pre)))
}
mean(auc_value)

歡迎大家關(guān)注我的公眾號:一只勤奮的科研喵

相關(guān)專題:

  • R語言 | X年N次K折交叉驗證
  • R語言 | 多指標N次K折交叉驗證
一只勤奮的科研喵
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內(nèi)容