交叉驗證的R語言實現

2021-02-21 郭老師統計小課堂

在之前的內容泛化誤差和留出法,交叉驗證中,我們介紹了泛化誤差的概念以及用以估計泛化誤差的留出法、留一法和K折交叉驗證法,本節我們討論如何在R語言中進行實現。

本文以An Introduction to Statistical Learning with Applications in R中的Wage數據為例進行說明。我們用Age作為自變量對響應變量Wage進行建模,考慮多項式回歸模型:

首先考慮留出法,程序如下:

############hold-out####################library(ISLR)attach(Wage)set.seed(1)n=nrow(Wage)k=2subn=floor(n/k)train=sample(1: n, subn)cv.errorsho<-rep(0,5)
for (i in 1:5) { fit=lm(wage~poly(age,i), data=Wage, train) pred=predict(fit,newdata=Wage[-train,]) cv.errorsho[i]<-mean((pred-wage[-train])^2)}cv.errorshoplot(1:5,cv.errorsho,type="l")

cv.errorsho

[1] 1712.319 1625.294 1622.104 1620.998 1629.320

可見,

接下來,我們考慮留一法,即Leave-one-out-cross-validatioin。對此,我們有兩種做法,一種是基於公式:

這裡

############LOOCV####################set.seed(1)cv.error<-rep(0,5)for (i in 1:5) {  fit=lm(wage~poly(age,i),data=Wage)  pred=predict(fit)  X<-rep(1,n);  for (l in 1: i){    X<-matrix(c(X,age^l),n)  }  H=X%*%ginv(t(X)%*%X)%*%t(X);  h=diag(H);  cv.error[i]<-mean((pred-wage)^2/(1-h)^2)}cv.errorplot(1:5,cv.error,type="l")

cv.error

[1] 1676.235 1599.913 1594.727 1592.641 1592.153

儘管

另一種方法則直接使用R中自帶的cv.glm()函數。但需注意的是,cv.glm()並沒有使用上述簡潔的計算公式,所以在樣本量很大時,計算量會非常大。另外在調用cv.glm()時,需使用glm()來擬合模型。glm()命令中有family這個參數,若不設置則此時glm()的擬合結果和lm()的結果一致。程序如下:

##########cv.glm################set.seed(1)library(boot)cv.error=rep(0,5)for(i in 1:5){  glm.fit=glm(wage~poly(age,i))  cv.error[i]=cv.glm(Wage,glm.fit)$delta[1]}cv.errorplot(1:5,cv.error,type="l",xlab="Polynomial order", ylab="Mean Squared Error")

cv.error

[1] 1676.235 1600.529 1595.960 1594.596 1594.879

可見,

最後,我們考慮K折交叉驗證。對此,我們也採用了兩種方法。第一個程序命令是按照K折交叉驗證的思路來編寫的,容易知道這種思路也適用於其他問題的模型評價和模型選擇,而第二個程序則採用cv.glm,此命令專門針對廣義線性回歸模型。具體程序如下:

##############10-fold CV###################set.seed(1)k=10n=nrow(Wage)subn=floor(n/k)location=sample(1: n, n)cv.errors1<-matrix(0,k,5)
for(j in 1:k){ for (i in 1:5) { test<-location[(subn*(j-1)+1): (subn*j)] train<-location[-(subn*(j-1)+1: subn*j)] fit=lm(wage~poly(age,i), data = Wage, train) pred = predict(fit,newdata=Wage[test,]) cv.errors1[j,i]<-mean((pred-wage[test])^2) }}cv.error1=apply(cv.errors1,2, mean)cv.error1plot(1:5,cv.error1,type="l",xlab="Polynomial order", ylab="Mean Squared Error")

cv.error1

[1] 1673.669 1597.541 1592.690 1590.358 1590.418

###################################set.seed(1)cv.error2=rep(0,5)for(i in 1:5){  glm.fit=glm(wage~poly(age,i))  cv.error2[i]=cv.glm(Wage,glm.fit,K=10)$delta[1]}cv.error2plot(1:5,cv.error2,type="l",xlab="Polynomial order", ylab="Mean Squared Error")

cv.error2

[1] 1676.826 1600.763 1598.399 1595.651 1594.977

