オーバーフィットとプルーニング
上記のアルゴリズムを使用すると、サンプルが分離可能であることを前提として、トレーニング サンプルを完全に分類するディシジョン ツリーをトレーニングできます。ただし、データセットにノイズが含まれている場合、このツリーはデータに過剰適合し、テストの精度が低下します。
次の図は、特徴 x とラベル y の間に直線関係があるノイズのあるデータセットを示しています。この図は、正則化を適用せずにこのデータセットでトレーニングされたディシジョン ツリーも示しています。このモデルは、すべてのトレーニング サンプルを正しく予測します(モデルの予測はトレーニング サンプルと一致します)。ただし、同じ線形パターンと異なるノイズ インスタンスを含む新しいデータセットでは、モデルのパフォーマンスは低下します。
図 12. ノイズが多いデータセット。
ディシジョン ツリーの過剰適合を制限するには、ディシジョン ツリーをトレーニングするときに、次の正則化条件のいずれかまたは両方を適用します。
- 最大深度を設定する: ディシジョン ツリーが最大深度(10 など)を超えないようにします。
- リーフのサンプルの最小数を設定する: サンプル数が一定数未満のリーフは、分割の対象になりません。
次の図は、リーフあたりの最小サンプル数が異なる場合の影響を示しています。モデルがキャプチャするノイズが少なくなります。
図 13. リーフあたりの最小サンプル数が異なる。
特定の枝を選択的に削除(剪定)することで、トレーニング後に正規化することもできます。つまり、特定のリーフ以外のノードをリーフに変換します。削除するブランチを選択する一般的なソリューションは、検証データセットを使用することです。つまり、ブランチを削除することで検証データセット上のモデルの品質が向上する場合、そのブランチは削除されます。
次の図は、この考え方を示しています。ここでは、葉以外の緑色のノードを葉に変換した場合(オレンジ色のノードを剪定した場合)に、意思決定ツリーの検証精度が向上するかどうかをテストします。
図 14. 条件とその子をリーフにプルーニング。
次の図は、データセットの 20% を検証として使用して、意思決定ツリーを剪定した場合の効果を示しています。
図 15. データセットの 20% を使用して、ディシジョン ツリーを剪定。
検証データセットを使用すると、ディシジョン ツリーの初期トレーニングに使用できるサンプル数が減ることに注意してください。
多くのモデル作成者は複数の条件を適用しています。たとえば、次のすべてを行うことができます。
- リーフあたりの最小サンプル数を適用します。
- 最大深度を適用して、ディシジョン ツリーの成長を制限します。
- ディシジョン ツリーを剪定する。
- サンプルの最小数は 5 個(
min_examples = 5
)です - トレーニング データセットの 10% は検証用に保持されます(
validation_ratio = 0.1
)。
validation_ratio=0.0
を設定すると、検証データセットでのプルーニングを無効にできます。これらの条件により、チューニングが必要な新しいハイパーパラメータ(最大ツリー深度など)が導入されます。多くの場合、ハイパーパラメータの自動チューニングが使用されます。ディシジョン ツリーは通常、クロス バリデーションでハイパーパラメータ チューニングを使用できるほどトレーニングが速いです。たとえば、「n」個のサンプルを含むデータセットの場合:
- トレーニング サンプルを重複しない p つのグループに分割します。例:
p=10
。 - すべての可能なハイパーパラメータ値(最大深度が {3,5,6,7,8,9}、最小サンプル数が {5,8,10,20} など)。
- 各グループで、他の p-1 グループでトレーニングされたディシジョン ツリーの品質を評価します。
- グループ全体の評価を平均します。
- 平均評価が最も高いハイパーパラメータ値を選択します。
- 選択したハイパーパラメータを使用して、すべての「n」個のサンプルを使用して最終的なディシジョン ツリーをトレーニングします。
このセクションでは、ディシジョン ツリーで過剰適合を制限する方法について説明しました。これらの方法にもかかわらず、過小適合と過剰適合は決定木の大きな弱点です。決定木では、過剰適合を制限する新しい方法が導入されています。この方法については後で説明します。
直接ディシジョン ツリーの解釈
ディシジョン ツリーは解釈が容易です。ただし、例をいくつか変更するだけで、決定木の構造が完全に変わり、解釈も変わる可能性があります。
ディシジョン ツリーはトレーニング例を分割して構築されるため、ディシジョン ツリーを使用して(モデルではなく)データセット自体を解釈できます。各リーフは、データセットの特定のコーナーを表します。
model.describe()
関数を使用してツリーを確認できます。model.get_tree()
を使用して個々のツリーにアクセスしてプロットすることもできます。詳細については、
YDF のモデル検査チュートリアルをご覧ください。ただし、間接的な解釈も有益です。