logo

1 簡介

       決策森林 (random forest) 是集成學習 (ensemble learning) 的一種,主要是透過建立多個相互獨立 (independent) 的迴歸樹 (classification and regression tree, 簡稱 CART),並將這些分類結果加以平均或以多數決準則 (majority vote) 為依據,來做為最後的模型預測結果。根據簡單的統計學概念可知,若令第 \(\small{i}\) 個 CART 分類結果為 \(\small{y_i}\),其平均數為 \(\small{\mu}\),變異數為 \(\small{\sigma^2}\),因為 \(~\small{y_i \stackrel{i.i.d.}{\sim}}\) 彼此相互獨立,所以在一些條件下決策森林的預測結果 \(\small{1/N}\sum_{i=1}^{N} y_i\) 具有以下的性質: \[ \small{ \mbox{E}(\frac{1}{N}\sum_{i=1}^{N} y_i) = \mu, \quad \quad \mbox{var}(\frac{1}{N}\sum_{i=1}^{N} y_i) = \frac{\sigma^2}{N}, } \] 其中 \(\small{N}\) 為 CART 模型個數 (number of trees)。換言之,決策森林的預測結果具有不偏性 (unbias),並且變異數 \(~\small{\sigma^2/N}\) 會隨著 \(\small{N}\) 愈大而變小。由於決策森林有此良好的特性,故常用來解決 CART 模型中過度配適 (over-fitting) 的問題。以下的們嘗試利用決策森林模型來預測未來領先指標 (leading indicator) 上漲或下跌的情況,雖然其預測結果不盡理想,並且也不一定有其經濟意涵,但卻不失為一個很好的練習。

2 模型架構

       決策森林模型的架構主要有以下幾個部份:

  1. 隨機抽取樣本: 在 R 中會依據 bootstrap 方式隨機抽出約 \(\small{63.2\%}\) 的樣本個數,以取出放回 (sampling with replacement) 的方式進行隨機抽樣。而沒有被抽出的資料稱為 out-of-bag (簡稱 OOB) 樣本。由於是隨機抽樣,所以在處理時間序列資料時要特別小心 (後續會再說明)。

  2. 隨機抽取解釋變數: 若被解釋變數 \(~\small{Y_t}\) 為間斷型變數,則會隨機抽取 \(\small{\sqrt{K}}\) 個解釋變數來建立 CART 模型,其中 \(\small{K}\) 為解釋變數個數。

  3. 設定 \(\small{N}\): 設定所需建構的 CART 模型個數。

  4. 其它: 詳見 R::randomForest 說明手冊以及課程說明。

換句話說,決策森林模型會依據隨機抽取出的樣本以及解釋變數來建立一個 CART 模型,並且該步驟會持續進行 \(\small{N}\) 次,以建立 \(~\small{N}\) 個相互獨立的 CART 模型。最後再將這 \(\small{N}\) 個模型的分類結果加以平均 (或依多數決準則的結果) 來做為決策森林模型的最終預測值。

3 實證分析

       國家發展委員會每月會公佈領先指標,該指標由外銷訂單動向指數 (以家數計)、實質貨幣總計數 M1B、股價指數、工業及服務業受僱員工淨進入率、建築物開工樓地板面積 (住宅、商辦、工業倉儲等)、實質半導體設備進口值,及製造業營業氣候測驗點等 7 項構成項目組成,具領先景氣波動性質。由於資料收集的時間限制,當月只會公佈上個月的領先指標指標,因此無法即時反應近期的景氣狀況。若可以透過模型預測未來指標的漲跌情況,便有更多資訊來掌握未來的景氣動向。以下我們嘗試透過當期與落後期的股價與股價報酬率來預測未來 6 個月領先指標的漲跌情況。

3.1 資料

       我們先從相關網站收集領先指標,中鋼、聯電、台積電以及台灣 50 指數這 4 檔經還原股價後的相關數據,資料期間為 2003-M8 ~ 2020-M12。此外,我們也進行以下的資料轉換,將領先指標改成間斷型資料: 當未來 6 個月領先指標成長率上漲超過 5%,則 \(\small{ Y_{t+6} = 1 }\),若下跌超過 5%,則 \(\small{ Y_{t+6} = -1 }\),其它情況則為 \(\small{ Y_{t+6} = 0 }\)。為方便說明,我們令 \(\small{X_{i,t}}\) 為第 \(~\small{i}~\) 檔第 \(~\small{t}~\) 期的股價指數或股價報酬率。我們嘗試利用決策森林模型以及當期與落後期的股價以及股價報酬率 \(\small{X_{i,t-j}, j=0, 1, 2}\) 來預測未來 6 個月 \(\small{ Y_{t+6} }\) 的結果。附錄呈現本文的部份資料,可供大家參考。

3.2 實證結果

       為方便起見,我們假設每筆資料相互獨立 (既不考慮時間數列的相關性),並且先設定 \(\small{N} = 1000\)。以下是我們 R 程式的模型設定以及執行結果:

set.seed(1234)
model   = randomForest(Y ~., data = Data , importane = T, proximity = T, do.trace = 100, ntree= 1000)
## ntree      OOB      1      2      3
##   100:   9.50% 63.64%  2.27% 61.54%
##   200:   9.00% 63.64%  1.70% 61.54%
##   300:   9.00% 63.64%  1.70% 61.54%
##   400:   8.50% 63.64%  1.70% 53.85%
##   500:   9.00% 63.64%  1.70% 61.54%
##   600:   9.50% 72.73%  1.70% 61.54%
##   700:   8.50% 63.64%  1.70% 53.85%
##   800:   8.50% 63.64%  1.70% 53.85%
##   900:   9.00% 72.73%  1.70% 53.85%
##  1000:   9.00% 72.73%  1.70% 53.85%

