【R語言學習筆記】3. CART分類樹、隨機森林以及Boosting的應用及對比


1. 目的:根據銀行客戶信息,判斷其是否接受銀行向他們提供的個人貸款。

 

2. 數據來源:https://www.kaggle.com/lowecoryr/universalbank

 

3. 數據介紹:數據中共包含5000個觀測值,14個變量。其中,每一個觀測值代表一個客戶。

bank.df <- read.csv("UniversalBank.csv") # 讀取數據
str(bank.df) # 查看數據結構

 

 

View(bank.df) # 查看數據

 

 

4. 應用及分析

 

4.1 構建回歸樹模型

bank.df <- bank.df[ , -c(1, 5)] # 刪除 ID 和 zip code 兩列

# 將數據分為訓練集和測試集
set.seed(1)
train.index <- sample(c(1:dim(bank.df)[1]), dim(bank.df)[1]*0.6)
train.df <- bank.df[train.index, ] # 訓練集
valid.df <- bank.df[-train.index, ] # 測試集

# 運用訓練集建立分類樹模型
default.ct <- rpart(Personal.Loan ~ ., data = train.df, method = "class") # 沒有設置cp或者depth,意味着建立一個有效的且盡可能簡單的模型
prp(default.ct, type = 1, extra = 1, under = TRUE, split.font = 1, varlen = -10)

 

library(caret) # 建立混淆矩陣
library(lattice)
library(ggplot2)


default.ct.point.pred.train <- predict(default.ct,train.df,type = "class") # 運用所建立的回歸樹模型預測訓練集的數據
confusionMatrix(default.ct.point.pred.train, as.factor(train.df$Personal.Loan)) # 創建訓練集數據與其預測結果的混淆矩陣

 

 

 

 將模型應用到訓練集中,預測的准確性為98.7%。

 

default.ct.point.pred.val <- predict(default.ct,valid.df,type = "class") # 運用所建立的回歸樹模型預測測試集的數據
confusionMatrix(default.ct.point.pred.val, as.factor(valid.df$Personal.Loan)) # 創建測試集數據與其預測結果的混淆矩陣

  

 

 


 將模型應用到訓練集中,預測的准確性為98.15%。

 

接下來,構建一個盡可能復雜的分類樹模型。

deeper.ct <- rpart(Personal.Loan ~ ., data = train.df, method = "class", cp = 0, minsplit = 1)
length(deeper.ct$frame$var[deeper.ct$frame$var == "<leaf>"]) # 共有53個葉子
prp(deeper.ct, type = 1, extra = 1, under = TRUE, split.font = 1, varlen = -10, 
    box.col=ifelse(deeper.ct$frame$var == "<leaf>", 'gray', 'white')) 

 

 

分類回歸樹模型一個很重要的優點在於簡單、容易理解。但是,這個模型中的葉子多達53個,這使模型變得復雜很多。因此,接下來需要修剪如上分類樹的葉子,來簡化模型。

 

第一種修剪葉子的方法為找到最小的cost complexity所對應的cp值,並進行建模。

set.seed(1)
cv.ct <- rpart(Personal.Loan ~ ., data = train.df, method = "class", 
               cp = 0.00001, minsplit = 5, xval = 10)

# xval = 10 -代表交叉檢驗10次
# 交叉檢驗指的是不斷將數據分為訓練集和測試集,不斷建立分類樹模型,計算cost complexity,取使得cost complexity最小的cp值

printcp(cv.ct)

 

 

 

R語言中xerror代表cost complexity,因此,使得cost complexity最小的cp值為0.002291.

 

# 使用使得cost complexity最小的cp值來修剪樹枝
pruned.ct <- prune(cv.ct, 
                   cp = cv.ct$cptable[which.min(cv.ct$cptable[,"xerror"]),"CP"])
length(pruned.ct$frame$var[pruned.ct$frame$var == "<leaf>"]) # 新模型的葉子數為20
prp(pruned.ct, type = 1, extra = 1, split.font = 1, varlen = -10) 

 

 

但是,修剪葉子以后的模型仍包含較多的葉子,不是特別便於理解。因此,引入第二種修剪葉子的方法:使用cost complexity < 最小的cost complexity + std.dev的cp中,使得模型最簡單的cp。

