機器學習 - 隨機森林手動10 折交叉驗證

生信寶典 發佈 2022-08-15T13:18:27.782793+00:00

隨機森林的 10 折交叉驗證再回到之前的隨機森林(希望還沒忘記,機器學習算法-隨機森林初探(1))library(randomForest)set.


隨機森林的 10 折交叉驗證

再回到之前的隨機森林(希望還沒忘記,機器學習算法-隨機森林初探(1))

library(randomForest)
set.seed(304)
rf1000 <- randomForest(expr_mat, metadata[[group]], ntree=1000)
rf1000
## 
## Call:
##  randomForest(x = expr_mat, y = metadata[[group]], ntree = 1000) 
##                Type of random forest: classification
##                      Number of trees: 1000
## No. of variables tried at each split: 84
## 
##         OOB estimate of  error rate: 11.69%
## Confusion matrix:
##       DLBCL FL class.error
## DLBCL    57  1  0.01724138
## FL        8 11  0.42105263

除了 OOB,我們還可以怎麼評估模型的準確性呢?這裡沒有測試集,那麼就拿原始數據做個評估吧(注意:這樣會低估預測錯誤率):

# 查看模型的類,為randomForest
class(rf1000)
## [1] "randomForest"
# 查看 predict 函數的幫助,默認幫助信息為通用函數 predict 的
# ?predict
# 查看 randomForest 類的 predict 的幫助(predict+'.'+類名字)
# 像 print 此類函數,也是如此查看幫助或源碼
#  type 參數: response 表示返回分類的值;prob 表示分類的概率;vote 表示 vote counts
# ?predict.randomForest

開始預測

preds <- predict(rf1000, expr_mat, type="response")

查看下preds對象,顯示的是每個樣品被預測為屬於什麼類。

preds
##  DLBCL_1  DLBCL_2  DLBCL_3  DLBCL_4  DLBCL_5  DLBCL_6  DLBCL_7  DLBCL_8  DLBCL_9 DLBCL_10 DLBCL_11 
##    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL 
## DLBCL_12 DLBCL_13 DLBCL_14 DLBCL_15 DLBCL_16 DLBCL_17 DLBCL_18 DLBCL_19 DLBCL_20 DLBCL_21 DLBCL_22 
##    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL 
## DLBCL_23 DLBCL_24 DLBCL_25 DLBCL_26 DLBCL_27 DLBCL_28 DLBCL_29 DLBCL_30 DLBCL_31 DLBCL_32 DLBCL_33 
##    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL 
## DLBCL_34 DLBCL_35 DLBCL_36 DLBCL_37 DLBCL_38 DLBCL_39 DLBCL_40 DLBCL_41 DLBCL_42 DLBCL_43 DLBCL_44 
##    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL 
## DLBCL_45 DLBCL_46 DLBCL_47 DLBCL_48 DLBCL_49 DLBCL_50 DLBCL_51 DLBCL_52 DLBCL_53 DLBCL_54 DLBCL_55 
##    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL    DLBCL 
## DLBCL_56 DLBCL_57 DLBCL_58     FL_1     FL_2     FL_3     FL_4     FL_5     FL_6     FL_7     FL_8 
##    DLBCL    DLBCL    DLBCL       FL       FL       FL       FL       FL       FL       FL       FL 
##     FL_9    FL_10    FL_11    FL_12    FL_13    FL_14    FL_15    FL_16    FL_17    FL_18    FL_19 
##       FL       FL       FL       FL       FL       FL       FL       FL       FL       FL       FL 
## Levels: DLBCL FL

計算模型效果評估矩陣(也稱混淆矩陣),敏感性、特異性 100%。完美的模型!!!(這裡主要是看下predict如何使用,完美的模型只是說構建的完美,不能表示預測性能的完美,因為沒有用獨立數據集進行評估。)

