Decision Tree
資料
目錄架構
.
├── census
│ ├── data_preprocess.py
│ ├── __init__.py
├── census_dt.py
├── data
│ ├── sample_submission.csv
│ ├── X_test.csv
│ ├── X_train.csv
│ └── y_train.csv
└── model
├── decision_tree.py
└── __init__.py
主程式
census_dt.py
|
|
- 將 data 的路徑定義好
- 丟進 CensusData 做預處理
- 處理 Data 中缺失的欄位
- 打亂 Train Data
- 透過 holdout validation 以及 k-fold cross validation 檢驗正確性
- 選出正確率最高的 Tree 對 test set 猜測答案
holdoutValidation
|
|
- 切割 Data 為 train:validation = 7:3
- Train Model
- 透過 Validation Data 驗證正確性
kFoldCrossValidation
|
|
- 做 K 次分割不同區段的 train 及 validation data
- Train Model
- 透過不同區段的 Validation Data 驗證正確性
validate
|
|
- 紀錄並回傳 Confusion matrix
Data Preprocessing
census / data_preprocess.py
|
|
建構式:
- 把 Label 放在 Train Dataframe 的最後一個 Column
- 同一 string 的 data,必免空格導致誤判
- 儲存 Test Data
handle_missing_data:
- 把 train data 與 test data 中的缺失項找出 (先換成 nan,再全部 replace)
- 把缺失項換成出現頻率最高的值 (因為缺失項都為非連續的欄位,所以不考慮連續情況)
資料結構設計
Decision Tree 的框架設計為:
tree = {
"feature": {
"question": {
"feature": {
...
}
}
"question": {
...
}
}
}
舉例來說:
tree = {
"age": {
">10": {
"relationship": {
"== Husband": {
},
...
}
}
"<=10": 0
}
}
同時這個 Tree 支援 multiple branch,在可分類(非連續)的欄位會建立所有可支援的 branch,在連續的欄位會有 >, <= 區分兩種範圍
Model
model / decision_tree.py
|
|
建構式:
- 把 pandas dataframe 轉為 numpy nd-array
- 取出 COLUMNS 的名字
- 遞迴建立 Tree
分為 4 個部份:
- 建立樹
- 選擇最佳分支
- helper function
- 預測答案
建立樹
|
|
- 檢查 Base case
- data 的 Purity,若 data 為單一的 label 就直接 classify Data
- 若資料量剩一筆,直接 classify Data
- 若遞迴深度到達最大深度,classify Data
- 算出 data 中各個 feature 的 unique levels
- 選出最佳的 feature 當作 root (Information Gain 最大的 feature)
- best feature 分兩種情況
- 連續 (data 的 type 為 int)
- 對最佳的分割值做分割
- 若分割後 data 為空則直接 return classify Data
- 非空則建立 >, <= 的 branch
- 若分割後 above 與 below 的 data 相同則直接 return 其中一個,不再分割 branch
- 非連續 (data 的 type 為 str)
- 對所有 category 都建一條 branch
- 再建一條如果所有 branch 都沒有 match 到的情況 (有可能 test data 的 category 不包含在 train data 中)
- 連續 (data 的 type 為 int)
選擇最佳分支
|
|
- 最佳的 feature 為 remainder 最小的 feature
- 兩種可能情況
- 連續
- 對所有可能的 split value (unique levels) 分割 data
- 計算這個分割的 remainder 若為最小就更新最佳的 feature
- 非連續
- 對所有可能的 category 分割 data
- 計算 category 的 remainder 若為最小就更新最佳的 feature
- 連續
|
|
- 算出 entropy
- 計算條件機率
helper function
|
|
- 分割上下兩段 data
|
|
- 算出 unique level
- 若 random forest 有要隨機選擇 feature 則隨機選擇 index
|
|
- 選擇 data 中出現頻率最高的 label
|
|
- 若 data 中只存在一種 label 則為 purity
預測答案
|
|
- call guess 這個遞迴 function
|
|
- 若 tree 直接為 label 則直接 return
- 選擇 tree 的 feature
- 對 feature 下的 question 做 parse
- 把 answer 設為 predict_ans (可能是一顆樹或是直接是 label),若滿足條件則 break
- 如果 answer 是樹則遞迴下去找答案
- 若 answer 是 label 則直接 return
Result
1) Holdout validation with train/test:7/3
0 1
0 4779.0 390.0
1 689.0 980.0
accuracy: 0.8422053231939164
2) K-fold cross-validation with K=3
-- fold 0
0 1
0 5372.0 403.0
1 834.0 988.0
accuracy: 0.8371725681189943
-- fold 1
0 1
0 5334.0 397.0
1 802.0 1064.0
accuracy: 0.8421745425825984
-- fold 2
0 1
0 5319.0 439.0
1 761.0 1078.0
accuracy: 0.8420429116756615