木のアンサンブルを用いた特徴量変換

Beginner

This tutorial is from open-source community. Access the source code

はじめに

この実験では、木のアンサンブルを使って特徴量を高次元の疎な空間に変換する方法を学びます。その後、これらの特徴量に対して線形モデルを学習します。ランダムフォレストや勾配ブースティングなど、さまざまな種類のアンサンブル手法を使い、それらの性能を比較します。

VM のヒント

VM の起動が完了したら、左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebook を使って練習しましょう。

時々、Jupyter Notebook が読み込み終わるまで数秒待つ必要があります。Jupyter Notebook の制限により、操作の検証は自動化できません。

学習中に問題に遭遇した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。

データの準備

まず、80,000 サンプルの大きなデータセットを作成し、それを 3 つのセットに分割します。

  • 後で特徴量エンジニアリングの変換器として使用されるアンサンブル手法を学習するためのセット
  • 線形モデルを学習するためのセット
  • 線形モデルをテストするためのセット。
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

X, y = make_classification(n_samples=80_000, random_state=10)

X_full_train, X_test, y_full_train, y_test = train_test_split(
    X, y, test_size=0.5, random_state=10
)

X_train_ensemble, X_train_linear, y_train_ensemble, y_train_linear = train_test_split(
    X_full_train, y_full_train, test_size=0.5, random_state=10
)

アンサンブル手法の学習

各アンサンブル手法について、推定器を 10 個、最大深さを 3 段階に設定します。

from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier

n_estimators = 10
max_depth = 3

random_forest = RandomForestClassifier(
    n_estimators=n_estimators, max_depth=max_depth, random_state=10
)
random_forest.fit(X_train_ensemble, y_train_ensemble)

gradient_boosting = GradientBoostingClassifier(
    n_estimators=n_estimators, max_depth=max_depth, random_state=10
)
_ = gradient_boosting.fit(X_train_ensemble, y_train_ensemble)

埋め込み変換器の学習

RandomTreesEmbeddingは非監督学習手法であり、個別に学習する必要はありません。

from sklearn.ensemble import RandomTreesEmbedding

random_tree_embedding = RandomTreesEmbedding(
    n_estimators=n_estimators, max_depth=max_depth, random_state=0
)

rt_model = make_pipeline(random_tree_embedding, LogisticRegression(max_iter=1000))
rt_model.fit(X_train_linear, y_train_linear)

ランダムフォレストと勾配ブースティングによる特徴量の変換

ここで、上記の埋め込みを前処理段階として使用する 2 つのパイプラインを作成します。特徴量の変換は、applyメソッドを呼び出すことによって行われます。その後、ロジスティック回帰によるランダムフォレストまたは勾配ブースティングをパイプライン化します。ただし、scikit - learn のパイプラインはtransformへの呼び出しを期待しています。したがって、applyへの呼び出しをFunctionTransformer内にラップしました。

from sklearn.preprocessing import FunctionTransformer
from sklearn.preprocessing import OneHotEncoder

def rf_apply(X, model):
    return model.apply(X)

rf_leaves_yielder = FunctionTransformer(rf_apply, kw_args={"model": random_forest})

rf_model = make_pipeline(
    rf_leaves_yielder,
    OneHotEncoder(handle_unknown="ignore"),
    LogisticRegression(max_iter=1000),
)
rf_model.fit(X_train_linear, y_train_linear)

def gbdt_apply(X, model):
    return model.apply(X)[:, :, 0]

gbdt_leaves_yielder = FunctionTransformer(
    gbdt_apply, kw_args={"model": gradient_boosting}
)

gbdt_model = make_pipeline(
    gbdt_leaves_yielder,
    OneHotEncoder(handle_unknown="ignore"),
    LogisticRegression(max_iter=1000),
)
gbdt_model.fit(X_train_linear, y_train_linear)

モデルの評価

最後に、すべてのモデルに対する異なる ROC 曲線を表示できます。

import matplotlib.pyplot as plt
from sklearn.metrics import RocCurveDisplay

fig, ax = plt.subplots()

models = [
    ("RT embedding -> LR", rt_model),
    ("RF", random_forest),
    ("RF embedding -> LR", rf_model),
    ("GBDT", gradient_boosting),
    ("GBDT embedding -> LR", gbdt_model),
]

model_displays = {}
for name, pipeline in models:
    model_displays[name] = RocCurveDisplay.from_estimator(
        pipeline, X_test, y_test, ax=ax, name=name
    )
_ = ax.set_title("ROC curve")

まとめ

この実験では、木のアンサンブルを使って特徴量を高次元の疎な空間に変換する方法を学びました。ランダムフォレストや勾配ブースティングなど、さまざまな種類のアンサンブル手法を使用し、それらの性能を比較しました。RandomTreesEmbeddingは非監督学習手法であり、個別に学習する必要はありません。また、FunctionTransformerを使って、ロジスティック回帰によるランダムフォレストまたは勾配ブースティングをパイプライン化する方法も学びました。最後に、ROC 曲線を使ってすべてのモデルの性能を評価しました。