如上圖所示,最小的cost complexity為0.16838,其所對應的std.dev為0.023858。因此最大可容忍的error為0.192238 ( = 0.16838 + 0.023858)。

當cp=0.0068729的時候,既滿足xerror  < 0.192238,又滿足最簡單的模型。因此設置參數cp為0.0068729。

 

pruned.ct <- prune(cv.ct, cp = 0.0068729) 
prp(pruned.ct, type = 1, extra = 1, under = TRUE, split.font = 1, varlen = -10, 
    box.col=ifelse(pruned.ct$frame$var == "<leaf>", 'gray', 'white')) 

 

 

 

 

4.2 構建隨機森林模型

 

library(randomForest) # 加載randomForest包
rf <- randomForest(as.factor(Personal.Loan) ~ ., data = train.df,
                   ntree = 500, mtry = 4, nodesize = 5, importance = TRUE)
varImpPlot(rf, type = 1)

 

由此可見,Income, Education的平均基尼系數下降最多。

 

rf.pred <- predict(rf, valid.df) # 將隨機森林模型應用到測試集並進行預測
confusionMatrix(rf.pred, as.factor(valid.df$Personal.Loan)) # 混淆矩陣

 

 

 

應用隨機森林以后,模型應用於測試集的准確性由98.15%提高至98.55%。

 

# 繪制ROC曲線
library(pROC)
pl0 <- roc(valid.df$Personal.Loan, as.numeric(rf.pred))
plot(pl0, print.auc = T, auc.polygon = T, grid = c(0.1,0.2), grid.col=c("green", "red"), 
    max.auc.polygon=TRUE, auc.polygon.col="skyblue", print.thres=TRUE, main='ROC Curve for Random Forest Algorithm')

 

 

 

 

 

 

4.3 構建boosted trees模型

library(adabag)
library(foreach) library(doParallel) library(iterators) library(parallel) library(rpart) library(caret) train.df$Personal.Loan <- as.factor(train.df$Personal.Loan) #將因變量轉為factor類型變量 error <- as.numeric()
for (i in 1:20) {
set.seed(1) boost <- boosting(Personal.Loan ~ ., data = train.df, boos = T, mfinal = i) pred <- predict(boost, valid.df) error[i] <- pred$error } # 用boosting()函數對訓練集進行訓練。 # 首先定義基分類器個數為1,通過循環依次增加基分類器個數,直至達到20。 # 基分類器個數通過boosting()中的mfinal參數進行設置。 # boos = T 代表權重使用迭代權重 # boos = F 代表各個觀測使用相同的權重 library(ggplot2) error <- as.data.frame(error) # 將error轉變為data frame p <- ggplot(error, aes(x = 1:20, y = error)) + geom_line(colour="red", linetype="dashed",size = 1) + geom_point(size = 3, shape = 18) + ylim(0,0.05) + xlab("the number of basic classifiers") + theme_bw() + theme(panel.grid = element_blank()) + theme(axis.title = element_text(face = 'bold')) p

 

 

因此,當弱學習機為數目為13的時候,誤差最小。

 

boost <- boosting(Personal.Loan ~ ., data = train.df, boos = T, mfinal = 13) # 設置mfinal=13
pre <- predict(boost, newdata = valid.df)$class # pre是數值為0/1的變量
df <- data.frame(prob = pre, obs = valid.df$Personal.Loan)
# 混淆矩陣
t <- table(valid.df$Personal.Loan, pre, dnn = c('observed','predicted')) # accuracy = (1805+176)/(1805+176+13+6)=99/05%

 

 

boosted trees 模型對測試集的預測准確性高達99.05%

 

# 計算誤差 = 0.0095
## method1
(sum(t) - sum(diag(t)))/sum(t) 
## method2
calculate error = predict(boost, newdata = valid.df)$error 


# 繪制各自變量的重要性
imp <- sort(boost$importance, decreasing = T) 
barplot(imp) 

 

 

# 繪制ROC曲線
library(pROC)
pl <- roc(valid.df$Personal.Loan, as.numeric(pre))
plot(pl, print.auc = T, auc.polygon = T, grid = c(0.1,0.2), grid.col=c("green", "red"), 
    max.auc.polygon=TRUE, auc.polygon.col="skyblue", print.thres=TRUE, main='ROC Curve for Adaboost Algorithm')

 

 

 

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM