ディシジョン ツリーを作成する

このユニットでは、YDF(Yggdrasil デシジョン フォレスト)ライブラリを使用して、ディシジョン ツリーをトレーニングして解釈します。

このユニットは、🧭 YDF スタートガイドのチュートリアルを参考にしています。

準備

データセットを学習する前に、次の操作を行います。

  1. 新しい Colab ノートブックを作成します。
  2. 新しい Colab ノートブックに次のコード行を配置して実行し、YDF ライブラリをインストールします。
    !pip install ydf -U
  3. 次のライブラリをインポートします。
    import ydf
    import numpy as np
    import pandas as pd

Palmer Penguins データセット

この Colab では、3 種類のペンギンのサイズ測定値を含む Palmer Penguins データセットを使用します。

  • ヒゲペンギン
  • Gentoo
  • アデリー

これは分類問題です。目標は、Palmer's Penguins データセットのデータに基づいてペンギンの種を予測することです。ペンギンは次のとおりです。

3 種類のペンギン。

図 16. 3 種類のペンギン。@allisonhorst さんの画像

 

次のコードは、pandas 関数を呼び出して、Palmer Penguins データセットをメモリに読み込みます。

path = "https://storage.googleapis.com/download.tensorflow.org/data/palmer_penguins/penguins.csv"
dataset = pd.read_csv(path)
label = "species"

# Display the first 3 examples.
dataset.head(3)

次の表は、Palmer Penguins データセットの最初の 3 つの例をフォーマットしたものです。

表 3. Palmer Penguins の最初の 3 つの例

island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g 性別
撮影していない アデリー Torgersen 39.1 18.7 181.0 3750.0 男性 2007
1 アデリー Torgersen 39.5 17.4 186.0 3800.0 女性 2007
2 アデリー Torgersen 40.3 18.0 195.0 3250.0 女性 2007

完全なデータセットには、数値(bill_depth_mm など)、カテゴリ(island など)、欠損値の特徴が混在しています。ニューラル ネットワークとは異なり、決定フォレストはこれらのすべての特徴タイプをネイティブにサポートしているため、ワンホット エンコーディング、正規化、追加の is_present 特徴を行う必要はありません。

次のコードセルは、データセットをトレーニング セットとテストセットに分割します。

# Use the ~20% of the examples as the testing set
# and the remaining ~80% of the examples as the training set.
np.random.seed(1)
is_test = np.random.rand(len(dataset)) < 0.2

train_dataset = dataset[~is_test]
test_dataset = dataset[is_test]

print("Training examples: ", len(train_dataset))
# >> Training examples: 272

print("Testing examples: ", len(test_dataset))
# >> Testing examples: 72

デフォルトのハイパーパラメータを使用してディシジョン ツリーをトレーニングする

ハイパーパラメータを指定せずに、CART(分類回帰木)学習アルゴリズム(学習者とも呼ばれます)を使用して最初の決定木をトレーニングできます。これは、ydf.CartLearner 学習器が適切なデフォルトのハイパーパラメータ値を提供するためです。このタイプのモデルの仕組みについては、コースの後半で詳しく説明します。

model = ydf.CartLearner(label=label).train(train_dataset)

上記の呼び出しでは、入力特徴として使用する列を指定していません。したがって、トレーニング セットのすべての列が使用されます。また、入力特徴のセマンティクス(数値、カテゴリ、テキストなど)も指定されていませんでした。そのため、特徴のセマンティクスは自動的に推論されます。

model.plot_tree() を呼び出して、結果の意思決定ツリーを表示します。

model.plot_tree()

Colab では、マウスを使用して、各ノードのクラス分布などの特定の要素に関する詳細情報を表示できます。

デフォルトのハイパーパラメータでトレーニングされたディシジョン ツリー。

図 17. デフォルトのハイパーパラメータでトレーニングされたディシジョン ツリー。

Colab には、ルート条件に 243 個の例が含まれていることが示されています。ただし、トレーニング データセットには 272 個の例が含まれていました。残りの 29 個の例は、検証とツリーの剪定のために自動的に予約されています。

最初の条件は bill_depth_mm の値をテストします。表 4 と表 5 は、最初の条件の結果に応じて異なる種が生じる可能性を示しています。

表 4. bill_depth_mm ≥ 42.3 の場合の各種の可能性

Likelihood
アデリーペンギン(赤) 8%
Gentoo(青) 58%
Chinstrap(緑) 36%

 

表 5. bill_depth_mm < 42.3 の場合のさまざまな種の可能性

