就像所有監督式機器學習模型一樣,決策樹的訓練目標是盡可能解釋一組訓練範例。決策樹的最佳訓練方法是 NP-hard 問題。因此,訓練通常會使用啟發法,這是一種易於建立的學習演算法,可提供非最佳但接近最佳的決策樹。
用於訓練決策樹的演算法大多採用貪婪的「分而治」策略。演算法會先建立單一節點 (根節點),然後以遞迴方式貪婪地擴充決策樹。
系統會在每個節點評估所有可能的條件並給予分數。演算法會選取「最佳」條件,也就是分數最高的條件。目前,您只需要知道分數是與工作相關的指標,而系統會選擇可將該指標提升至最高的條件。
舉例來說,在 Palmer 企鵝資料集 (用於本課程後續的程式碼範例) 中,大多數的阿德利企鵝和巴布亞企鵝嘴喙長度超過 16 公釐,而大多數的冠企鵝嘴喙較小。因此,條件 bill_length_mm ≥ 16 幾乎可完美預測 Gentoo 企鵝,但無法區分 Adelie 企鵝和 Chinstrap 企鵝。演算法可能會選取這個條件。
圖 7. 種樹的第一步。
接著,演算法會在兩個子節點上獨立地重複遞迴。如果找不到符合條件的節點,該節點就會變成葉節點。葉節預測結果會視為範例中最具代表性的標籤值。
演算法如下:
def train_decision_tree(training_examples):
root = create_root() # Create a decision tree with a single empty root.
grow_tree(root, training_examples) # Grow the root node.
return root
def grow_tree(node, examples):
condition = find_best_condition(examples) # Find the best condition.
if condition is None:
# No satisfying conditions were found, therefore the grow of the branch stops.
set_leaf_prediction(node, examples)
return
# Create two childrens for the node.
positive_child, negative_child = split_node(node, condition)
# List the training examples used by each children.
negative_examples = [example for example in examples if not condition(example)]
positive_examples = [example for example in examples if condition(example)]
# Continue the growth of the children.
grow_tree(negative_child, negative_examples)
grow_tree(positive_child, positive_examples)
接下來,我們將進一步說明訓練特定決策樹的步驟。
步驟 1:建立根:
步驟 2:擴展節點 #1。找到「x1 ≥ 1」的條件。系統會建立兩個子節點:
步驟 3:擴展節點 2。找不到符合條件的情況。因此,請將節點設為葉節點:
步驟 4:擴展第 3 個節點。找到「x2 ≥ 0.5」的條件。系統會建立兩個子節點。
還有其他方法可以建立決策樹。另一種常見的做法是全局最佳化節點,而非使用分而治之策略。
growing_strategy="BEST_FIRST_GLOBAL"
參數啟用全球成長功能。詳情請參閱
說明文件。視輸入特徵的數量和類型而定,特定節點的可能條件數量可能非常多,甚至無限。舉例來說,假設閾值條件為 $\mathrm{feature}_i \geq t$,則 $t \in \mathbb{R}$ 的所有可能閾值值組合是無限的。
負責尋找最佳條件的例行程序稱為分隔器。由於需要測試許多可能的條件,因此在訓練決策樹時,分隔器是瓶頸。
分割器可將分數提高至多少,取決於任務。例如:
分割器演算法有很多種,每種演算法支援的項目都不同:
- 特徵類型,例如數值、類別、文字
- 任務,例如二元分類、多元分類、迴歸
- 條件類型,例如門檻條件、集合內條件、斜率條件
- 規則化條件,例如閾值條件的確切或近似分隔符
此外,也有等效的 Splitter 變數,在記憶體用量、CPU 用量、運算分配等方面有不同的取捨。