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

このユニットでは、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 では、 Palmer Penguins データセットを使用します。このデータセットには、次の 3 種類のペンギンのサイズ測定値が含まれています。

  • あごひげ
  • 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. The first 3 example in Palmer Penguins

island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g 性交 year
撮影していない アデリー トーガーセン 3,910 万台 1,870 万台 1,810 3,750.0 男性 2007 年
1 アデリー トーガーセン 3,950 万台 1,740 万台 1,860 3,800.0 女性 2007 年
2 アデリー トーガーセン 4,030 万台 18.0 1,950 3,250.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
Adelie(赤) 8%
Gentoo(青) 58%
チンストラップ(緑) 36%

 

表 5. 異なる種の可能性 bill_depth_mm < 42.3

種族 Likelihood
Adelie(赤) 97%
Gentoo(青) 2%
チンストラップ(緑) 0%

bill_depth_mm は数値特徴です。したがって、値 42.3 は、数値特徴によるバイナリ分類の正確な分割アルゴリズムを使用して検出されました。

bill_depth_mm ≥ 42.3 が True の場合、flipper_length_mm ≥ 207.5 が Gentoos と Gentoos + 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 の例のリーフには Adelie ラベルと Chinstrap ラベルが混在しています。アルゴリズムでこのリーフをさらに分割しなかったのはなぜでしょうか。理由は 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(pandas_train_dataset)
print("Test accuracy: ", model.evaluate(pandas_test_dataset).accuracy)
# >> Test accuracy: 0.986111

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

使用量と制限事項

前述のように、ランダム フォレスト、勾配ブーストツリー、ニューラル ネットワークなどの最新の ML 手法よりも、1 つのディシジョン ツリーの品質は低くなります。ただし、ディシジョン ツリーは次のケースでも有用です。

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