CatBoost
CatBoostは、Yandexが開発したオープンソースの勾配ブースティングライブラリです。順序付きターゲット統計を使ってカテゴリ特徴量をエンコードし、対称木を成長させます。
CatBoostは、Yandexが開発し、2017年に公開した、勾配ブースティングによる決定木のオープンソースライブラリです。名前は「categorical boosting」に由来します。都市名、商品ID、デバイス種別などのカテゴリ列を文字列のまま受け取り、内部で数値に変換するため、表形式データを学習する前に手動でone-hotエンコーディングやターゲットエンコーディングを行う必要がありません。NeurIPS 2018の論文で紹介された順序付きターゲット統計と順序付きブースティングという2つの手法は、各学習行のラベルが、その行の学習に使う数値に含まれないようにします。このような漏洩は、通常のターゲットエンコーディングと標準的なブースティングの両方にバイアスをもたらします。CatBoostはCPUとGPUで学習でき、Python、R、コマンドラインのインターフェースを備え、分類、回帰、ランキングに対応しています。
CatBoostによるカテゴリ特徴量のエンコード方法#
one-hotエンコーディングではカテゴリごとに1列を作成するため、加盟店IDやユーザーIDなど数千種類の値を持つ特徴量では扱いが煩雑になります。ターゲットエンコーディングでは、各カテゴリを、そのカテゴリに属する行のラベル平均に置き換えます。これはコンパクトですが、行自身のラベルがその行を表す数値に含まれるため、答えが漏洩します。その結果、モデルは新しいデータで通用しない近道を学習します。これはデータリークの一種で、過学習として表れ、希少なカテゴリで特に深刻になります。
CatBoostの順序付きターゲット統計では、学習行をランダムに並べ替えることでこの問題を解決します。各行のカテゴリは、その並べ替えで前に位置する行のラベルだけを使ってエンコードし、事前分布に向けて平滑化するため、その行自身のラベルが使われることはありません。CatBoostはこの処理を複数の並べ替えで繰り返し、異なる値が非常に少ない特徴量はone-hotエンコードします。また、都市とデバイス種別の組み合わせなど、カテゴリ特徴量の組み合わせを貪欲に構築し、学習中に新しい特徴量として追加します。
CatBoost Pythonパッケージでは、cat_featuresを介してカテゴリ列を名前で渡します。この例では、50種類のサブスクリプションプランそれぞれに固有の非公開の解約率を設定し、プラン名の生データからモデルがその率を復元できるかを確認します。
import numpy as np
import pandas as pd
from catboost import CatBoostClassifier
# Synthetic churn data: each of 50 plans has its own hidden churn rate
rng = np.random.default_rng(0)
rates = rng.uniform(0.05, 0.6, size=50)
plan_ids = rng.integers(0, 50, size=5000)
X = pd.DataFrame({"plan": [f"plan_{i}" for i in plan_ids], "tenure_months": rng.integers(1, 60, size=5000)})
y = rng.random(5000) < rates[plan_ids]
# Raw strings go in directly; CatBoost encodes them with ordered target statistics
model = CatBoostClassifier(iterations=200, depth=4, verbose=0, random_seed=0)
model.fit(X, y, cat_features=["plan"])
# Compare true and predicted churn for the safest and riskiest plans
lo, hi = rates.argmin(), rates.argmax()
probe = pd.DataFrame({"plan": [f"plan_{lo}", f"plan_{hi}"], "tenure_months": [30, 30]})
print("True churn rates: ", rates[[lo, hi]].round(2))
print("Predicted churn rates:", model.predict_proba(probe)[:, 1].round(2))スクリプトは真の率として0.05と0.60、予測率として0.06と0.59を出力します。プランごとに学習行が約100件しかない場合でも、モデルは文字列のままの列から各プランの解約率を復元しました。
順序付きブースティングと対称木#
標準的な勾配ブースティングでは、新しい木の目的変数となる損失の勾配を、先行する木の学習にも使った同じ行から計算します。これにより勾配にバイアスが生じます。CatBoostの著者はこの現象を予測シフトと呼んでいます。順序付きブースティングでは、並べ替えの前にある行だけで学習したモデルから各行の勾配を求めるという、順列を使った手法を再び適用します。これは学習オプションboosting_type="Ordered"で、小規模なデータセットでは品質が向上することが多い一方、速度は低下します。CPUでは従来の"Plain"方式がデフォルトです。GPU学習では、マルチクラスモードを除き、行数が50,000以下のデータセットで"Ordered"がデフォルトです。
CatBoostはデフォルトで、対称木またはoblivious treeを成長させます。この木では、同じ深さにあるすべてのノードで同じ分岐条件を使います。そのため、デフォルトの深さ6の木は、6つのyes/no判定の答えを64個の葉への6ビットのインデックスとして扱う構造になり、予測が速く、各木の複雑さも制限されます。これは正則化の一種です。grow_policyパラメーターを使うと、データセットに制約の緩い木が必要な場合に、深さ優先または葉優先の成長方式に切り替えられます。
実際のアプリケーション#
- 信用リスク:貸し手は、職業、地域、ローンの目的など、申込者のカテゴリ項目と、収入や負債の数値を組み合わせて債務不履行を予測します。職業コードを数百個もone-hotエンコードする必要はありません。
- ランキングとレコメンデーション:CatBoostはYetiRankなどのランキング損失を提供します。これらは、ユーザー、アイテム、コンテキストの特徴量から予測した関連度に基づき、レコメンデーションシステムの検索結果や商品を並べ替えるために使われます。
- 不動産価格評価:YOLO26でカスタム学習した検出器は、物件写真からプールやソーラーパネルなどの設備を数えられます。その数を、近隣地域や物件種別などのカテゴリ列とともに、数値列としてCatBoostの価格モデルに入力できます。
CatBoostとXGBoostおよびLightGBMの比較#
3つのライブラリはいずれも、木を順次構築してアンサンブルを作ります。各木はその前にある木の誤差を修正するため、独立して学習した木を使うランダムフォレストとは異なります。
- XGBoost:デフォルトではレベルごとに木を成長させ、目的関数にL1正則化とL2正則化を加えます。ネイティブなカテゴリ対応は後のバージョンで追加されましたが、学習前にカテゴリをエンコードするパイプラインは今も多く使われています。
- LightGBM:損失を最も減らす葉を選んで分割する葉優先方式で木を成長させ、特徴量をヒストグラムにビン分割するため、大規模なデータセットでも高速です。整数にエンコードしたカテゴリ列もネイティブに受け付けます。
- CatBoost:対称木を構築し、順序付きターゲット統計でカテゴリをエンコードします。また、ハイパーパラメーター調整を行う前から高い性能を発揮します。デフォルトでは深さ6の木を1,000本使い、対数損失、マルチクラス、RMSEの目的関数では、反復回数に基づいて学習率が自動的に選択されます。










