㈠ 如何進行變數篩選和特徵選擇(三)交叉驗證
交叉驗證是機器學習中常用的一種驗證和選擇模型的方法,常用的交叉驗證方法是K折交叉驗證。將原始數據分成K組(一般是均分),將每個子集分別作一次驗證集,其餘的K-1組子集數據作為訓練集,這樣會得到K個模型,k個模型的驗證誤差的均值即作為模型的總體驗證誤差,取多次驗證的平均值作為驗證結果,誤差小的模型則為最優模型。k一般大於等於2,一般而言 k=10 (作為一個經驗參數)算是相當足夠了。
採用的R包是bestglm,主要函數是bestglm()。
結合一個二元Logistic回歸的例子,分享如何運用R軟體實現10折交叉驗證。
搭建完模型,運用predict()得到預測概率,保存測試集的預測概率。
函數中IC = "CV"表示採用交叉驗證,CVArgs 表示交叉驗證的參數,k=10表示分成10份,REP=1是每次一份作為測試集,family=binomial 表示因變數為二項分布。該函數是利用最優子集回歸的原理,對於不同數量的特徵,都用k折交叉驗證法求一個驗證誤差,最後比較驗證誤差與特徵數量的關系,選取最優變數。
將返回結果的cv列作圖,可以看到在模型變數個數為3的時候,驗證誤差變得很小,之後隨著變數個數增加,誤差變化不大。利用coef()函數可查看最優變數。
根據篩選的最優變數,搭建模型,運用predict()得到預測概率。
根據ROC曲線面積對比兩個模型在測試集上的預測性能,檢驗P值>0.05,且AUC均接近於1,說明兩模型預測性能一致且很好,但交叉驗證得到的模型變數為3個,模型簡潔,在實際運用中效率更高,因此可選擇交叉驗證的模型作為最優模型。
在構建模型做變數篩選方法比較多,在前面推文中給大家介紹了2個,可以翻看一下
如何進行高維變數篩選和特徵選擇(一)?Lasso回歸
如何進行變數篩選和特徵選擇(二)?最優子集回歸
以上就是本次跟大家分享的內容,覺得有用的話點贊、轉發哦~
㈡ 5折交叉驗證與10折區別
5折交叉驗證與10折區別:5折交叉驗證就是把樣本分為5份,其中4份用來做訓練建立模型,留剩下的一份來驗證,交叉驗證重復5次,每個子樣本驗證一次。10折交叉驗證將數據集分成十份,輪流將其中9份做訓練1份做驗證,10次的結果的均值作為對演算法精度的估計,一般還需要進行多次10折交叉驗證求均值。交叉驗證也稱作循環估計(RotationEstimation),是一種統計學上將數據樣本切割成較小子集的實用方法,該理論是由SeymourGeisser提出的。
㈢ 什麼是交叉檢驗
交叉驗證(Cross Validation)是用來驗證分類器的性能一種統計分析方法,基本思想是把在某種意義下將原始數據(dataset)進行分組,一部分做為訓練集(training set),另一部分做為驗證集(validation set),首先用訓練集對分類器進行訓練,在利用驗證集來測試訓練得到的模型(model),以此來做為評價分類器的性能指標。常見的交叉驗證方法如下:1、Hold-Out Method
將原始數據隨機分為兩組,一組做為訓練集,一組做為驗證集,利用訓練集訓練分類器,然後利用驗證集驗證模型,記錄最後的分類准確率為此分類器的性能指標。此種方法的好處的處理簡單,只需隨機把原始數據分為兩組即可,其實嚴格意義來說Hold-Out Method並不能算是CV,因為這種方法沒有達到交叉的思想,由於是隨機的將原始數據分組,所以最後驗證集分類准確率的高低與原始數據的分組有很大的關系,所以這種方法得到的結果其實並不具有說服性。
2、Double Cross Validation(2-fold Cross Validation,記為2-CV)
做法是將數據集分成兩個相等大小的子集,進行兩回合的分類器訓練。在第一回合中,一個子集作為training set,另一個便作為testing set;在第二回合中,則將training set與testing set對換後,再次訓練分類器,而其中我們比較關心的是兩次testing sets的辨識率。不過在實務上2-CV並不常用,主要原因是training set樣本數太少,通常不足以代表母體樣本的分布,導致testing階段辨識率容易出現明顯落差。此外,2-CV中分子集的變異度大,往往無法達到「實驗過程必須可以被復制」的要求。
3、K-fold Cross Validation(K-折交叉驗證,記為K-CV) 將原始數據分成K組(一般是均分),將每個子集數據分別做一次驗證集,其餘的K-1組子集數據作為訓練集,這樣會得到K個模型,用這K個模型最終的驗證集的分類准確率的平均數作為此K-CV下分類器的性能指標。K一般大於等於2,實際操作時一般從3開始取,只有在原始數據集合數據量小的時候才會嘗試取2。K-CV可以有效的避免過學習以及欠學習狀態的發生,最後得到的結果也比較具有說服性。
4、Leave-One-Out Cross Validation(記為LOO-CV) 如果設原始數據有N個樣本,那麼LOO-CV就是N-CV,即每個樣本單獨作為驗證集,其餘的N-1個樣本作為訓練集,所以LOO-CV會得到N個模型,用這N個模型最終的驗證集的分類准確率的平均數作為此下LOO-CV分類器的性能指標。相比於前面的K-CV,LOO-CV有兩個明顯的優點:
(1)每一回合中幾乎所有的樣本皆用於訓練模型,因此最接近原始樣本的分布,這樣評估所得的結果比較可靠。
(2)實驗過程中沒有隨機因素會影響實驗數據,確保實驗過程是可以被復制的。
但LOO-CV的缺點則是計算成本高,因為需要建立的模型數量與原始數據樣本數量相同,當原始數據樣本數量相當多時,LOO-CV在實作上便有困難幾乎就是不顯示,除非每次訓練分類器得到模型的速度很快,或是可以用並行化計算減少計算所需的時間。
㈣ 一文看懂 AI 訓練集、驗證集、測試集(附:分割方法+交叉驗證)
先用一個不恰當的比喻來說明3種數據集之間的關系:
訓練集(Training Dataset)是用來訓練模型使用的。
在《 一文看懂機器學習 》里我們介紹了機器學習的7個步驟,訓練集(Training Dataset)主要在訓練階段使用。
當我們的模型訓練好之後,我們並不知道他的表現如何。這個時候就可以使用驗證集(Validation Dataset)來看看模型在新數據(驗證集和測試集是不同的數據)上的表現如何。 同時通過調整超參數,讓模型處於最好的狀態 。
驗證集有2個主要的作用:
說明:
當我們調好超參數後,就要開始「最終考試」了。我們通過測試集(Test Dataset)來做最終的評估。
通過測試集的評估,我們會得到一些最終的評估指標,例如:准確率、精確率、召回率、F1等。
擴展閱讀:《 分類模型評估指標——准確率、精準率、召回率、F1、ROC曲線、AUC曲線 》
下面的數據集劃分方式主要針對「留出法」的驗證方式,除此之外還有其他的交叉驗證法,詳情見下文——交叉驗證法。
數據劃分的方法並沒有明確的規定,不過可以參考3個原則:
假如我們教小朋友學加法:1個蘋果+1個蘋果=2個蘋果
當我們再測試的時候,會問:1個香蕉+1個香蕉=幾個香蕉?
如果小朋友知道「2個香蕉」,並且換成其他東西也沒有問題,那麼我們認為小朋友學習會了「1+1=2」這個知識點。
如果小朋友只知道「1個蘋果+1個蘋果=2個蘋果」,但是換成其他東西就不會了,那麼我們就不能說小朋友學會了「1+1=2」這個知識點。
評估模型是否學會了「某項技能」時,也需要用新的數據來評估,而不是用訓練集里的數據來評估。這種「訓練集」和「測試集」完全不同的驗證方法就是交叉驗證法。
留出法(Holdout cross validation)
上文提到的,按照固定比例將數據集 靜態的 劃分為訓練集、驗證集、測試集。的方式就是留出法。
留一法(Leave one out cross validation)
每次的測試集都只有一個樣本,要進行 m 次訓練和預測。
這個方法用於訓練的數據只比整體數據集少了一個樣本,因此最接近原始樣本的分布。但是訓練復雜度增加了,因為模型的數量與原始數據樣本數量相同。
一般在數據缺乏時使用。
k 折交叉驗證(k-fold cross validation)
靜態的「留出法」對數據的劃分方式比較敏感,有可能不同的劃分方式得到了不同的模型。「k 折交叉驗證」是一種動態驗證的方式,這種方式可以降低數據劃分帶來的影響。具體步驟如下:
k 一般取 10
數據量小的時候,k 可以設大一點,這樣訓練集占整體比例就比較大,不過同時訓練的模型個數也增多。
數據量大的時候,k 可以設小一點。
本文首發自 產品經理的 AI 學習庫 easyai.tech
㈤ R語言之決策樹和隨機森林
R語言之決策樹和隨機森林
總結決策樹之前先總結一下特徵的生成和選擇,因為決策樹就是一種內嵌型的特徵選擇過程,它的特徵選擇和演算法是融合在一起的,不需要額外的特徵選擇。
一、特徵生成:
特徵生成是指在收集數據之時原始數據就具有的數據特徵,這些數據特徵由收集的數據決定(其實也就是在產品定型時設定的需要收集的數據特徵),當然,在數據預處理時,也可以在此基礎上構造一些新的數據特徵,這些特徵越多越好,表示你考慮問題比較周全,具體那些變數有用或沒用,這要交給下一步特徵選擇來決定。
二、特徵選擇
特徵選擇是指在原有數據特徵的基礎上,去除重要性比較低的特徵變數,過濾出有用的特徵變數。這里比較困難的是搞清楚什麼樣的特徵比較重要?這需要根據具體的問題具體分析,有些變數的選擇可以很直觀的看出來,但這種直覺也不一定正確。對於常用特徵選擇方法主要有:過濾型、包裝型、內嵌型。
過濾型:是指你可以根據某個統計量的大小排序來選擇特徵變數,如相關系數、p值、R值等
包裝型:是指在一個特徵集合中選取最優的特徵子集。具體需要考慮:用什麼樣的演算法來選取?選取的最優的標準是什麼?
常用的演算法是分步回歸包括向前搜索、向後刪除、雙向搜索
向前搜索:每次選取一個能使模型預測或分類效果最好的特徵變數進來,進來後不退出,直到模型改善效果不再明顯;
向後刪除:是指每次從特徵全集中每次刪除一個特徵變數能使模型預測或分類效果最好,退出後不進來,直到模型改善效果不再明顯;
雙向搜索:是指每次每次刪除一個特徵變數或加入一個特徵變數能使模型預測或分類效果最好,退出的不進來,進來的不退出,直到模型改善效果不再明顯;
這里再提一下特徵變數選擇的幾個標准:p值、R值、AIC(越小效果越好)、BIC(越小效果越好)、熵(越小效果越好)
內嵌型:這里應該主要就是像決策樹這樣的情況,演算法內部完成特徵變數的選取。
三、決策樹
決策的幾個要點:1、如何決策?(也就是如何樹如何分叉)------熵和信息增益---這裡麵包含的就是特徵的選擇?哪個特徵變數包含的信息量大,就排在前面,至於最後樹的深度就決定特徵變數的個數。
當然不同的演算法使用的衡量的標准不同,還有:信息增益比、基尼不純系數
2、如何剪枝?-----一般是事後剪枝
3、連續性變數如何離散化?-----閾值的選擇
熵:是指信息的混合程度(混亂程度),熵【0-1】越大表示該集合中混合的信息越多,也就表明這次的分叉效果不好還是有很多不同類的信息混在一起
信息增益:熵值的減少量,越大越好
決策樹模型特點:模型易於解釋;存儲空間較小,以樹的形式存儲,決策樹是一個弱分類器,不能完全分類,需要把多個弱分類器通過多數投票法組合在一起。
四、R包實現決策樹
library(rpart)
library(rpart.plot)
## rpart.control對樹進行一些設置
## xval是10折交叉驗證
## minsplit是最小分支節點數,這里指大於等於20,那麼該節點會繼續分劃下去,否則停止
## minbucket:葉子節點最小樣本數
## maxdepth:樹的深度
## cp全稱為complexity parameter,指某個點的復雜度,對每一步拆分,模型的擬合優度必須提高的程度
ct <- rpart.control(xval=10, minsplit=20, cp=0.1)
## kyphosis是rpart這個包自帶的數據集
## na.action:缺失數據的處理辦法,默認為刪除因變數缺失的觀測而保留自變數缺失的觀測。
## method:樹的末端數據類型選擇相應的變數分割方法:
## 連續性method=「anova」,離散型method=「class」,計數型method=「poisson」,生存分析型method=「exp」
## parms用來設置三個參數:先驗概率、損失矩陣、分類純度的度量方法(gini和information)
## cost是損失矩陣,在剪枝的時候,葉子節點的加權誤差與父節點的誤差進行比較,考慮損失矩陣的時候,從將「減少-誤差」調整為「減少-損失」
data("Kyphosis")
fit <- rpart(Kyphosis~Age + Number + Start,data=kyphosis, method="class",control=ct,parms = list(prior = c(0.65,0.35), split = "information"));
## 作圖有2種方法
## 第一種:
par(mfrow=c(1,3));plot(fit); text(fit,use.n=T,all=T,cex=0.9)
## 第二種,這種會更漂亮一些:
rpart.plot(fit, branch=1, branch.type=2, type=1, extra=102,
shadow.col="gray", box.col="green",
border.col="blue", split.col="red",
split.cex=1.2, main="Kyphosis決策樹");
## rpart包提供了復雜度損失修剪的修剪方法,printcp會告訴分裂到每一層,cp是多少,平均相對誤差是多少
## 交叉驗證的估計誤差(「xerror」列),以及標准誤差(「xstd」列),平均相對誤差=xerror±xstd
printcp(fit)
## 通過上面的分析來確定cp的值
##調用CP(complexity parameter)與xerror的相關圖,一種方法是尋找最小xerror點所對應
#的CP值,並由此CP值決定樹的大小,另一種方法是利用1SE方法,尋找xerror+SE的最小點對應的CP值。
plotcp(fit)
##利用以下方法進行修剪:
## prune(fit, cp= fit$cptable[which.min(fit$cptable[,"xerror"]),"CP"])
fit2 <- prune(fit, cp=0.01)
#利用模型預測
ndata=data.frame(...)
predict(fit,newdata=ndata)
#案例
str(iris)
set.seed(1234)#設置隨機數種子--使每次運行時產生的一組隨機數相同,便於結果的重現
#抽樣:從iris數據集中隨機抽70%定義為訓練數據集,30%為測試數據集(常用)
#這里是對行抽樣,ind是一個只含1和2的向量
ind <- sample(2, nrow(iris), replace=TRUE, prob=c(0.7, 0.3))
trainData <- iris[ind==1,]
testData <- iris[ind==2,]
f<-Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width
#訓練數據
fit<-rpart(f,trainData)
#預測
re<-predict(fit,testData)
#******************或者用其他包********************
library(party)
#建立決策樹模型預測花的種類
myFormula <- Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width
iris_ctree <- ctree(myFormula, data=trainData)
# 查看預測的結果
z<-table(predict(iris_ctree), trainData$Species)
#可以根據以上列聯表求出預測的正確率---評估模型
#計算準確度
q<-sum(diag(z))/sum(z)
五、機器集成與隨機森林法則
前面說過,決策樹的一個特點是:弱分類器,分類不完全,需要利用集成投票的方式來增加精確度和穩健性。
機器集成演算法:對於數據集訓練多個模型,對於分類問題,可以採用投票的方法,選擇票數最多的類別作為最終的類別,而對於回歸問題,可以採用取均值的方法,取得的均值作為最終的結果。主要的集成演算法有bagging和adaboost演算法。
隨機森林:隨機森林就是利用機器集成多個決策樹,主要有兩個參數,一個是決策樹的個數,一個是每棵樹的特徵變數個數。
隨機森林特點:精確度高、穩健性好,但可解釋性差。(可以知道各個變數的重要性)
R包實現機器集成演算法:
#adabag包均有函數實現bagging和adaboost的分類建模
#利用全部數據建模
library(adabag)
a<-boosting(Species~.,data=iris)
z0<-table(iris[,5],predict(a,iris)$class)
#計算誤差率
E0<-(sum(z0)-sum(diag(z0)))/sum(z0)
barplot(a$importance)
b<-errorevol(a,iris)#計算全體的誤差演變
plot(b$error,type="l",main="AdaBoost error vs number of trees") #對誤差演變進行畫圖
a<-bagging(Species~.,data=iris)
z0<-table(iris[,5],predict(a,iris)$class)
#計算誤差率
E0<-(sum(z0)-sum(diag(z0)))/sum(z0)
barplot(a$importance)
b<-errorevol(a,iris)#計算全體的誤差演變
plot(b$error,type="l",main="AdaBoost error vs number of trees") #對誤差演變進行畫圖
#5折交叉驗證
set.seed(1044) #設定隨機種子
samp=c(sample(1:50,25),sample(51:100,25),sample(101:150,25)) #進行隨機抽樣
a=boosting(Species~.,data=iris[samp,]) #利用訓練集建立adaboost分類模
z0<-table(iris[samp,5],predict(a,iris[samp,])$class)#訓練集結果
z1<-table(iris[-samp,5],predict(a,iris[-samp,])$class)#測試集結果
E0<-(sum(z0)-sum(diag(z0)))/sum(z0)
E1<-(sum(z0)-sum(diag(z0)))/sum(z1)
a=bagging(Species~.,data=iris[samp,]) #利用訓練集建立adaboost分類模
z0<-table(iris[samp,5],predict(a,iris[samp,])$class)#訓練集結果
z1<-table(iris[-samp,5],predict(a,iris[-samp,])$class)#測試集結果
E0<-(sum(z0)-sum(diag(z0)))/sum(z0)
E1<-(sum(z0)-sum(diag(z0)))/sum(z1)
R包實現隨機森林:
#隨機森林法則
library(randomForest)
library(foreign)
data("iris")
#抽樣數據
ind<-sample(2,nrow(iris),replace = TRUE,prob=c(0.7,0.3))
traning<-iris[ind==1,]
testing<-iris[ind==2,]
#訓練數據
rf <- randomForest(Species ~ ., data=traning, ntree=100, proximity=TRUE)
#預測
table(predict(rf),traning$Species)
table(predict(rf,testing),testing$Species)
#查看預測的效果
print(rf)
plot(rf)
#查看重要性
importance(rf)
varImpPlot(rf)
㈥ 交叉驗證,K折交叉驗證的偏差和方差分析
交叉驗證是一種通過估計模型的泛化誤差,從而進行模型選擇的方法。沒有任何假定前提,具有應用的普遍性,操作簡便, 是一種行之有效的模型選擇方法。
人們發現用同一數據集,既進行訓練,又進行模型誤差估計,對誤差估計的很不準確,這就是所說的模型誤差估計的樂觀性。為了克服這個問題,提出了交叉驗證。基本思想是將數據分為兩部分,一部分數據用來模型的訓練,稱為訓練集;另外一部分用於測試模型的誤差,稱為驗證集。由於兩部分數據不同,估計得到的泛化誤差更接近真實的模型表現。數據量足夠的情況下,可以很好的估計真實的泛化誤差。但是實際中,往往只有有限的數據可用,需要對數據進行重用,從而對數據進行多次切分,得到好的估計。
以上兩種方法基於數據完全切分,重復次數多,計算量大。因此提出幾種基於數據部分切分的方法減輕計算負擔。
衡量一個模型評估方法的好壞,往往從偏差和方差兩方面進行。
3.再來個射箭問題:假設你在射箭,紅星是你的目標,以下是你的射箭結果
分析:
綜合起來看,我們需要的模型最好是兩個L,又准確又穩定,妥妥的,但是,這個在現實模型中是不會存在的。你只能權衡著來
一句話,過擬合會出現高方差問題
一句話,欠擬合會出現高偏差問題
避免欠擬合(刻畫不夠)
避免過擬合(刻畫太細,泛化太差)
1. 交叉驗證,這是僅使用訓練集衡量模型性能的一個方便技術,不用建模最後才使用測試集
2. Cross-validation 是為了有效的估測 generalization error(泛化誤差) 所設計的實驗方法,而generalization error=bias+variance
可以發現,怎麼來平衡Bias和Variance則成了我們最大的任務了,也就是怎麼合理的評估自己模型呢?我們由此提出了交叉驗證的思想,以K-fold Cross Validation(記為K-CV)為例,基本思想如下:(其他更多方法請看 @bigdataage --交叉驗證(Cross-Validation) )
看不清上面的就來一幅更簡單的
每次的training_set 紅色, validation_set白色 ,也就是說k=5的情況了
注意:交叉驗證使用的僅僅是訓練集!!根本沒測試集什麼事!很多博客都在誤導!
這也就解決了上面剛開始說的Variance(不同訓練集產生的差異),Bias(所有data訓練結果的平均值)這兩大問題了!因為交叉驗證思想集合了這兩大痛點,能夠更好的評估模型好壞!
說白了,就是你需要用下交叉驗證去試下你的演算法是否精度夠好,夠穩定!你不能說你在某個數據集上表現好就可以,你做的模型是要放在整個數據集上來看的!畢竟泛化能力才是機器學習解決的核心
@知乎--機器學習中的Bias(偏差),Error(誤差),和Variance(方差)有什麼區別和聯系?
@知乎--方差和偏差
@bigdataage --交叉驗證(Cross-Validation)
@一隻鳥的天空--機器學習中防止過擬合的處理方法
㈦ 訓練集、驗證集、測試集(交叉驗證)
模型參數分為 訓練參數 和 超參數 ,其中前者是在訓練集上訓練得到的,而後者是在訓練之前由用戶指定的,比如學習率、迭代次數等。
機器學習中,樣本集通常會被分為 訓練集 、 驗證集 和 測試集 ,其中訓練集和測試集是必須有的。
對於一個訓練好的模型,需要了解它的泛化性能(在新樣本上的准確率),真正的泛化性能應該在除原樣本集之外的所有潛在樣本上進行計算,但實際中沒法得到這些潛在樣本,於是退而求其次,在原樣本集上劃分出了一個測試集作為近似,並將在該測試集上的泛化性能近似作為在所有樣本上的泛化性能。
注意: 測試集中的樣本與訓練集、驗證集不能有任何交集;測試集只能用於檢驗最終模型的泛化性能,不能用於更新模型參數。換句話說,只有最終模型才需要經過測試集檢驗泛化性能,或者說模型經過測試集檢驗泛化性能後就不能再進行任何訓練或修改參數了 。如果將在測試集上得到的准確率(也就是誤差)反過來作為模型進一步訓練的依據,實際上是將測試集也作為訓練集對待了,也就沒有了測試集。
實際中,有人會這么做,當碰到最終模型在測試集上的准確率不高時,又反過來重新調整超參數或利用測試集上的誤差進一步訓練模型,如此重復直到模型在測試集上表現很好,但上線後發現模型的准確率很低。出現上線後准確率低的其中一種原因就是誤用了測試集,上述過程實際上就沒有測試集,而是將整個樣本集都作為了訓練集,並且調整模型使其在測試集上獲得高准確率的做法還會導致模型過擬合,上線後准確率自然會很低。
理論上,如果最終模型在測試集上的表現非常差,則應該從樣本數據量、樣本分布、訓練集和測試集劃分情況、模型選擇等一系列因素入手查找原因,而不是回去繼續調整模型參數(雖然也有可能就是模型參數還不不夠好)。
值得注意的是, 測試集上的准確率不一定越高越好 。如果樣本集本身的分布就很有局限性(無法有效表徵所有潛在樣本的基本特徵),那麼測試集的分布就更有局限性,此時測試集上的高准確率就意味著嚴重的過擬合,模型投入實際應用後准確率一定差。因此對於不太理想的樣本集而言,測試集上的准確率相對低一些,模型的真正泛化性能反而更好。如果樣本集的分布足夠好,能足夠表徵所有潛在樣本的特徵,那麼模型在測試集上的准確率越高越好。
驗證集是訓練集和測試集之間的一個中間件。根據前面的定義,我們發現了一個問題,如果只有訓練集和測試集,是無法在測試集之前對模型進行評價的。實際上我們更希望在最終模型確定之前,可以先對模型進行一定的評價,然後根據評價結果調整模型參數(特別是超參數),直到我們認為模型已經不錯了,最後再用測試集進行測試,測試就只為了查看模型的近似泛化性能,不再繼續更新模型參數。正是為了這個目的,才劃分出了一個驗證集。可見, 驗證集一定程度上還是訓練集,因為會根據驗證集的結果調整模型參數 。
有了驗證集,整個過程就變成了下面這樣:先確定一組超參數,然後在訓練集上訓練,再用驗證集進行檢驗,如果效果不好,則繼續調整超參數,重新在訓練集上訓練,如此循環,直到模型在驗證集上表現良好。 到這一步,相當於我們已經基本找到了最優的超參數,接下去可以將這組超參數對應的模型參數作為最終模型參數,也可以利用這組超參數在「訓練集+驗證集」上重新訓練一遍,得到的結果作為最終模型參數 。最後用測試集檢驗最終模型參數的泛化效果,好與不好都不再單純地調整模型參數了。
最簡單的樣本集劃分就是只有訓練集和測試集,而沒有驗證集。這種情況實際上前面已經說過,他無法利用驗證集反過來對模型參數進行調整。只能確定一組超參數,然後訓練得到訓練參數,這個就算是最終結果了,然後利用測試集檢驗一下泛化效果就算結束了。或者更復雜點的做法,先確定幾組超參數,然後分別在訓練集上訓練得到不同訓練參數,最後利用測試集分別進行測試,最後根據測試結果選擇認為最好的那組作為最終模型參數。如下圖所示:
當然,不地道的做法,也可以一定程度上利用測試集的結果反過來調整模型參數,但不能過度,否則極容易過擬合。
將樣本集劃分為訓練集、驗證集和測試集,比例通常為8:1:1或6:2:2。這種情況比第一種要好,他多了一個驗證集,至少讓你可以根據驗證集來不斷調整模型參數了。
先確定一組超參數,在訓練集上得到訓練參數,然後在驗證集上得到驗證結果,根據驗證結果反過來修改超參數,繼續在訓練集上訓練,然後再驗證……如此循環直到你認為訓練結果在驗證集上表現良好為止。到這一步,我們僅僅只是找到了相對最優的超參數,其對應的訓練參數通常還不能作為最後參數。 還需要根據獲得的最優超參數在「訓練集+驗證集」上整體做訓練得到最終結果 ,最後將該「最優超參數+最終訓練參數」在測試集上做測試(不再訓練),結束整個過程。如下圖所示,其中曲線圖展示了不斷嘗試不同的超參數,最終確定最優超參數C0的過程(注意,這里的最優超參數C0隻是當前訓練集和驗證集劃分情況下的最優,但這並不代表它是整個樣本集真正的最優超參數,詳見「單一劃分的缺陷」章節):
上述兩種方式都有一個問題。
我們知道把一個樣本集劃分成訓練集、(驗證集)、測試集,由於每個樣本可能不同,即使劃分子集的樣本數每次相同,最終的劃分結果也不同。
事實證明, 在樣本集規模較小的情況下,對於不同的子集劃分,即使是完全相同的超參數,其最終的訓練和測試結果也會出現很大波動 。如下圖所示,同一個樣本集,訓練集和驗證集劃分不同(測試集用同一個),得到的最優超參數就不同,對應的誤差曲線差異也很大。
出現上述情況的本質原因是樣本集分布不夠充分,導致劃分後的子集更不充分,每一種劃分都出現較大波動,自然訓練和測試的結果也會波動較大;如果樣本集足夠大足夠充分(足夠表徵全局特徵),那麼無論劃分情況怎麼變化,子集很大程度上也都足夠充分,訓練和測試出來的結果也就是全局結果,最優超參數和誤差曲線也不會變化太大 。
前面已經說過,對於樣本數量不大,樣本分布不充分的樣本集而言,單一驗證方法會因為樣本集分割變化而導致最終的訓練和測試結果出現比較嚴重的動盪。
針對這種情況,很自然地想到,可以對訓練集做K次分割(K折交叉驗證),然後用同一組超參數對應訓練K個模型,並在同一組測試集上測試,取最終的平均准確率作為該組超參數的最終測試結果;
然後選下一組超參數重復上述過程,這樣我們就獲得了不同超參數各自的平均准確率;
選擇平均准確率最高的超參數作為最終超參數;
將最終超參數在「原訓練集+驗證集」上整體做訓練得到最終結果;
最後將該「最終超參數+最終訓練參數」在測試集上做測試(不再訓練),結束整個過程。
上述過程可以用下圖表示:
交叉驗證使最終在測試集上的准確率更加可信,一定程度上擺脫了因為單一樣本劃分帶來的分布不均衡問題;
交叉驗證使訓練集樣本既做了訓練集又做了驗證集,因此,一定程度上利用了更多的樣本信息;
用於調節超參數;用於選擇不同模型;用於選擇不同樣本參數。
K折交叉驗證的過程就是上圖所示,不再贅述。
關於K的選擇需要說明:
當 K=1 時,即所有訓練樣本都作為訓練樣本,這種情況相當於沒有交叉驗證,跟只有訓練集和測試集的情況一樣;
當 K=N 時(N是訓練集的樣本總數,不包括測試集),即每次只留1個樣本作為驗證集,N-1個作為訓練集,這種方法稱為留一法(LOOCV,Leave-one-out cross-validation);
LOOCV的優點:首先它不受訓訓練集和驗證集劃分(這里指將大訓練集劃分為訓練集和驗證集)的影響,因為每一個樣本都單獨的做過驗證集,同時,其用了N-1個樣本訓練模型,幾乎用到了所有樣本信息。
LOOCV優點:計算量過大。
當 1<K<N 時,K選取實際上是偏差(bias)和方差(variance)的一個折中(trade off)。K越大,每次投入的訓練樣本越多,模型的Bias越小。但K越大,也意味著每次選取的訓練樣本的相關性越大(或者重疊性越大)(考慮最極端的例子,當K=N,也就是在LOOCV里,每次的訓練樣本幾乎是一樣的),而這種大相關性會導致最終的test error具有更大的Variance;K越小,偏差越大,方差越小。
一般來說,根據經驗我們一般選擇K=5或10。
下圖展示了LOOCV和10折交叉驗證的對比結果:
藍色線表示真實的測試誤差曲線;
黑色線表示LOOCV方法測試誤差曲線;
橙色線表示10折交叉驗證測試誤差曲線;
可見LOOCV和10折交叉驗證結果是很相似的,但是相比LOOCV,10折交叉驗證的計算成本卻小了很多 。
1.需要注意的是,交叉驗證只是對訓練集的進一步有效利用,最終還是要通過未使用過的數據(單獨劃分出測試集)來檢驗它的泛化能力;
2.我們首先要在樣本集上留出一直不變的測試集,然後將剩餘部分作為大測試集,然後在該的測試集上做K折交叉驗證;
3.當訓練集樣本只有幾十、幾百或幾千時,最好用交叉驗證來保證利用盡量多的樣本信息;
4.其他交叉驗證方法:多次K折交叉驗證(Repeated K-Fold Cross Validation)、蒙特卡洛交叉驗證(Monte Carlo Cross Validation)
https://zhuanlan.hu.com/p/257808534
https://zhuanlan.hu.com/p/32627500
https://blog.csdn.net/yawei_liu1688/article/details/79138202
https://blog.csdn.net/qq_39751437/article/details/85071395
https://zhuanlan.hu.com/p/24825503?refer=rdatamining
https://www.cnblogs.com/wangkundentisy/p/8968316.html
https://blog.csdn.net/sysstc/article/details/103567520?utm_medium=distribute.pc_relevant.none-task-blog-2 default js_landingword~default-0.pc_relevant_default&spm=1001.2101.3001.4242.1&utm_relevant_index=3
https://tanxg.blog.csdn.net/article/details/109280753?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2 default BlogCommendFromBai Rate-6.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2 default BlogCommendFromBai Rate-6.pc_relevant_default&utm_relevant_index=11
㈧ 交叉驗證
交叉驗證是在機器學習建立模型和驗證模型參數時常用的辦法。交叉驗證就是重復使用數據,把得到的樣本數據進行切分,組合為不同的訓練集和測試集,用訓練集來訓練模型,用測試集來評估模型預測的好壞。在此基礎上可以得到多組不同的訓練和測試集,某次訓練集中的某樣本在下次可能成為測試集中的樣本,即所謂「交叉」。
交叉驗證用在數據不是很充足的時候。比如,在日常項目中,對於普通適中問題,如果數據樣本量小於一萬條,我們就會採用交叉驗證來訓練優化選擇模型。如果樣本大於一萬條的話,一般隨機的把數據分成三份,一份為訓練集(Training Set),一份為驗證集(Validation Set),最後一份為測試集(Test Set)。用訓練集來訓練模型,用驗證集來評估模型預測的好壞和選擇模型及其對應的參數。把最終得到的模型再用於測試集,最終決定使用哪個模型以及對應參數。
根據切分的方法不同,交叉驗證分為下面三種:
第一種,簡單交叉驗證。首先,隨機的將樣本數據分為兩部分(比如:70%的訓練集,30%的測試集),然後用訓練集來訓練模型,在測試集上驗證模型及參數。接著,我們再把樣本打亂,重新選擇訓練集合測試集,繼續訓練數據和檢驗模型。最後我們選擇損失函數評估最優的模型和參數。
第二種是S折交叉驗證(S-Folder Cross Validation)。和第一種方法不同,S折交叉驗證會把樣本數據隨機的分成S份,每次隨機的選擇S-1份作為訓練集,剩下的1份做測試集。當這一輪完成後,重新隨機選擇S-1份來訓練數據。若干輪(小於S)之後,選擇損失函數評估最優的模型和參數。
留一交叉驗證(Leave-one-out Cross Validation),它是第二種情況的特例,此時S等於樣本數N,這樣對於N個樣本,每次選擇N-1個樣本來訓練數據,留一個樣本來驗證模型預測的好壞。此方法主要用於樣本量非常少的情況,比如對於普通適中問題,N小於50時,一般採用留一交叉驗證。
通過反復的交叉驗證,用損失函數來度量得到的模型的好壞,最終可以得到一個較好的模型。
此外還有一種比較特殊的交叉驗證方式,也是用於樣本量少的時候,叫做自助法啊(bootstrapping)。比如有m個樣本(m較小),每次在這m個樣本中隨機採集一個樣本,放入訓練集,采樣完後把樣本放回。這樣重復採集n次,我們得到m個樣本組成的訓練集。當然,這m個樣本中很有可能有重復的樣本數據。同時,用沒有被采樣到的樣本做測試集,這樣接著進行交叉驗證。由於我們的訓練集有重復數據,這會改變數據的分布,因而訓練結果會有估計偏差,因此,此種方法不是很常用,除非數據量很少,比如小於20個。
將拿到的數據,分為訓練和驗證集。以下圖為例:將數據分成5份,其中一份作為驗證集。然後經過5次(組)的測試,每次都更換不同的驗證集。即得到5組模型的結果,取平均值作為最終結果,又稱5折交叉驗證。
㈨ Pytorch_循環神經網路RNN
RNN是Recurrent Neural Networks的縮寫,即循環神經網路,它常用於解決序列問題。RNN有記憶功能,除了當前輸入,還把上下文環境作為預測的依據。它常用於語音識別、翻譯等場景之中。
RNN是序列模型的基礎,盡管能夠直接調用現成的RNN演算法,但後續的復雜網路很多構建在RNN網路的基礎之上,如Attention方法需要使用RNN的隱藏層數據。RNN的原理並不復雜,但由於其中包括循環,很難用語言或者畫圖來描述,最好的方法是自己手動編寫一個RNN網路。本篇將介紹RNN網路的原理及具體實現。
在學習循環神經網路之前,先看看什麼是序列。序列sequence簡稱seq,是有先後順序的一組數據。自然語言處理是最為典型的序列問題,比如將一句話翻譯成另一句話時,其中某個詞彙的含義不僅取決於它本身,還與它前後的多個單詞相關。類似的,如果想預測電影的情節發展,不僅與當前的畫面有關,還與當前的一系列前情有關。在使用序列模型預測的過程中,輸入是序列,而輸出是一個或多個預測值。
在使用深度學習模型解決序列問題時, 最容易混淆的是,序列與序列中的元素 。在不同的場景中,定義序列的方式不同,當分析單詞的感情色彩時,一個單詞是一個序列seq;當分析句子感情色彩時,一個句子是一個seq,其中的每個單詞是序列中的元素;當分析文章感情色彩時,一篇文章是一個seq。簡單地說,seq是最終使用模型時的輸入數據,由一系列元素組成。
當分析句子的感情色彩時,以句為seq,而句中包含的各個單詞的含義,以及單詞間的關系是具體分析的對象,此時,單詞是序列中的元素,每一個單詞又可有多維特徵。從單詞中提取特徵的方法將在後面的自然語言處理中介紹。
RNN有很多種形式,單個輸入單個輸入;多個輸入多個輸出,單個輸入多個輸出等等。
舉個最簡單的例子:用模型預測一個四字短語的感情色彩,它的輸入為四個元素X={x1,x2,x3,x4},它的輸出為單個值Y={y1}。字的排列順序至關重要,比如「從好變壞」和「從壞變好」,表達的意思完全相反。之所以輸入輸出的個數不需要一一對應,是因為中間的隱藏層,變向存儲中間信息。
如果把模型設想成黑盒,如下圖所示:
如果模型使用全連接網路,在每次迭代時,模型將計算各個元素x1,x2...中各個特徵f1,f2...代入網路,求它們對結果y的貢獻度。
RNN網路則要復雜一些,在模型內部,它不是將序列中所有元素的特徵一次性輸入模型,而是每一次將序列中單個元素的特徵輸入模型,下圖描述了RNN的數據處理過程,左圖為分步展示,右圖將所有時序步驟抽象成單一模塊。
第一步:將第一個元素x1的特徵f1,f2...輸入模型,模型根據輸入計算出隱藏層h。
第二步:將第二個元素x2的特徵輸入模型,模型根據輸入和上一步產生的h再計算隱藏層h,其它元素以此類推。
第三步:將最後一個元素xn的特徵輸入模型,模型根據輸入和上一步產生的h計算隱藏層h和預測值y。
隱藏層h可視為將序列中前面元素的特徵和位置通過編碼向前傳遞,從而對輸出y發生作用,隱藏層的大小決定了模型攜帶信息量的多少。隱藏層也可以作為模型的輸入從外部傳入,以及作為模型的輸出返回給外部調用。
本例仍使用上篇中的航空乘客序列數據,分別用兩種方法實現RNN:自己編寫程序實現RNN模型,以及調用Pytorch提供的RNN模型。前一種方法主要用於剖析原理,後一種用於展示常用的調用方法。
首先導入頭文件,讀取乘客數據,做歸一化處理,並將數據切分為測試集和訓練集,與之前不同的是加入了create_dataset函數,用於生成序列數據,序列的輸入部分,每個元素中包括兩個特徵:前一個月的乘客量prev和月份值mon,這里的月份值並不是關鍵特徵,主要用於在常式中展示如何使用多個特徵。
第一步:實現模型類,此例中的RNN模型除了全連接層,還生成了一個隱藏層,並在下一次前向傳播時將隱藏層輸出的數據與輸入數據組合後再代入模型運算。
第二步,訓練模型,使用全部數據訓練500次,在每次訓練時,內部for循環將序列中的每個元素代入模型,並將模型輸出的隱藏層和下一個元素一起送入下一次迭代。
第三步:預測和作圖,預測的過程與訓練一樣,把全部數據拆分成元素代入模型,並將每一次預測結果存儲在數組中,並作圖顯示。
需要注意的是,在訓練和預測過程中,每一次開始輸入新序列之前,都重置了隱藏層,這是由於隱藏層的內容只與當前序列相關,序列之間並無連續性。
程序輸出結果如下圖所示:
經過500次迭代,使用RNN的效果明顯優於上一篇中使用全連接網路的擬合效果,還可以通過調整超參數以及選擇不同特徵,進一步優化。
使用Pytorch提供的RNN模型,torch.nn.RNN類可直接使用,是循環網路最常用的解決方案。RNN,LSTM,GRU等循環網路都實現在同一源碼文件torch/nn/moles/rnn.py中。
第一步:創建模型,模型包含兩部分,第一部分是Pytorch提供的RNN層,第二部分是一個全連接層,用於將RNN的輸出轉換成輸出目標的維度。
Pytorch的RNN前向傳播允許將隱藏層數據h作為參數傳入模型,並將模型產生的h和y作為函數返回值。形如: pred, h_state = model(x, h_state)
什麼情況下需要接收隱藏層的狀態h_state,並轉入下一次迭代呢?當處理單個seq時,h在內部前向傳遞;當序列與序列之間也存在前後依賴關系時,可以接收h_state並傳入下一步迭代。另外,當模型比較復雜如LSTM模型包含眾多參數,傳遞會增加模型的復雜度,使訓練過程變慢。本例未將隱藏層轉到模型外部,這是由於模型內部實現了對整個序列的處理,而非處理單個元素,而每次代入的序列之間又沒有連續性。
第二步:訓練模型,與上例中把序列中的元素逐個代入模型不同,本例一次性把整個序列代入了模型,因此,只有一個for循環。
Pythorch支持批量處理,前向傳遞時輸入數據格式是[seq_len, batch_size, input_dim),本例中輸入數據的維度是[100, 1, 2],input_dim是每個元素的特徵數,batch_size是訓練的序列個數,seq_len是序列的長度,這里使用70%作為訓練數據,seq_len為100。如果數據維度的順序與要求不一致,一般使用transpose轉換。
第三步:預測和作圖,將全部數據作為序列代入模型,並用預測值作圖。
程序輸出結果如下圖所示:
可以看到,經過500次迭代,在前100個元素的訓練集上擬合得很好,但在測試集效果較差,可能存在過擬合。
㈩ 什麼是交叉檢驗
交叉驗證(Cross-validation)主要用於建模應用中,例如PCR 、PLS 回歸建模中。在給定的建模樣本中,拿出大部分樣本進行建模型,留小部分樣本用剛建立的模型進行預報,並求這小部分樣本的預報誤差,記錄它們的平方加和。這個過程一直進行,直到所有的樣本都被預報了一次而且僅被預報一次。把每個樣本的預報誤差平方加和,稱為PRESS(predicted Error Sum of Squares)
用交叉驗證的目的是為了得到可靠穩定的模型。在建立PCR 或PLS 模型時,一個很重要的因素是取多少個主成分的問題。用cross validation 校驗每個主成分下的PRESS值,選擇PRESS值小的主成分數。或PRESS值不再變小時的主成分數。
常用的精度測試方法主要是交叉驗證,例如10折交叉驗證(10-fold cross validation),將數據集分成十份,輪流將其中9份做訓練1份做測試,10次的結果的均值作為對演算法精度的估計,一般還需要進行多次10折交叉驗證求均值,例如:10次10折交叉驗證,以求更精確一點