以上討論均針對回歸問題,當響應變量是離散的時,cv.glm也是適用的,此時需增加family參數,並修改損失函數。具體如何調用,可通過?cv.glm或者cv.glm進行查看。

                                       如果覺得本文不錯,請點讚關注!

相關焦點

  • R語言——交叉驗證法計算線性回歸模型擬合優度的第三種R方
    本來打算這周繼續更新一篇LaTex的小短文,但是貌似我已經很久沒有寫R語言相關的東西了。想來想去,今天就寫一篇和R語言有關的,畢竟不能忘記初心呀!凡是學過計量的同學,哪怕只記得一點點皮毛,對於R方和調整R方也應該是再熟悉不過了。R方和調整R方是判斷回歸模型擬合度的最為方便簡單的指標,一般來說,數值越大代表模型的擬合度越好。
  • R語言實現LASSO回歸模型
    此時如果用全新的數據去驗證模型(validation),通常效果很差。 一般來說,變量數大於數據點數量很多,或者某一個離散變量有太多獨特值時,都有可能過度擬合。   今天我們給大家介紹下在R語言如何實現LASSO模型構建,其中有兩個包是可以實現的(glmnet和lars)。因為glmnet涉及範圍涉及廣義線性模型,我們就主要介紹下lars是怎麼實現LASSO的。
  • R 語言 lasso回歸
    接下來以線性回歸為例介紹其在R語言中的實現,當然在logistic回歸、cox回歸也是可用lasso的。實例數據R包(glmnet)我們用交叉驗證來確定lamda的值,在這裡我們隨便指定使用nfolds=4 4折交叉驗證,實際中常用5折或者10折。
  • R 語言之數據分析「Resampling」
    交叉驗證( Cross validation )在交叉驗證的思想中,一個樣本被隨機的分成兩個或 K 個子樣本,將其中一個作為驗證集,其他 K-1 個子樣本組合成訓練集,在訓練集上獲得回歸方程,而後在驗證集上做出預測,這為一重驗證,而後所有子樣本輪流充當驗證集,如此往復,直至遍歷所有可能。
  • 三分鐘重新學習交叉驗證
    什麼是交叉驗證?「交叉驗證」是一種模型驗證技術,可用於評估統計分析(模型)結果在其它獨立數據集上的泛化能力。它主要用於預測,我們可以用它來評估預測模型在實踐中的準確度。Python 的實現方式:sklearn.model_selection.train_test_splitk 分劃分 —— 組數為k由於永遠不會有充足的數據來訓練模型,因此如果將數據集中的某一部分劃分出來用於驗證還會導致模型出現欠擬合的問題。
  • 嵌套交叉驗證(Nested cross-validation)
    傳統交叉驗證和嵌套交叉驗證的區別在開始分享嵌套交叉驗證前,首先以K-Fold為例,區分K-Fold交叉驗證和嵌套K-Fold交叉驗證的區別,這是我剛始學習時的困惑點:(1)K-Fold交叉驗證:只有一個loop(循環),即內層循環(a) 將數據集切分為k-摺疊;
  • 機器學習:R語言實現隨機森林
    #作圖展示 top30 重要的 OTUsvarImpPlot(otu_train.forest, n.var = min(30, nrow(otu_train.forest$importance)), main = 'Top 30 - variable importance')交叉驗證那麼,選擇多少重要的變量(本示例為OTUs)是更合適的呢?
  • K折交叉驗證實例
    交叉驗證思想交叉驗證用於模型選擇,可以更好的來估計模型的試驗誤差。
  • R語言-stringr-字符串處理
    ,不用轉義路徑複製和直接可用charchar <- r"(我是一名'R語言'學習者)"cat(char)常用函數截取字符串,匹配字符串,添加指定字符籌齊長度,去除左右兩邊空格,分割字符串,r_left <- function(str,num){  str_sub(string = str,start = 1,end = num)}r_left('我是R語言學習者',3)
  • R語言從入門到精通:Day12--R語言統計--回歸分析
    回歸作為一個廣義的概念,涵蓋了許多變種,R語言中也為其提供了強大而豐富的函數和選項(但顯然選項越多,對初學者越不友好),早在2005年,R中就有200多種關於回歸分析的函數 (https://cran.r-project.org/doc/contrib/Ricci-refcard-regression.pdf,這個文檔提供了部分回歸分析函數列表,供大家參考)。
  • r語言有什麼優劣勢及R語言的未來發展趨勢_R語言在現實中的應用
    正如Tiobe、PyPL以及Redmonk等程式語言人氣排名所指出,R語言所受到的關注程度正在快速提升。作為一款誕生於上世紀九十年代的語言,R已經成為S統計程式語言的一類實現方式。已經擁有十八年R編程經驗的高校教授兼Coursera在線平臺培訓師Roger Peng指出,「R語言已經成為統計領域最具人氣的語言選項」。
  • 機器學習乾貨|交叉驗證(Cross Validation)詳解
    交叉驗證也稱為循環估計,是統計上將數據樣本切割成較小集合的使用方法,由Seymour Geisser提出。交叉驗證應用場景主要在模型訓練中,在給定的樣本空間中,拿出大部分樣本作為訓練集,小部分樣本使用剛建立的模型進行測試,並求這小部分樣本的預測誤差或者預測精度,同時記錄它們的加和平均值,這個過程迭代K次,即K折交叉。
  • 用交叉驗證識別謠言,可能你都做錯了!
    這件利器就是——交叉驗證。關於交叉驗證,你可能會說:這沒什麼稀奇的啊,不就是同一件事獲取它不同緯度的信息來進行相互檢驗佐證嘛。如果你認為這件利器很容易上手,那麼你可能只練了個皮毛,甚至都練錯了!那麼,真正的交叉驗證是什麼?
  • R語言中獲取矩陣中元素的幾種形式
    在上一篇文章中,小編介紹了R語言中創建矩陣的幾種形式。今天,我們再來探討一下如何訪問矩陣中的元素。在R語言中獲取矩陣中的元素主要有以下幾種形式:獲取矩陣中所有的元素值只要使用矩陣名就可以獲取整個矩陣中的所有元素。
  • r語言的p值檢驗 - CSDN
    輸入1: rdata = matrix(rnorm(1000* 6, 0, 3), 6) rvar = apply(rdata, 2, var) mean(rvar)結果1: [1] 8輸入2: var(rvar)結果2: [1] 32=2*81/5輸入3:
  • 9 本優秀的 R 語言免費電子圖書
    R語言是主要用於統計分析、繪圖的語言和操作環境。 R本來是由來自紐西蘭奧克蘭大學的Ross Ihaka和Robert Gentleman 開發。
  • R語言arma模型診斷_arma模型實現模型r語言 - CSDN
    tsdiag(m1)  #對估計進行診斷,判斷殘差是否為白噪聲summary(m1)r=m1$residuals  #用r來保存殘差Box.test(r,type="Ljung-Box",lag=6, fitdf=1)#對殘差進行純隨機性檢驗,fitdf表示殘差減少的自由度
  • 掌握R語言for循環一文就夠了(認真臉)
    嗨,大家好,我就是帥氣的小編~R語言是進行統計分析和可視化的優秀語言(其實機器學習和網頁製作也可以用R,小聲說~|ω`))R語言相信大家在利用R語言進行數據分析的時候可能會有大數據分析需求。R語言不考慮並行運算下的簡單批處理實現方式就是for循環。
  • 醫學統計與R語言:GiViTI Calibration Belt
    https://cran.r-project.org/web/packages/givitiR/vignettes/givitiR.htmlNattino, G., Finazzi, S., & Bertolini, G. (2016).
  • 用AVR彙編語言實現AES及其優化
    本文在研究分析AES加密算法原理的基礎上,著重說明算法的實現步驟,並結合AVR彙編語言完整地實現AES加密和解密。根據AES原理,提出幾種列變化的優化算法,並根據實驗結果分析和比較它們的優缺點。本文以128為例,介紹算法的基本原理;結合AVR彙編語言,實現高級數據加密算法AES。1 AES加密、解密算法原理和AVR實現AES是分組密鑰,算法輸入128位數據,密鑰長度也是128位。用Nr表示對一個數據分組加密的輪數(加密輪數與密鑰長度的關係如表1所列)。