從執行結果不難看出,在建構 \(\small{N} = 400\) 個 CART 模型時其 OOB 錯誤率為 8.50%,相對低於其它的 \(\small{N}\) 值。因此我們重新執行上述程式,並設定 \(\small{N} = 400\),依此 OOB 樣本來計算 confusion matrix,以下為執行結果:

set.seed(1234)
model = randomForest(Y ~., data = Data , importane = T, proximity = T, do.trace = 100, ntree= 400)
## ntree      OOB      1      2      3
##   100:   9.50% 63.64%  2.27% 61.54%
##   200:   9.00% 63.64%  1.70% 61.54%
##   300:   9.00% 63.64%  1.70% 61.54%
##   400:   8.50% 63.64%  1.70% 53.85%
model
## 
## Call:
##  randomForest(formula = Y ~ ., data = Data, importane = T, proximity = T,      do.trace = 100, ntree = 400) 
##                Type of random forest: classification
##                      Number of trees: 400
## No. of variables tried at each split: 4
## 
##         OOB estimate of  error rate: 8.5%
## Confusion matrix:
##    -1   0 1 class.error
## -1  4   7 0  0.63636364
## 0   1 173 2  0.01704545
## 1   0   7 6  0.53846154

從上述的 confusion matirx 結果可以觀察到,若真實的 \(\small{ Y_{t+6} = 0 }\) 時,模型也預測為 0 的比例約為 0.983%,錯誤率只有 0.017%,但若真實的 \(\small{ Y_{t+6} = -1 }\) 或是 1 時,模型預測錯誤率則約為 0.63% 以及 0.53%,預測結果不盡理想。接著,我們再依據 OOB 錯誤率來計算解釋變數的重要性 (importance):

importance  = model$importance                                                  # importance
importance[order(-importance),]
##       中鋼     中鋼L1     聯電L2     聯電L1   台灣50L1   台灣50L2   台灣50_r 
##  3.6007993  3.2454649  2.9233014  2.8170288  2.7076783  2.7004622  2.1713380 
##   台積電L2       聯電     台灣50 台灣50_rL1     中鋼L2   台積電L1   台積電_r 
##  2.0423184  2.0199256  1.9085520  1.7932960  1.7120058  1.6353556  1.4556774 
## 台積電_rL1   中鋼_rL2 台灣50_rL2   聯電_rL2     台積電   聯電_rL1     中鋼_r 
##  1.4023495  1.2670094  1.1632870  1.1099819  1.0391383  0.9936874  0.9936280 
## 台積電_rL2     聯電_r   中鋼_rL1 
##  0.9792419  0.9256042  0.7387935

我們看到,當期的中鋼股價、落後一期的中鋼股價 (代碼為中鋼L1)、落後二期與的聯電股價 (代碼為聯電L2)、落後一期的聯電股價 (代碼為聯電L1) 以及落後一期台灣 50 指數 (代碼為台灣50L1) 為前 5 個較重要的解釋變數。因為我們再依據這 5 個重要的解釋變數建構一個 CART 模型,來做為決策者判斷未來 6 個月領先指標漲跌情況的基本準則:

### Step 1: 資料 ########################################
Name = c("Y", names(importance[order(-importance),])[1:5])
Data = Data[ , Name]

### Step 2: 模型 ########################################
formula = "Y ~."

### Step 3: 估計 ########################################
### Decision Tree: CART ################################# rpart::rpart(formula, data, weights, subset, na.action = na.rpar, ...); parms = list(split = 'gini' or 'information'))
Model   = rpart(as.formula(formula), data = Data, method = 'class', parms=list(split="gini"))   # 使用 CART 算法的時候 split = 'gini'

### Decision Tree: Plot ################################# rattle::fancyRpartPlot(model, main="", sub, caption, palettes, type=2, ...)
fancyRpartPlot(Model, main = paste("", sep = " "), sub = '')

從上圖 CART 模型中可以看到,當落後二期的聯電股價 \(\small{< 7.3}\) 時,模型會預測未來 6 個月的領先指標應該是上漲的情況,其成長率大於 5% (既 \(~\small{ Y_{t+6} = 1 }\))。主要是因為該群組的樣本中有 12% 為 \(\small{ Y_{t+6} = 0 }\),88% 為 \(\small{ Y_{t+6} = 1 }\),在多數決準則下模型會判斷 \(\small{ Y_{t+6} = 1}\) 這結果。同理,當落後二期的聯電股價 \(\small{\ge 7.3}\) 且當期的中鋼股價 \(\small{< 23}\) 時,模型會預測未來 6 個月的領先指標應該為持平情況 (既 \(~\small{ Y_{t+6} = 0 }\)),因為該群組的樣本中有 95% 為 \(\small{ Y_{t+6} = 0 }\)

4 結論

       我們透過決策森林以及 CART 嘗試建立一個模型來協助我們判斷未來 6 個月的領先指標漲跌情況。雖然模型在預測 \(~\small{ Y_{t+6} = \pm 1 }\) 時不盡理想,但在判斷 \(~\small{ Y_{t+6} = 0 }\) 時有很高的準確率,也可以學習到不少知識,因此不失為一個好的練習。但值得一提的是,模型中假設每筆資料相互獨立 (既不考慮時間數列的相關性),並且解釋變數與領先指標之間也不一定存在經濟意涵,這些缺點都可以做為後續研究者的修改方向。

5 附錄

       以下我們節錄部份資料,供大家參考。表中 Date_Y 對應 \(~\small{Y}\) 的日期,而代碼中鋼_r 為中鋼股價的成長率。