預(yù)測模型在各個(gè)領(lǐng)域都越來越火腿倚,今天的分享和之前的臨床預(yù)測模型背景上有些不同纯出,但方法思路上都是一樣的,多了解各個(gè)領(lǐng)域的方法應(yīng)用敷燎,視野才不會(huì)被局限暂筝。
今天試圖再用一個(gè)實(shí)例給到大家一個(gè)統(tǒng)一的預(yù)測模型的做法框架(R中同樣的操作可以有多種多樣的實(shí)現(xiàn)方法,框架統(tǒng)一尤其重要硬贯,不是簡單的我做出來就行)焕襟。而是要:
eliminate syntactical differences between many of the functions for building and predicting models
數(shù)據(jù)劃分
通常我們的數(shù)據(jù)是有限的,所以首先第一步就是決定如何使用我們的數(shù)據(jù)饭豹,就這一步來講都有很多流派鸵赖。
數(shù)據(jù)比較少的情況下务漩,一般還是將全部數(shù)據(jù)都拿來做訓(xùn)練,盡可能使得模型的代表性強(qiáng)一點(diǎn)它褪,但是隨之而來的問題就是沒有樣本外驗(yàn)證饵骨。上文寫機(jī)器學(xué)習(xí)的時(shí)候提到,樣本外驗(yàn)證是模型評(píng)估的重要一步茫打,所以一般還是會(huì)劃分?jǐn)?shù)據(jù)居触。個(gè)人意見:好多同學(xué)就200多個(gè)數(shù)據(jù),就別去劃分?jǐn)?shù)據(jù)集了老赤,全用吧轮洋,保證下模型效度。
我現(xiàn)在手上有數(shù)據(jù)如下:
[圖片上傳失敗...(image-59c252-1661865851360)]
這是一個(gè)有4335個(gè)觀測1579個(gè)變量的數(shù)據(jù)集抬旺,我現(xiàn)在要對(duì)其切分為訓(xùn)練集和測試集弊予,代碼如下:
inTrain <- createDataPartition(mutagen, p = 3/4, list = FALSE)
trainDescr <- descr[inTrain,]
testDescr <- descr[-inTrain,]
trainClass <- mutagen[inTrain]
testClass <- mutagen[-inTrain]
代碼的重點(diǎn)在createDataPartition,這個(gè)函數(shù)的p參數(shù)指的是訓(xùn)練集的比例开财,此處意味著75%的數(shù)據(jù)用來訓(xùn)練模型汉柒,剩下的25%的數(shù)據(jù)用來驗(yàn)證。使用這個(gè)函數(shù)的時(shí)候要注意一定是用結(jié)局作為劃分的依據(jù)床未,比如說我現(xiàn)在做一個(gè)死亡預(yù)測模型竭翠,一定要在生存狀態(tài)這個(gè)變量上進(jìn)行劃分,比如原來數(shù)據(jù)中死亡與否的占比是7:3薇搁,這樣我們能保證劃分出的訓(xùn)練集死亡與否的占比依然是7:3斋扰。
數(shù)據(jù)劃分中會(huì)有兩個(gè)常見的問題:一是zero-variance predictor的問題,二是multicollinearity的問題啃洋。
第一個(gè)問題指的是很多的變量只有一個(gè)取值传货,不提供信息,比如變量A可以取y和n宏娄,y占90%n占10%问裕,劃分?jǐn)?shù)據(jù)后訓(xùn)練集中有可能全是y,此時(shí)這個(gè)變量就沒法用了孵坚。為了避免這個(gè)問題我們首先應(yīng)該排除數(shù)據(jù)集中本身就是單一取值的變量粮宛,還有哪些本身比例失衡的變量,可以用到nearZeroVar函數(shù)找后進(jìn)行刪除卖宠。
第二個(gè)問題是共線性巍杈,解決方法一個(gè)是取主成分降維后重新跑,另一個(gè)是做相關(guān)扛伍,相關(guān)系數(shù)大于某個(gè)界值后刪掉筷畦,可以用到findCorrelation函數(shù)。
下面的代碼就實(shí)現(xiàn)了去除zero-variance predictor和相關(guān)系數(shù)大于0.9的變量:
isZV <- apply(trainDescr, 2, function(u) length(unique(u)) == 1)
trainDescr <- trainDescr[, !isZV]
testDescr <- testDescr[, !isZV]
descrCorr <- cor(trainDescr)
highCorr <- findCorrelation(descrCorr, 0.90)
trainDescr <- trainDescr[, -highCorr]
testDescr <- testDescr[, -highCorr]
ncol(trainDescr)
運(yùn)行上面的代碼之后我們的預(yù)測因子就從1575個(gè)降低到了640個(gè)刺洒。
接下來對(duì)于模型特定的預(yù)測算法鳖宾,比如partial least squares, neural networks and support vector machines吼砂,都是需要我們將數(shù)值型變量中心化或標(biāo)準(zhǔn)化的,這個(gè)時(shí)候我們需要對(duì)數(shù)據(jù)進(jìn)行預(yù)處理鼎文,需要用到preProcess函數(shù)渔肩,具體代碼如下:
xTrans <- preProcess(trainDescr)
trainDescr <- predict(xTrans, trainDescr)
testDescr <- predict(xTrans, testDescr)
在preProcess函數(shù)中,可以通過method參數(shù)很方便地對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行插補(bǔ)漂问,中心化赖瞒,標(biāo)準(zhǔn)化或者取主成分等等操作女揭,我愿稱其為最強(qiáng)數(shù)據(jù)預(yù)處理函數(shù)蚤假。
建模與調(diào)參
建模是用train函數(shù)進(jìn)行的,caret提供的預(yù)測模型建立的統(tǒng)一框架的精髓也在train函數(shù)中吧兔,我們想要用各種各樣的機(jī)器學(xué)習(xí)算法去做預(yù)測模型磷仰,就只需要在train中改動(dòng)method參數(shù)即可,并且我們能用的算法也非常多境蔼,列舉部分如下:
[圖片上傳失敗...(image-291968-1661865851360)]
另外一個(gè)值得注意的參數(shù)就是trControl灶平,這個(gè)參數(shù)可以用來設(shè)定交叉驗(yàn)證的方法:
trControl which specifies the resampling scheme, that is, how cross-validation should be performed to find the best values of the tuning parameters
[圖片上傳失敗...(image-1a4c50-1661865851360)]
比如我現(xiàn)在需要訓(xùn)練一個(gè)logistics模型(大家用的最多的),我就可以寫出如下代碼:
default_glm_mod = train(
form = default ~ .,
data = default_trn,
trControl = trainControl(method = "cv", number = 5),
method = "glm",
family = "binomial"
)
在上面的代碼中箍土,我們?cè)O(shè)定了4個(gè)重要的參數(shù):
一是模型公式form逢享,二是數(shù)據(jù)來源data,三是交叉驗(yàn)證方法吴藻,這兒我們使用的是5折交叉驗(yàn)證瞒爬,四是模型算法method。
我現(xiàn)在要訓(xùn)練一個(gè)支持向量機(jī)模型沟堡,代碼如下:
bootControl <- trainControl(number = 200)
svmFit <- train(
trainDescr, trainClass,
method = "svmRadial",
trControl = bootControl,
scaled = FALSE)
上面的代碼運(yùn)行需要一點(diǎn)時(shí)間侧但,我們是用自助抽樣法,抽樣迭代次數(shù)200次航罗,也就是抽200個(gè)數(shù)據(jù)集禀横,所以比較耗時(shí)。
支持向量機(jī)是有兩個(gè)超參的sigma和C粥血,上面的結(jié)果輸出中每一行代表一種超參組合柏锄,通過上圖我們可以看到不同的超參組合下模型的表現(xiàn)
[圖片上傳失敗...(image-469a05-1661865851359)]
其中有一致性系數(shù)Kappa,如果我們的結(jié)局是十分不平衡的复亏,這個(gè)Kappa就會(huì)是特別重要的評(píng)估模型表現(xiàn)的一個(gè)指標(biāo)
Kappa is an excellent performance measure when the classes are highly unbalanced
我們發(fā)現(xiàn)超參取0.00137和2趾娃,模型會(huì)表現(xiàn)得更好,這個(gè)也成為我們的finalmodel蜓耻。
預(yù)測新樣本
模型目前已經(jīng)訓(xùn)練好了茫舶,我們可以用訓(xùn)練好的最好的模型finalmodel來預(yù)測我們的測試集,進(jìn)而評(píng)估模型表現(xiàn)刹淌。預(yù)測新樣本的代碼如下:
predict(svmFit$finalModel, newdata = testDescr)
有時(shí)候我們會(huì)訓(xùn)練不同算法的多個(gè)模型饶氏,比如一個(gè)支持向量機(jī)模型讥耗,另外一個(gè)gbm模型,這個(gè)時(shí)候使用predict也可以方便的得到多個(gè)算法的預(yù)測結(jié)果疹启,只需要將模型放在一個(gè)list中即可古程。
另外還有extractProb和extractPrediction兩個(gè)函數(shù),extractPrediction可以很方便地從預(yù)測模型中提出預(yù)測值喊崖,extractProb可以提出預(yù)測概率挣磨。
評(píng)估模型表現(xiàn)
對(duì)于分類問題,我們可以用confusionMatrix很方便地得到下面的模型評(píng)估指標(biāo):
[圖片上傳失敗...(image-123ec7-1661865851359)]
還有要報(bào)告的ROC曲線:
svmROC <- roc(svmProb$mutagen, svmProb$obs)
[圖片上傳失敗...(image-c1debc-1661865851359)]
aucRoc則可以幫助我們快速地得到曲線下面積荤懂。
對(duì)于回歸問題茁裙,評(píng)估模型表現(xiàn)的時(shí)候就沒有所謂的accuracy and the Kappa statistic了,我們關(guān)心R2节仿,plotObsVsPred可以方便地畫出實(shí)際值和預(yù)測值的走勢晤锥,關(guān)心rmse和mae,calc_rmse函數(shù)可以幫助計(jì)算rmse廊宪,get_best_result函數(shù)可以輸出R方等指標(biāo)矾瘾。
預(yù)測因子選擇
預(yù)測因子的重要性作圖,有時(shí)候我們的數(shù)據(jù)變量很多箭启,或者叫維度很多壕翩,從而導(dǎo)致維度災(zāi)難,好多的預(yù)測因子其實(shí)并不能給模型提供信息傅寡,預(yù)測因子的選擇則是要在盡量使得模型精簡的情況下不損害模型的表現(xiàn)放妈。
varImp可以幫助我們查看各個(gè)預(yù)測因子對(duì)模型的貢獻(xiàn)重要性,并且這個(gè)重要性是以得分的形式給出的赏僧,分怎么計(jì)算的大猛,我也不知道。獲得各個(gè)預(yù)測因子重要性得分的代碼如下:
varImp(gbmFit, scale = FALSE)
[圖片上傳失敗...(image-6d4f87-1661865851359)]
更直觀的我們將該對(duì)象plot下淀零,就可以得到預(yù)測因子重要性的面條圖如下:
[圖片上傳失敗...(image-f9f0dc-1661865851359)]
上面的圖中只列出了重要性前20的變量挽绩,我們其實(shí)是有655個(gè)變量的,但是有200多個(gè)的重要性得分均為0驾中,所以跑模型的時(shí)候其實(shí)是可以完全不要它們的唉堪。
小結(jié)
今天給大家簡單介紹了在caret中做預(yù)測模型的一些知識(shí),感謝大家耐心看完肩民,自己的文章都寫的很細(xì)唠亚,重要代碼都在原文中,希望大家都可以自己做一做持痰,