Likelihood
アデリーペンギン(赤) 97%
Gentoo(青) 2%
Chinstrap(緑) 0%

bill_depth_mm は数値特徴です。したがって、値 42.3 は、数値特徴を使用したバイナリ分類の正確な分割アルゴリズムを使用して見つかりました。

bill_depth_mm ≥ 42.3 が True の場合、flipper_length_mm ≥ 207.5 が Gentoo と Gentoo+Adelie をほぼ完全に分離できるかどうかをさらにテストします。

次のコードは、モデルのトレーニング精度とテスト精度を示します。

train_evaluation = model.evaluate(train_dataset)
print("train accuracy:", train_evaluation.accuracy)
# >> train accuracy:  0.9338

test_evaluation = model.evaluate(test_dataset)
print("test accuracy:", test_evaluation.accuracy)
# >> test accuracy:  0.9167

テスト精度がトレーニング精度よりも高くなることはまれですが、あり得ます。この場合、テストセットはトレーニング セットと異なる可能性があります。ただし、ここではトレーニングとテストがランダムに分割されているため、このケースには当てはまりません。考えられる説明としては、テスト データセットが非常に小さいため(72 個の例のみ)、精度推定にノイズが含まれていることが挙げられます。

実際には、このような小さなデータセットの場合、より正確な評価指標値を計算できるため、交差検証を使用することをおすすめします。ただし、この例では、簡潔にするためにトレーニングとテストを続行します。

モデルのハイパーパラメータを改善する

このモデルは、デフォルトのハイパーパラメータ値でトレーニングされた単一のディシジョン ツリーです。予測の精度を高めるには、次の操作を行います。

  1. ランダム フォレスト勾配ブーストツリー モデルなど、より強力な学習者を使用します。これらの学習アルゴリズムについては、次のページで説明します。

  2. 観測と直感に基づいてハイパーパラメータを最適化します。モデル改善ガイドが役立ちます。

  3. ハイパーパラメータ チューニングを使用して、多数のハイパーパラメータの候補を自動的にテストします。

ランダム フォレスト アルゴリズムとグラデーション ブースト ツリー アルゴリズムはまだ確認しておらず、自動ハイパーパラメータ チューニングを行うにはサンプル数が少なすぎるため、モデルを手動で改善します。

上記のディシジョン ツリーは小さく、61 個の例を含むリーフにはアデリーとヒゲペンギンのラベルが混在しています。アルゴリズムがこのリーフをさらに分割しなかったのはなぜですか?理由は 2 つ考えられます。

  • リーフあたりの最小サンプル数(デフォルトでは min_examples=5)に達した可能性があります。
  • 過適合を防ぐために、ツリーが分割されてからプルーニングされた可能性があります。

最小サンプル数を 1 に減らして、結果を確認します。

model = ydf.CartLearner(label=label, min_examples=1).train(train_dataset)
model.plot_tree()

min_examples=1 でトレーニングされたディシジョン ツリー。

図 18. min_examples=1 でトレーニングされたディシジョン ツリー。

 

61 個の例を含むリーフノードが複数回分割されています。

ノードをさらに分割する価値があるかどうかを確認するために、テスト データセットでこの新しいモデルの品質を評価します。

print(model.evaluate(test_dataset).accuracy)
# >> 0.97222

テスト精度が 0.9167 から 0.97222 に向上し、モデルの品質が向上しました。このハイパーパラメータの変更は良いアイデアでした。

デシジョン フォレストのプレビュー

ハイパーパラメータを改善し続けることで、完全な精度に達する可能性があります。ただし、この手動プロセスではなく、ランダム フォレストなどのより強力なモデルをトレーニングして、より良い結果が得られるかどうかを確認できます。

model = ydf.RandomForestLearner(label=label).train(train_dataset)
print("Test accuracy: ", model.evaluate(test_dataset).accuracy)
# >> Test accuracy: 0.986111

ランダム フォレストの精度は、単純なツリーよりも優れています。その理由については、次のページで説明します。

使用量と制限事項

前述のように、単一のディシジョン ツリーは、ランダム フォレスト、勾配ブースト ツリー、ニューラル ネットワークなどの最新の ML メソッドよりも品質が低いことがよくあります。ただし、決定木は次のような場合に有用です。

  • より複雑なアプローチを評価するためのシンプルで安価なベースラインとして。
  • モデルの品質と解釈可能性の間にトレードオフがある場合。
  • デシジョン フォレスト モデルの解釈のプロキシとして。このコースでは後ほど詳しく説明します。