library(caret)
## Warning: package 'caret' was built under R version 4.0.3
## Loading required package: lattice
## Loading required package: ggplot2
## 
## Attaching package: 'ggplot2'
## The following object is masked from 'package:randomForest':
## 
##     margin
caret::confusionMatrix(preds, metadata[[group]])
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction DLBCL FL
##      DLBCL    58  0
##      FL        0 19
##                                      
##                Accuracy : 1          
##                  95% CI : (0.9532, 1)
##     No Information Rate : 0.7532     
##     P-Value [Acc > NIR] : 3.343e-10  
##                                      
##                   Kappa : 1          
##                                      
##  Mcnemar's Test P-Value : NA         
##                                      
##             Sensitivity : 1.0000     
##             Specificity : 1.0000     
##          Pos Pred Value : 1.0000     
##          Neg Pred Value : 1.0000     
##              Prevalence : 0.7532     
##          Detection Rate : 0.7532     
##    Detection Prevalence : 0.7532     
##       Balanced Accuracy : 1.0000     
##                                      
##        'Positive' Class : DLBCL      
##

predict還可以返回分類的概率 (有了這個是不是就可以繪製 ROC 曲線和計算AUC 值了)。

preds_prob <- predict(rf1000, expr_mat, type="prob")
head(preds_prob)
##         DLBCL    FL
## DLBCL_1 0.951 0.049
## DLBCL_2 0.972 0.028
## DLBCL_3 0.975 0.025
## DLBCL_4 0.984 0.016
## DLBCL_5 0.963 0.037
## DLBCL_6 0.989 0.011

predict還可以返回分類的vote值。

preds_prob <- predict(rf1000, expr_mat, type="vote")
head(preds_prob)
##         DLBCL    FL
## DLBCL_1 0.951 0.049
## DLBCL_2 0.972 0.028
## DLBCL_3 0.975 0.025
## DLBCL_4 0.984 0.016
## DLBCL_5 0.963 0.037
## DLBCL_6 0.989 0.011

前面主要是學習下predictconfusionMatrix函數的使用。把前面的代碼串起來,就構成了一個隨機森林的 10 折交叉驗證代碼:

# https://stackoverflow.com/questions/47960427/how-to-calculate-the-oob-of-random-forest
K = 10
m = nrow(expr_mat)
set.seed(1)
kfold <- sample(rep(1:K, length.out=m), size=m, replace=F)
randomForestCV <- function(x, y, xtest, ytest, type="response", seed=1, ...){
  set.seed(seed)
  model <- randomForest(x, y, ...)
  preds <- predict(model, xtest, type=type)
  return(data.frame(preds, real=ytest))
}
CV_rf <- lapply(1:K, function(x, ...){ 
  train_set = expr_mat[kfold != x,]
  train_label = metadata[[group]][kfold!=x]
  validate_set = expr_mat[kfold == x,]
  validate_label = metadata[[group]][kfold==x]
  randomForestCV(x=train_set, y=train_label, xtest=validate_set, ytest=validate_label, ...)
  })
kfold_estimate <- do.call(rbind, CV_rf)

查看下10 折交叉驗證的預測結果

