編者按:保險(xiǎn)業(yè)數(shù)據(jù)科學(xué)家Alan Marazzi用R語言展示了基于決策樹的模型的強(qiáng)大和簡潔之處。
這是一篇基于決策樹的模型的簡明介紹,盡量使用非技術(shù)術(shù)語,同時(shí)也給出了模型的R語言實(shí)現(xiàn)。由于這篇文章已經(jīng)夠長了,因此我們省略了一些代碼。不過別擔(dān)心,你可以在配套的GitHub倉庫中找到完整代碼:https://github.com/alanmarazzi/trees-forest
為何基于決策樹的模型經(jīng)久不衰
決策樹是一組通常用于分類的機(jī)器學(xué)習(xí)算法。因?yàn)樗鼈兒唵斡行?,所以也是初學(xué)者首先學(xué)習(xí)的算法之一。你大概很難在最新的機(jī)器學(xué)習(xí)論文和研究上看到它們,但在真實(shí)世界項(xiàng)目中,基于決策樹的模型仍被廣泛使用。
之所以得到如此廣泛的使用,主要原因之一是它們的簡單性和可解釋性。下面是一棵預(yù)測天氣是否多云的簡單決策樹。
這一方法讓我們可以通過傳入數(shù)據(jù)預(yù)測某個(gè)變量,不過,大概更重要的是我們可以推斷預(yù)測因子之間的關(guān)系。這意味著我們可以從底部開始,看看哪些因素導(dǎo)致了多云。
比如,如果風(fēng)很小,看起來要下雨了,那說明是多云。對簡單模型而言,這些規(guī)則可以被人類所學(xué)習(xí)和應(yīng)用,或者我們可以生成一份清單以輔助決策過程。通過可視化決策樹,我們可以理解機(jī)器是如何工作的,為何將某些日子分類為多云,將另一些日子分類為非多云。
盡管這看起來挺微不足道的,但在許多情形下,我們需要知道模型為何做出某些預(yù)測??紤]一個(gè)預(yù)測是否接受胸痛患者的模型。在測試了許多高級模型之后,醫(yī)生想要搞清楚算法為什么讓某些處以危險(xiǎn)之中的患者回家。所以他們在數(shù)據(jù)上運(yùn)行了一個(gè)基于決策樹的模型,結(jié)果發(fā)現(xiàn)算法認(rèn)為患有哮喘的胸痛病人風(fēng)險(xiǎn)很小。
這是一個(gè)巨大的錯(cuò)誤。醫(yī)生非常清楚哮喘和胸痛必須立刻治療,這意味著哮喘和胸痛的病人會馬上得到收治。你發(fā)現(xiàn)問題所在了吧?用于建模的數(shù)據(jù)認(rèn)為這類病人風(fēng)險(xiǎn)很小,是因?yàn)樗羞@類病人都得到了治療,所以極少有人在此之后死亡。
何時(shí)使用基于決策樹的模型
如前所述,當(dāng)可解釋性很重要時(shí),決策樹非常好,即使它可能僅用于理解預(yù)測哪里出錯(cuò)了。實(shí)際上,基于決策樹的模型可以變得非常復(fù)雜,在損失可解釋性的同時(shí),增加準(zhǔn)確性。這里存在著一個(gè)權(quán)衡。
另一個(gè)使用決策樹的理由是它們非常容易理解和解釋。在有一些強(qiáng)預(yù)測因子的情形下,決策樹可以用來創(chuàng)建可以同時(shí)為機(jī)器和人類使用的模型。我剛想到的一個(gè)例子是預(yù)測顧客是否最終會購買某物的決策樹模型。
評測也是這些方法大放異彩之處:你很快會發(fā)現(xiàn),用于分類時(shí),即使是相當(dāng)簡單的基于決策樹的模型,也很難被大幅超過。我個(gè)人經(jīng)常在要處理的數(shù)據(jù)集上運(yùn)行隨機(jī)森林(后文會介紹這一算法),接著嘗試戰(zhàn)勝它。
R語言配置
在開始之前,你可能需要先配置一下R環(huán)境。
安裝如下包:
trees_packages <- c("FFTrees", ? ?"evtree", ? ?"party", ? ?"randomForest", ? ?"intubate", ? ?"dplyr")install.packages(trees_packages)
這些是在R語言中使用基于決策樹的模型和數(shù)據(jù)處理的主要包,但它們不是唯一的。任何你打算使用的基于決策樹的模型,幾乎都有幾十個(gè)包可以用,不信的話可以上Crantastic搜索一番。
現(xiàn)在是植樹時(shí)刻!我決定使用Titanic數(shù)據(jù)集,機(jī)器學(xué)習(xí)社區(qū)最著名的數(shù)據(jù)集之一。你可以從Kaggle(c/titanic)或GitHub(alanmarazzi/trees-forest)獲取這一數(shù)據(jù)集。我將直接從清洗數(shù)據(jù)和建模開始講起,如果你在數(shù)據(jù)下載、加載上需要幫助,或者缺乏頭緒,可以參考我之前的文章Data Science in Minutes或者GitHub倉庫中的完整代碼。
預(yù)備數(shù)據(jù)
首先,我們看下要處理的數(shù)據(jù)是什么樣子的:
我真心不喜歡有大寫字母姓名的數(shù)據(jù)集,很幸運(yùn),我們可以用tolower()函數(shù),一行代碼轉(zhuǎn)換為小寫字母:
names(titanic) <- tolower(names(titanic))
接著,將sex和embarked變量轉(zhuǎn)換為因子(類別變量):
titanic$sex <- as.factor(titanic$sex)titanic$embarked <- as.factor(titanic$embarked)
建模時(shí)最重要的步驟之一是處理缺失值(NA)。許多R模型可以自動(dòng)處理缺失值,但大多數(shù)只不過是直接移除包含缺失值的觀測。這意味著可供模型學(xué)習(xí)的訓(xùn)練數(shù)據(jù)變少了,這幾乎一定會導(dǎo)致準(zhǔn)確率下降。
有各種填充NA的技術(shù):填充均值、中位數(shù)、眾數(shù),或使用一個(gè)模型預(yù)測它們的值。我們的例子將使用線性回歸替換數(shù)據(jù)集中年齡變量的缺失值。
乍看起來這個(gè)想法有點(diǎn)嚇人,有點(diǎn)怪異,你可能會想:“你說的是,為了改進(jìn)我的模型,我應(yīng)該使用另一個(gè)模型?!”但其實(shí)并沒有看起來這么難,特別是如果我們使用線性回歸的話。
首先讓我們看下年齡變量中有多少NA:
mean(is.na(titanic$age))[1] 0.1986532
將近20%的乘客沒有年齡記錄,這意味著如果我們不替換缺失值,直接在數(shù)據(jù)集上運(yùn)行模型的話,我們的訓(xùn)練數(shù)據(jù)只有714項(xiàng),而不是891項(xiàng)。
是時(shí)候在數(shù)據(jù)上跑下線性回歸了:
age_prediction <- lm(age ~ survived + pclass + fare, data = titanic)summary(age_prediction)
我們干了什么?我們告訴R求解如下線性等式,找出恰當(dāng)?shù)摩?、βn的值。
age = α + β1?survived + β2?pclass + β3?fare
然后我們在創(chuàng)建的模型上調(diào)用summary()函數(shù),查看線性回歸的結(jié)果。R會給出一些統(tǒng)計(jì)數(shù)據(jù),我們需要查看這些數(shù)據(jù)以了解數(shù)據(jù)的情況:
Call:lm(formula = age ~ survived + pclass + fare, data = titanic)Residuals: Min 1Q Median 3Q Max -37.457 -8.523 -1.128 8.060 47.505 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 54.14124 2.04430 26.484 < 2e-16 ***survived ? ?-6.81709 ? ?1.06801 ?-6.383 3.14e-10 ***pclass ? ? ?-9.12040 ? ?0.72469 -12.585 ?< 2e-16 ***fare ? ? ? ?-0.03671 ? ?0.01112 ?-3.302 ?0.00101 ** ---Signif. codes: ?0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1Residual standard error: 13.03 on 710 degrees of freedom ?(177 observations deleted due to missingness)Multiple R-squared: ?0.1993, ? ?Adjusted R-squared: ?0.1959 F-statistic: ?58.9 on 3 and 710 DF, ?p-value: < 2.2e-16
上面第一行(Call)提示我們是哪個(gè)模型產(chǎn)生了這一結(jié)果,第二行顯示了殘差,之后是系數(shù)。這里我們可以查看系數(shù)的估計(jì)值,它們的標(biāo)準(zhǔn)差,t值和p值。之后是一些其他統(tǒng)計(jì)數(shù)據(jù)。我們看到R實(shí)際上移除了含NA的數(shù)據(jù)(177 observations deleted due to missingness)。
現(xiàn)在我們可以使用這個(gè)模型來填充NA了。我們使用predict()函數(shù):
titanic$age[is.na(titanic$age)] <- predict(age_prediction, ? ?newdata = titanic[is.na(titanic$age),])
邏輯回歸基準(zhǔn)
是否幸存這樣的二元分類問題,邏輯回歸很難戰(zhàn)勝。我們將使用邏輯回歸預(yù)測泰坦尼克幸存者,并將這一結(jié)果作為基準(zhǔn)。
別擔(dān)心,在R中進(jìn)行邏輯回歸非常直截了當(dāng)。我們引入dplyr和intubate庫,然后調(diào)用glm()函數(shù)運(yùn)行邏輯回歸。glm()接受三個(gè)參數(shù),predictors為預(yù)測因子,例如年齡、艙等,response為結(jié)果變量,這里我們傳入survived,family指定返回結(jié)果的類別,這里我們傳入binomial。
library(dplyr) # 數(shù)據(jù)處理library(intubate) # 建模工作流# btbt_glb是 %>% 版本的glm函數(shù)logi <- titanic %>% select(survived, pclass, sex, age, sibsp) %>% ntbt_glm(survived ~ ., family = binomial)summary(logi)
下面讓我們查看下邏輯回歸模型做出的預(yù)測:
# 收集訓(xùn)練數(shù)據(jù)上的預(yù)測logi_pred <- predict(logi, type = "response")# 預(yù)測值在0和1之間,我們將其轉(zhuǎn)換為`survived`或`not`survivors_logi <- rep(0, nrow(titanic))survivors_logi[logi_pred > .5] <- 1# 這將成為我們的基準(zhǔn)table(model = survivors_logi, real = titanic$survived)
上面的混淆矩陣給出了模型在訓(xùn)練數(shù)據(jù)上的結(jié)果:預(yù)測572人死亡(0),319人幸存(1)。矩陣的對角線表明,480項(xiàng)和250項(xiàng)預(yù)測正確,而預(yù)測死亡的92人實(shí)際上幸存了,預(yù)測幸存的69人實(shí)際上未能幸存。
對這樣開箱即用的模型而言,82%的預(yù)測精確度已經(jīng)相當(dāng)不錯(cuò)了。但是我們想在未見數(shù)據(jù)上測試一下,所以讓我們載入測試集,試下模型在測試集上的效果。
test <- read.csv(paste0("https://raw.githubusercontent.com/", ? ?"alanmarazzi/trees-forest/master/data/test.csv"), ? ?stringsAsFactors = FALSE, ? ?na.strings = "")# 和訓(xùn)練集一樣,清洗下數(shù)據(jù)names(test) <- tolower(names(test))test$sex <- as.factor(test$sex)
下面在測試數(shù)據(jù)上預(yù)測幸存率:
test_logi_pred <- predict(logi, test, type = "response")surv_test_logi <- data.frame(PassengerId = test$passengerid, ? ?Survived = rep(0, nrow(test)))surv_test_logi$Survived[test_logi_pred > .5] <- 1write.csv(surv_test_logi, "results/logi.csv", row.names = FALSE)
我們將結(jié)果保存為csv,因?yàn)闇y試數(shù)據(jù)沒有標(biāo)簽,我們并不知道預(yù)測是否正確。我們需要將結(jié)果上傳到Kaggle以查看結(jié)果。最終模型做出了77.5%的正確預(yù)測。
快速和低成本決策樹
終于可以開始植樹了!我們將嘗試的第一個(gè)模型是快速和低成本決策樹。這基本上是最簡單的模型。我們將使用R的FFTrees包。
# 臨時(shí)復(fù)制下數(shù)據(jù)集,因?yàn)镕FTrees包里也包含titanic變量titanicc <- titaniclibrary(FFTrees)titanic <- titaniccrm(titanicc)
載入包,我們只需在選中的變量上應(yīng)用FFTrees。
fftitanic <- titanic %>% select(age, pclass, sex, sibsp, fare, survived) %>% ntbt(FFTrees, survived ~ .)
模型需要跑一會兒,因?yàn)橐?xùn)練和測試不止一棵FFTree。最終得到的結(jié)果是一個(gè)FFTree對象,包含了所有測試過的FFTree:
fftitanic[1] "An FFTrees object containing 8 trees using 4 predictors {sex,pclass,fare,age}"[1] "FFTrees AUC: (Train = 0.84, Test = --)"[1] "My favorite training tree is #5, here is how it performed:" trainn 891.00p(Correct) 0.79Hit Rate (HR) 0.70False Alarm Rate (FAR) 0.16d-prime 1.52
我們看到,算法使用最多4個(gè)預(yù)測因子測試了8棵樹,表現(xiàn)最佳的是5號樹。接著我們看到了這棵樹的一些統(tǒng)計(jì)數(shù)據(jù)。這些輸出很有幫助,但可視化方法能夠更好地幫助我們理解發(fā)生了什么:
plot(fftitanic, main = "Titanic", decision.names = c("Not Survived", "Survived"))
這一張圖中有大量信息,從上往下依次為:觀測數(shù)目、分類數(shù)目、決策樹、診斷數(shù)據(jù)。讓我們重點(diǎn)關(guān)注決策樹。
決策樹的第一個(gè)節(jié)點(diǎn)考慮sex變量:如果是女性(sex != male),我們將直接退出決策樹,預(yù)測幸存。粗暴,但相當(dāng)有效。如果是男性,將通過第二個(gè)節(jié)點(diǎn)pclass。這里,如果是三等艙,我們將退出決策樹,預(yù)測死亡。接著,如果船費(fèi)超過£ 26.96(fare),預(yù)測幸存。最后一個(gè)節(jié)點(diǎn)考慮的是age(年齡):如果年齡大于21.35歲,預(yù)測死亡。
在圖表的Performance(表現(xiàn))區(qū)域,我們最關(guān)心左側(cè)的混淆矩陣,我們可以對比之前邏輯回歸得到的混淆矩陣。
此外,我們也可以查看下右側(cè)的ROC曲線。FFTrees包在數(shù)據(jù)上自動(dòng)運(yùn)行邏輯回歸和CART(另一種基于決策樹的模型),以供比較。仔細(xì)看圖,我們看到,代表邏輯回歸的圓圈基本上完全被5號樹的圓圈蓋住了,意味著這兩個(gè)模型表現(xiàn)相當(dāng)。
現(xiàn)在我們分類測試數(shù)據(jù),并提交結(jié)果至Kaggle。如同我之前說過的那樣,這些決策樹極為簡單。我上面解釋決策樹如何工作時(shí),解釋每一個(gè)節(jié)點(diǎn)的句子中都有“如果”,這意味著我們可以依照同樣的結(jié)構(gòu)創(chuàng)建一個(gè)基于清單的分類器,或者,我們甚至可以記住這些規(guī)則,然后手工分類。
ffpred <- ifelse(test$sex != "male", 1, ? ? ? ? ? ? ? ? ifelse(test$pclass > 2, 0, ifelse(test$fare < 26.96, 0, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ifelse(test$age >= 21.36, 0, 1))))ffpred[is.na(ffpred)] <- 0
只需4個(gè)嵌套的ifelse語句,我們就可以分類整個(gè)數(shù)據(jù)集。我們只有2個(gè)NA,所以我決定將它們分類為“未幸存”。接著我們只需將csv格式的結(jié)果上傳到Kaggle,看看模型表現(xiàn)如何。
我們的4個(gè)if-else語句表現(xiàn)只比基準(zhǔn)差了1%. 考慮到模型的簡單性,這是非常出色的成績。
聚會時(shí)分
party包使用條件推理樹,比FFTrees更復(fù)雜的決策樹。簡單來說,條件推理樹在決定分割節(jié)點(diǎn)時(shí),不僅考慮重要性,還考慮數(shù)據(jù)分布。雖然條件推理樹更復(fù)雜,但使用起來很簡單,加載包后只需使用ctree函數(shù)即可創(chuàng)建決策樹。
library(party)partyTitanic <- titanic %>% select(age, pclass, sex, sibsp, fare, survived) %>% ntbt(ctree, as.factor(survived) ~ .)
運(yùn)行模型后,我們可以調(diào)用這個(gè)包的繪圖函數(shù)可視化得到的決策樹,plot(ctree_relust)。這里我們不在乎其他花里胡哨的東西,只在意最終得到的決策樹。所以會使用一些可選參數(shù)讓輸出整潔一點(diǎn)。
plot(partyTitanic, main = "Titanic prediction", type = "simple", inner_panel = node_inner(partyTitanic, pval = FALSE), terminal_panel = node_terminal(partyTitanic, abbreviate = TRUE, digits = 1, fill = "white"))
不幸的是較大的樹占用更多空間,如果再加上一些節(jié)點(diǎn),圖就基本上看不清了。將這棵樹和上面那棵FFTree比較一下,我們看到現(xiàn)在這棵樹更復(fù)雜:之前我們直接預(yù)測每個(gè)男性死亡,現(xiàn)在這個(gè)模型嘗試將男性分為多種情況。
增加的復(fù)雜性降低了15%的訓(xùn)練誤差。和上面的FFTree相比,這是一項(xiàng)改進(jìn)。
train_party <- Predict(partyTitanic)table(tree = train_party, real = titanic$survived)
不過,很遺憾,我們下面將學(xué)到機(jī)器學(xué)習(xí)最重要的一課。事實(shí)上,在測試集上的分類正確率只有73.7%!
你也許會問,這怎么可能?我們剛看到的是過擬合現(xiàn)象。模型考慮的一些變量最終看來其實(shí)是噪聲。結(jié)果在訓(xùn)練集上改善了,但在未見數(shù)據(jù)上的表現(xiàn)變差了。有多種應(yīng)對這一問題的方式,比如剪枝。剪枝的意思是削減分支,比如通過降低樹的最大深度達(dá)成。剪枝搭配交叉驗(yàn)證,很可能改善測試數(shù)據(jù)上的結(jié)果。
集成模型
目前為止,我們開發(fā)的都是單個(gè)學(xué)習(xí)者,意味著我們通過一個(gè)模型找到解決方案。另一系列的機(jī)器學(xué)習(xí)算法是集成,通過許多所謂的弱小學(xué)習(xí)者創(chuàng)建的模型。背后的理論是通過使用許多學(xué)習(xí)者(在我們的例子中是決策樹),結(jié)合他們的選擇,我們能得到良好的結(jié)果。
集成模型因模型創(chuàng)建方法、組合結(jié)果方式的不同而不同??赡芸雌饋碛悬c(diǎn)雜亂,但部分集成方法通常是開箱即用的,是一個(gè)很好的優(yōu)化結(jié)果的選擇。
集成的目的是為了減少方差。比如,我們上面在訓(xùn)練集上得到了良好的結(jié)果,但在測試集上的誤差率卻很大。如果我們有不同的訓(xùn)練集,不同的模型,那么各自會有不同的偏差,集成之后就能得到更好的結(jié)果。
我們將查看三種不同的集成算法:Bagging、隨機(jī)森林、Boosting。
Bagging
bagging的主要思路相當(dāng)簡單:如果我們在不同的訓(xùn)練集上訓(xùn)練許多較大的決策樹,我們將得到許多高方差、低偏差的模型。平均每棵樹的預(yù)測,我們就能得到方差和偏差相對較低的分類。
你可能已經(jīng)發(fā)現(xiàn)一個(gè)問題,我們并沒有許多訓(xùn)練集。為了應(yīng)對這一問題,我們通過bootstrap方法創(chuàng)建這些訓(xùn)練集。bootstrap不過是一種有放回的重復(fù)取樣方法。
x <- rnorm(100) # 生成隨機(jī)向量# 定義固定取樣函數(shù)boot_x <- function(x, size) { ? ?sample(x, size, replace = TRUE)}# 循環(huán)取樣,直到取滿需要的樣本bootstrapping <- function(x, reps, size) { ? ?y <- list() ? ?for (i in seq_len(reps)) { ? ? ? ?y[[i]] <- boot_x(x, size) ? ?} ? ?y}# 結(jié)果是一個(gè)列表z <- bootstrapping(x, 500, 20)
為了在泰坦尼克數(shù)據(jù)上運(yùn)行bagging,我們可以使用randomForest包。這是因?yàn)閎agging和隨機(jī)森林差不多,唯一的區(qū)別是在創(chuàng)建決策樹時(shí)考慮多少預(yù)測因子。bagging中,我們考慮數(shù)據(jù)集中的每個(gè)預(yù)測因子,我們可以通過設(shè)置mtry參數(shù)做到這一點(diǎn)。
library(randomForest)# 如果你希望重現(xiàn)結(jié)果,別忘了設(shè)置一樣的隨機(jī)數(shù)種子set.seed(123)# 創(chuàng)建bagging模型titanic_bag <- titanic %>% select(survived, age, pclass, sex, sibsp, fare, parch) %>% ntbt_randomForest(as.factor(survived) ~ ., mtry = 6)
注意,這里我們將survived作為因子(as.factor)傳入,這樣就可以使函數(shù)創(chuàng)建分類樹,而不是回歸樹(是的,決策樹同樣可以用于回歸)。
bagging默認(rèn)創(chuàng)建500棵樹,如果你想要增加更多樹,可以傳入ntree參數(shù),設(shè)定一個(gè)更高的數(shù)值。
上面的代碼有一個(gè)問題,直接跳過NA,不作預(yù)測。為了在避免進(jìn)一步特征工程的前提下,生成符合Kaggle要求的結(jié)果,我決定將測試集中的NA用中位數(shù)替換。不幸的是,這個(gè)問題限制了預(yù)測能力,結(jié)果是66.5%的正確預(yù)測率。
隨機(jī)森林
隨機(jī)森林是最著名的機(jī)器學(xué)習(xí)算法之一,原因是它開箱即用的效果好到?jīng)]道理。隨機(jī)森林幾乎和bagging一樣,只不過使用較弱的學(xué)習(xí)者,創(chuàng)建決策樹時(shí)只考慮有限數(shù)量的預(yù)測因子。
你可能會問使用全部預(yù)測因子和僅使用部分預(yù)測因子有什么區(qū)別。答案是使用所有預(yù)測因子時(shí),在不同的bootstrap取樣的數(shù)據(jù)集上創(chuàng)建決策樹時(shí),前兩個(gè)分割很可能是一樣的,因?yàn)閯?chuàng)建決策樹時(shí)考慮的是預(yù)測因子的重要性。所以使用bagging創(chuàng)建的500棵樹會很相似,相應(yīng)地,做出的預(yù)測也會很相似。
為了限制這一行為,我們使用隨機(jī)森林,通過mtry參數(shù)限制預(yù)測因子。我們使用交叉驗(yàn)證決定“最好”的參數(shù)值,或者嘗試一些經(jīng)驗(yàn)法則,比如ncol(data)/3和sqrt(ncol(data)),不過在這個(gè)例子中我將mtry參數(shù)值定為3.
我建議你試驗(yàn)不同的值,然后查看發(fā)生了什么,以更好地理解隨機(jī)森林算法。
set.seed(456)titanic_rf <- titanic %>% select(survived, age, pclass, sex, sibsp, fare, parch) %>% ntbt_randomForest(as.factor(survived) ~ ., mtry = 3, n.trees = 5000)
結(jié)果是74.6%,比bagging要好不少(譯者注:這里的比較不是很公平,因?yàn)橹癰agging只用了500棵樹,而這里隨機(jī)森林用了5000棵樹,感興趣的讀者可以試下統(tǒng)一數(shù)量后再做比較),但還是比邏輯回歸差一點(diǎn)。
隨機(jī)森然有很多實(shí)現(xiàn),也許我們可以嘗試下party包,用下條件推斷樹構(gòu)成的隨機(jī)森林。
set.seed(415)titanic_rf_party <- titanic %>% select(survived, age, pclass, sex, sibsp, fare, parch) %>% ntbt(cforest, as.factor(survived) ~ ., controls = cforest_unbiased(ntree = 5000, mtry = 3))
如你所見,代碼和之前差不多,但是結(jié)果是不是差不多呢?
這個(gè)結(jié)果差不多可以算是和邏輯回歸打了個(gè)平手。
Boosting
和之前“奮發(fā)”學(xué)習(xí)的算法不同,boosting緩慢學(xué)習(xí)。實(shí)際上,為了避免過擬合,bagging和隨機(jī)森林需要?jiǎng)?chuàng)建幾千棵決策樹,然后平均所有預(yù)測。boosting的方式與此不同:創(chuàng)建一棵樹,結(jié)果基于第一棵樹的結(jié)果創(chuàng)建另一棵樹,以此類推。
boosting比其他基于決策樹的算法學(xué)得慢,這有助于防止過擬合,但也要求我們小心地調(diào)整學(xué)習(xí)速度。從下面的代碼中,我們能看到,boosting的參數(shù)和隨機(jī)森林比較相似。
library(gbm)set.seed(999)titanic_boost <- titanic %>% select(survived, age, pclass, sex, sibsp, fare, parch) %>% ntbt(gbm, survived ~ ., distribution = "bernoulli", n.trees = 5000, interaction.depth = 3)
我們使用gbm包中的同名函數(shù)(ntbt),并指定distribution參數(shù)為bernoulli(伯努利分布),告訴函數(shù)這是一個(gè)分類問題。n.trees參數(shù)指定創(chuàng)建決策樹的數(shù)目,interaction.depth指定樹的最大深度。
76%,和邏輯回歸、隨機(jī)森林、FFTrees的結(jié)果差不多。
我們學(xué)到了
復(fù)雜模型 > 簡單模型 == 假。邏輯回歸和FFTrees很難戰(zhàn)勝,而且我們只需一點(diǎn)特征工程就可以進(jìn)一步提升簡單模型的表現(xiàn)。
特征工程 > 復(fù)雜模型 == 真。特征工程是一項(xiàng)藝術(shù)。它是數(shù)據(jù)科學(xué)家最強(qiáng)大的武器之一,我們可以使用特征工程改進(jìn)預(yù)測。
創(chuàng)建模型 == 樂!數(shù)據(jù)科學(xué)家很有意思。盡管R有時(shí)會讓人有點(diǎn)沮喪,但總體而言學(xué)習(xí)R回報(bào)豐厚。如果你希望進(jìn)一步了解細(xì)節(jié),或者想要一個(gè)逐步的指南,你可以訪問文章開頭提到的GitHub倉庫,里面有完整的代碼。
如果你喜歡這篇文章,請留言、轉(zhuǎn)發(fā)。你也可以訂閱我的博客rdisorder.eu
-
數(shù)據(jù)集
+關(guān)注
關(guān)注
4文章
1229瀏覽量
25906 -
決策樹
+關(guān)注
關(guān)注
3文章
96瀏覽量
13950 -
r語言
+關(guān)注
關(guān)注
1文章
30瀏覽量
6585
原文標(biāo)題:別迷失在森林里
文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
關(guān)于決策樹,這些知識點(diǎn)不可錯(cuò)過
介紹支持向量機(jī)與決策樹集成等模型的應(yīng)用
決策樹的生成資料
決策樹的構(gòu)建設(shè)計(jì)并用Graphviz實(shí)現(xiàn)決策樹的可視化

決策樹的原理和決策樹構(gòu)建的準(zhǔn)備工作,機(jī)器學(xué)習(xí)決策樹的原理
決策樹和隨機(jī)森林模型

詳談機(jī)器學(xué)習(xí)的決策樹模型

決策樹的基本概念/學(xué)習(xí)步驟/算法/優(yōu)缺點(diǎn)

什么是決策樹模型,決策樹模型的繪制方法

評論