すべての教師あり ML モデルと同様に、ディシジョン ツリーは一連のトレーニング サンプルを最もよく説明するようにトレーニングされます。ディシジョンツリーの最適なトレーニングは NP 難しい問題ですしたがって、トレーニングは通常、ヒューリスティックを使用して行われます。ヒューリスティックは、簡単に作成できる学習アルゴリズムで、最適ではないものの、最適に近いディシジョン ツリーを提供します。
ディシジョン ツリーのトレーニングに使用されるほとんどのアルゴリズムは、欲張りな分割統治戦略で機能します。このアルゴリズムは、まず単一のノード(ルート)を作成し、ディシジョン ツリーを再帰的かつ強引に拡大します。
各ノードで、考えられるすべての条件が評価され、スコアが付けられます。このアルゴリズムは、「最良」の条件、つまり最も高いスコアを持つ条件を選択します。今のところは、スコアはタスクと相関する指標であり、その指標を最大化する条件が選択されていることだけを覚えておいてください。
たとえば、Palmer Penguins データセット(このコースの後半のコード例で使用します)では、ほとんどの Adelie ペンギンと Chinstrap ペンギンのくちばしの長さは 16 mm を超えていますが、Gentoo ペンギンのほとんどはくちばしが小さいです。したがって、bill_length_mm ≥ 16 という条件は、ジェントゥー ペンギンについてはほぼ完璧な予測を行いますが、アデリースとチンストラップを区別することはできません。アルゴリズムはおそらく、この条件を選択します。
図 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」という条件が見つかりました。 2 つの子ノードが作成されます。
ステップ 3: ノード 2 を拡張します。一致する条件が見つかりませんでした。ノードをリーフにします
ステップ 4: ノード 3 を拡張します。"x2 ≥ 0.5" の条件が見つかりました。2 つの子ノードが作成されます。
ディシジョン ツリーを増やす別の方法も存在します。一般的な代替策は、分割統治戦略を使用するのではなく、ノードをグローバルに最適化することです。
growing_strategy="BEST_FIRST_GLOBAL"
パラメータを使用してグローバルな拡張を有効にすることもできます。詳細については、
ドキュメントをご覧ください。入力特徴の数とタイプによっては、特定のノードで考えられる条件の数が膨大になり、通常は無限になる可能性があります。たとえば、しきい値条件 $\mathrm{feature}_i \geq t$ の場合、$t \in \mathbb{R}$ に対して可能なすべてのしきい値の組み合わせは無限です。
最適な条件を見つけるためのルーチンは、スプリッターと呼ばれます。考えられる多くの条件をテストする必要があるため、ディシジョン ツリーをトレーニングする際のボトルネックがスプリッターです。
スプリッターによって最大化されるスコアは、タスクによって異なります。次に例を示します。
スプリッター アルゴリズムは多数あり、それぞれで次のサポートが異なります。
- 特徴のタイプ(数値、カテゴリ、テキストなど)
- タスク(バイナリ分類、マルチクラス分類、回帰など)
- 条件のタイプ(しきい値条件、セット内条件、傾斜条件など)
- 正則化条件(しきい値条件の厳密なスプリッターや近似スプリッターなど)
さらに、同等のスプリッター バリアントがあり、メモリ使用量、CPU 使用量、計算分散などに関して異なるトレードオフがあります。