kfold_estimate
##          preds  real
## DLBCL_3  DLBCL DLBCL
## DLBCL_8  DLBCL DLBCL
## DLBCL_9  DLBCL DLBCL
## DLBCL_35 DLBCL DLBCL
## DLBCL_57 DLBCL DLBCL
## FL_9     DLBCL    FL
## FL_10    DLBCL    FL
## FL_18       FL    FL
## DLBCL_15 DLBCL DLBCL
## DLBCL_16 DLBCL DLBCL
## DLBCL_40 DLBCL DLBCL
## DLBCL_41 DLBCL DLBCL
## DLBCL_42 DLBCL DLBCL
## DLBCL_44 DLBCL DLBCL
## DLBCL_51 DLBCL DLBCL
## DLBCL_53 DLBCL DLBCL
## DLBCL_5  DLBCL DLBCL
## DLBCL_20 DLBCL DLBCL
## DLBCL_25 DLBCL DLBCL
## DLBCL_32 DLBCL DLBCL
## DLBCL_38 DLBCL DLBCL
## FL_2     DLBCL    FL
## FL_12    DLBCL    FL
## FL_16       FL    FL
## DLBCL_4  DLBCL DLBCL
## DLBCL_6  DLBCL DLBCL
## DLBCL_10 DLBCL DLBCL
## DLBCL_14 DLBCL DLBCL
## DLBCL_18 DLBCL DLBCL
## DLBCL_39 DLBCL DLBCL
## FL_1     DLBCL    FL
## FL_6        FL    FL
## DLBCL_17 DLBCL DLBCL
## DLBCL_19 DLBCL DLBCL
## DLBCL_22 DLBCL DLBCL
## DLBCL_33 DLBCL DLBCL
## DLBCL_36 DLBCL DLBCL
## DLBCL_45 DLBCL DLBCL
## DLBCL_47 DLBCL DLBCL
## FL_11    DLBCL    FL
## DLBCL_13 DLBCL DLBCL
## DLBCL_23 DLBCL DLBCL
## DLBCL_37 DLBCL DLBCL
## DLBCL_52 DLBCL DLBCL
## FL_3        FL    FL
## FL_5        FL    FL
## FL_17    DLBCL    FL
## FL_19       FL    FL
## DLBCL_11 DLBCL DLBCL
## DLBCL_12 DLBCL DLBCL
## DLBCL_27 DLBCL DLBCL
## DLBCL_28 DLBCL DLBCL
## DLBCL_54 DLBCL DLBCL
## DLBCL_56 DLBCL DLBCL
## DLBCL_58 DLBCL DLBCL
## FL_14    DLBCL    FL
## DLBCL_1  DLBCL DLBCL
## DLBCL_26    FL DLBCL
## DLBCL_29    FL DLBCL
## DLBCL_43 DLBCL DLBCL
## DLBCL_50 DLBCL DLBCL
## FL_8     DLBCL    FL
## FL_15       FL    FL
## DLBCL_2  DLBCL DLBCL
## DLBCL_7  DLBCL DLBCL
## DLBCL_48 DLBCL DLBCL
## DLBCL_55 DLBCL DLBCL
## FL_4        FL    FL
## FL_7        FL    FL
## FL_13       FL    FL
## DLBCL_21 DLBCL DLBCL
## DLBCL_24 DLBCL DLBCL
## DLBCL_30 DLBCL DLBCL
## DLBCL_31 DLBCL DLBCL
## DLBCL_34 DLBCL DLBCL
## DLBCL_46 DLBCL DLBCL
## DLBCL_49 DLBCL DLBCL

計算模型效果評估矩陣(也稱混淆矩陣)。準確性值為0.8581,OOB 的錯誤率是88.31%,相差不大。但Kappa值不算高0.5614,這也是數據集中兩個分組的樣本數目不均衡導致的。

library(caret)
caret::confusionMatrix(kfold_estimate$preds, kfold_estimate$real)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction DLBCL FL
##      DLBCL    56  9
##      FL        2 10
##                                           
##                Accuracy : 0.8571          
##                  95% CI : (0.7587, 0.9265)
##     No Information Rate : 0.7532          
##     P-Value [Acc > NIR] : 0.01936         
##                                           
##                   Kappa : 0.5614          
##                                           
##  Mcnemar's Test P-Value : 0.07044         
##                                           
##             Sensitivity : 0.9655          
##             Specificity : 0.5263          
##          Pos Pred Value : 0.8615          
##          Neg Pred Value : 0.8333          
##              Prevalence : 0.7532          
##          Detection Rate : 0.7273          
##    Detection Prevalence : 0.8442          
##       Balanced Accuracy : 0.7459          
##                                           
##        'Positive' Class : DLBCL           
## 
# 結果如下

其它指標前面大都有講述或?confusionMatrix可看到對應的計算公式。

重點看下Kappa係數,其也是評估分類準確性的一個指標。在模型評估指標一文有提到,準確性值在各個分類樣本不平衡時會更多偏向樣品多的類。而Kappa係數則可以綜合評估這種不平衡性。Kappa係數在-1和1之間,值越大表示模型性能越好。

  • Kappa=0說明模型和瞎猜差不多。
  • Kappa>0.4說明模型還行。
  • Kappa>0.4說明模型挺好的。
  • 這幾個標準未找到確切文獻,僅供參考來理解 Kappa 係數。

其計算公式如下:

關鍵字: