基於樹的補值

在 R 中以插補處理遺漏值

Michal Oleszak

Machine Learning Engineer

基於樹的補值方法

用機器學習模型來預測遺漏值!

  • 非參數方法:不對變數關係做任何假設。
  • 能捕捉複雜的非線性模式。
  • 通常比簡單統計模型有更好的預測表現。

本課使用:missForest 套件,基於 randomForest

在 R 中以插補處理遺漏值

決策樹

決策樹示意圖,顯示模型如何做決策。模型依據 Height 與 Weight 的不同組合,給出不同的 Diabetes 機率。

在 R 中以插補處理遺漏值

隨機森林

隨機森林運作示意。原始資料產生三個 bagging 資料集與隨機欄位子集。各自擬合決策樹,最後彙整所有樹的結果。

在 R 中以插補處理遺漏值

missForest 演算法

  1. 先用平均值補法為遺漏值做初始猜測。
  2. 依遺漏值數量由少到多排序變數。
  3. 針對每個變數 x
    • x 的觀測部分擬合隨機森林(用其他變數當預測因子)。
    • 用模型預測 x 的遺漏部分。
  4. 重複步驟 3,直到補值幾乎不再變動。
在 R 中以插補處理遺漏值

實作 missForest

nhanes %>% is.na() %>% colSums()
Age     Gender     Weight     Height   Diabetes    TotChol      Pulse PhysActive 
  0          0          9          8          1         85         32         26
library(missForest)
imp_res <- missForest(nhanes)
nhanes_imp  <- imp_res$ximp
nhanes_imp %>% is.na() %>% colSums()
Age     Gender     Weight     Height   Diabetes    TotChol      Pulse PhysActive 
  0          0          0          0          0          0          0          0
在 R 中以插補處理遺漏值

補值誤差

missForest() 會提供袋外(OOB)補值誤差估計:

  • 連續變數用標準化均方根誤差(NRMSE)。
  • 類別變數用錯誤分類比例(PFC)。

imp_res <- missForest(nhanes)
imp_res$OOBerror
      NRMSE         PFC 
0.147687025 0.003676471
在 R 中以插補處理遺漏值

補值誤差

missForest() 會提供袋外(OOB)補值誤差估計:

  • 連續變數用標準化均方根誤差(NRMSE)。
  • 類別變數用錯誤分類比例(PFC)。

兩種情況下,表現佳→數值接近 0;接近 1→結果不佳。

imp_res <- missForest(nhanes, variablewise = TRUE)
imp_res$OOBerror
    MSE       PFC       MSE       MSE       PFC       MSE       MSE       MSE 
0.00000   0.00000 285.79563  40.42142   0.00735   0.53444 129.03609   0.17576
在 R 中以插補處理遺漏值

速度與準確度的權衡

同時成長多個隨機森林會很耗時。

想法:犧牲些許準確度,縮小森林以降低計算時間。

  • 減少每個森林的樹數(ntree 參數)。
  • 降低用於分裂的變數數(mtry 參數)。

對計算時間的影響不同:

  • 降低 ntree 為線性影響。
  • 當變數很多時,減少 mtry 提速更明顯。
在 R 中以插補處理遺漏值

實作:速度與準確度的權衡

預設設定:

start_time <- Sys.time()
imp_res <- missForest(nhanes)
end_time <- Sys.time()
print(imp_res$OOBerror)
print(end_time - start_time)
      NRMSE         PFC 
0.147687025 0.003676471
Time difference of 5.496582 secs

縮小的森林:

start_time <- Sys.time()
imp_res <- missForest(nhanes,
                      ntree = 10,
                      mtry = 2)
end_time <- Sys.time()
print(imp_res$OOBerror)
print(end_time - start_time)
      NRMSE         PFC 
0.162420139 0.007425743
Time difference of 0.516367 secs
在 R 中以插補處理遺漏值

一起來練習吧!

在 R 中以插補處理遺漏值

Preparing Video For Download...