XGBoostLSS - 確率的推論のためのXGBoost拡張とその使い方

機械学習の世界では、予測モデルの精度だけでなく、その予測に伴う不確実性を理解することが重要です。特に、金融、医療、リスク管理などの分野では、予測の信頼性を評価し、それに基づいて意思決定を行う必要があります。

XGBoostは、その高い予測精度から多くの分野で利用されている強力な機械学習アルゴリズムです。しかし、従来のXGBoostは点推定に限定されており、予測の不確実性を直接的に扱うことはできません。

そこで提案されたのが「XGBoostLSS」です。XGBoostLSSは、XGBoostを拡張し、確率的推論を可能にすることで、予測の不確実性を考慮したより高度な分析を可能にします。本稿では、XGBoostLSSの基本概念、アーキテクチャ、そして使い方について解説します。

XGBoostLSSとは?

従来のXGBoostの限界と確率的推論の重要性

XGBoostは、勾配ブースティングを用いた強力な機械学習アルゴリズムであり、その高い予測精度から多くの分野で広く利用されています。しかし、従来のXGBoostは点推定に限定されており、予測値の不確実性を直接的に扱うことはできません。現実の問題では、予測の不確実性を考慮することが不可欠な場面が多く存在します。例えば、金融リスクの評価、医療診断の精度評価、需要予測における変動幅の把握などが挙げられます。

XGBoostLSSは、このような従来のXGBoostの限界を克服し、確率的推論を可能にする拡張アルゴリズムです。これにより、予測値だけでなく、その背後にある確率分布全体を推定できるようになり、予測の不確実性をより詳細に分析できます。

XGBoostLSSのアーキテクチャ

XGBoostLSSは、位置、スケール、形状などの分布パラメータを同時に推定することで、確率分布全体をモデル化します。具体的には、以下の特徴があります。

  • 分布パラメータの同時推定: 従来のXGBoostが単一の予測値を出力するのに対し、XGBoostLSSは指定された確率分布の全てのパラメータを同時に推定します。これにより、予測値の信頼区間や分位点などを直接的に算出できます。
  • 勾配ブースティングを用いたパラメータ最適化: XGBoostと同様に、勾配ブースティングを用いて各分布パラメータを最適化します。これにより、高い予測精度を維持しながら、確率分布の推定を可能にします。
  • カスタム損失関数の実装: XGBoostLSSは、PyTorchを用いて勾配とヘッセ行列を自動的に導出するため、様々な確率分布に対応したカスタム損失関数を容易に実装できます。これにより、特定のデータ特性に合わせた柔軟なモデル構築が可能です。
  • 安定化: XGBoostLSSは勾配とヘッセ行列を最適化するため、分布パラメータの範囲によって、勾配とヘッセ行列の大きさが大きく異なる場合に、学習が不安定になる可能性があります。その為、XGBoostLSSでは勾配とヘッセ行列の安定化を実装しています。また、レスポンス変数を標準化するアプローチも提供しており、特にレスポンス変数の範囲が勾配とヘッセ行列の範囲と大きく異なる場合に有効です。
  • 実行時間: XGBoostLSSは、それぞれの分布パラメータに対して個別の決定木を学習させるため、XGBoostと比較して学習に必要な決定木の数が多くなります。よって、実行時間はXGBoostと比較して長くなる傾向があります。

XGBoostLSSは、これらの特徴により、従来のXGBoostでは困難だった確率的推論を可能にし、より高度なデータ分析と予測を実現します。

XGBoostLSSがサポートする確率分布

XGBoostLSSはPyTorchとPyroをベースに構築されており、ユーザーは様々な分布を利用する過程で、自動微分機能を活用できます。これにより、確率的モデリングと不確実性推定の選択肢が大幅に広がり、複雑な回帰タスクに取り組むことが可能になります。


XGBoostLSSは現在、以下の確率分布をサポートしています。

DistributionUsageTypeSupportNumber of Parameters
BetaBeta()Continuous (Univariate)\(y \in (0, 1)\)2
CauchyCauchy()Continuous (Univariate)\(y \in (- \infty, \infty)\)2
DirichletDirichlet(D)Continuous (Multivariate)\(y_D \in (0, 1)\)D
ExpectileExpectile()Continuous (Univariate)\(y \in (- \infty, \infty)\)Number of expectiles
GammaGamma()Continuous (Univariate)\(y \in (0, \infty)\)2
GaussianGaussian()Continuous (Univariate)
\(y \in (- \infty, \infty)\)
2
GumbelGumbel()Continuous (Univariate)
\(y \in (- \infty, \infty)\)
2
LaplaceLaplace()Continuous (Univariate)
\(y \in (- \infty, \infty)\)
2
LogNormalLogNormal()Continuous (Univariate)\(y \in (0, \infty)\)2
MixtureMixture(CompDist(), M)Continuous & Discrete Count (Univariate)\(y \in (- \infty, \infty)\)
\(y \in [0, \infty)\)
\(y \in [0, 1]\)
\(y \in (0, 1, 2, 3, \cdots)\)
CompDist + M
Multivariate Normal (Cholesky)MVN(D)Continuous (Multivariate)\(y_D \in (-\infty, \infty)\)D(D + 3)/2
Multivariate Normal (Low-Rank)MVN_LoRa(D, rank)Continuous (Multivariate)\(y_D \in (-\infty, \infty)\)D(2+rank)
Multivariate Student-TMVT(D)Continuous (Multivariate)\(y_D \in (-\infty, \infty)\)1 + D(D + 3)/2
Negative BinomialNegativeBinomial()Discrete Count (Univariate)\(y \in (0, 1, 2, 3, \cdots)\)2
PoissonPoisson()Discrete Count (Univariate)\(y \in (0, 1, 2, 3, \cdots)\)1
Spline FlowSplineFlow()Continuous & Discrete Count (Univariate)\(y \in (- \infty, \infty)\)
\(y \in [0, \infty)\)
\(y \in [0, 1]\)
\(y \in (0, 1, 2, 3, \cdots)\)
2xcount_bins + (count_bins-1) (order=quadratic) 3xcount_bins + (count_bins-1) (order=linear)
Student-TStudentT()Continuous (Univariate)
\(y \in (- \inf, \inf)\)
3
WeibullWeibull()Continuous (Univariate)\(y \in [0, \infty)\)2
Zero-Adjusted BetaZABeta()Discrete-Continuous (Univariate)\(y \in [0, 1)\)3
Zero-Adjusted GammaZAGamma()Discrete-Continuous (Univariate)\(y \in [0, \infty)\)3
Zero-Adjusted LogNormalZALN()Discrete-Continuous (Univariate)\(y \in [0, \infty)\)3
Zero-Inflated Negative BinomialZINB()Discrete-Count (Univariate)\(y \in [0, 1, 2, 3, \cdots)\)3
Zero-Inflated PoissonZIPoisson()Discrete-Count (Univariate)\(y \in [0, 1, 2, 3, \cdots)\)2

XGBoostLSSの使い方

XGBoostLSS は PyPI に Python パッケージとして公開されているので、pipコマンドから簡単にインストールすることができます。

$ pip install xgboostlss

# GitHubリポジトリから、最新版をインストールしたい場合
$ pip install git+https://github.com/StatMixedML/XGBoostLSS.git

では、お試し用のデータに California Housing dataset(住宅価格予測のためのデータセット) を使用して、XGBoostLSS の基本的な使い方を紹介します。まずは、必要なパッケージを読み込んでおきましょう。

from xgboostlss.model import *
from xgboostlss.distributions.Gaussian import *
from scipy.stats import norm
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split

import multiprocessing
import pandas as pd
import plotnine
from plotnine import *

次は、使用するデータセットの読み込みです。

california_housing = fetch_california_housing()

# 説明変数はDataFrame型にしておく
x_data = pd.DataFrame(data= np.c_[california_housing["data"]], columns=california_housing["feature_names"])
y_data = california_housing["target"]

# 学習データとテストデータに分割
x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.2)

# XGBoostで扱えるデータ型に変換
n_cpu = multiprocessing.cpu_count()
dtrain = xgb.DMatrix(x_train, label=y_train, nthread=n_cpu)
dtest = xgb.DMatrix(x_test, nthread=n_cpu)

次に、XGBoostLSS のモデルを準備します。今回は、予測対象の分布に正規分布を仮定します。

xgblss = XGBoostLSS(
    Gaussian(
        stabilization="None",  
        response_fn="exp",      
        loss_fn="nll"          
    )
)

では、モデルを学習させましょう。XGBoostLSS には、標準でハイパーパラメータのチューニング機能が実装されているで、まずはハイパーパラメータを最適化していきます。

param_dict = {
    "eta":              ["float", {"low": 1e-5,   "high": 1,     "log": True}],
    "max_depth":        ["int",   {"low": 1,      "high": 10,    "log": False}],
    "gamma":            ["float", {"low": 1e-8,   "high": 40,    "log": True}],
    "subsample":        ["float", {"low": 0.2,    "high": 1.0,   "log": False}],
    "colsample_bytree": ["float", {"low": 0.2,    "high": 1.0,   "log": False}],
    "min_child_weight": ["float", {"low": 1e-8,   "high": 500,   "log": True}],
    "booster":          ["categorical", ["gbtree"]]
}

opt_param = xgblss.hyper_opt(
    param_dict,
    dtrain,
    num_boost_round=100,        # Number of boosting iterations.
    nfold=5,                    # Number of cv-folds.
    early_stopping_rounds=20,   # Number of early-stopping rounds
    max_minutes=10,             # Time budget in minutes, i.e., stop study after the given number of minutes.
    n_trials=30 ,               # The number of trials. If this argument is set to None, there is no limitation on the number of trials.
    silence=True,               # Controls the verbosity of the trail, i.e., user can silence the outputs of the trail.
    seed=123,                   # Seed used to generate cv-folds.
    hp_seed=123                 # Seed for random number generator used in the Bayesian hyperparameter search.
)

次に、最適化されたハイパーパラメータを利用して、モデルを本学習させます。

opt_params = opt_param.copy()
n_rounds = opt_params["opt_rounds"]
del opt_params["opt_rounds"]

# Train Model with optimized hyperparameters
xgblss.train(
    opt_params,
    dtrain,
    num_boost_round=n_rounds,
)

学習が完了したら、テストデータを利用して推論してみましょう。XGBoostの点推定と異なり、XGBoostLSS では、以下のモードで推論が可能です。なお、推論結果の戻り値は DataFrame 型であることに注意してください。

  • samples:
    • 予測された確率分布から、指定された数(n_samples)のサンプルをランダムに生成します。
    • これにより、予測の不確実性を表現する複数の予測値のセットを得ることができます。
    • 例:ある商品の需要予測において、1000個のサンプルを生成することで、需要のばらつきをシミュレーションし、リスク評価などに活用できます。
  • quantiles:
    • 予測された確率分布から、指定された分位数(例:0.1, 0.5, 0.9)を計算します。
    • これにより、予測値の特定の範囲(例:10%点、中央値、90%点)を知ることができます。
    • 例:ある患者の入院期間予測において、50%点(中央値)だけでなく、10%点や90%点を計算することで、入院期間の最短・最長ケースを把握できます。
  • parameters:
    • 予測された確率分布のパラメータ(例:平均、分散)をそのまま返します。
    • これにより、予測の基礎となる確率分布の特性を直接的に分析できます。
    • 例:ある地域の気温予測において、平均気温と気温のばらつき(分散)を把握することで、気候変動の影響などを分析できます。
# Number of samples to draw from predicted distribution
n_samples = 1000
quant_sel = [0.05, 0.95] # Quantiles to calculate from predicted distribution

# Sample from predicted distribution
pred_samples = xgblss.predict(
    dtest,                          
    pred_type="samples",
    n_samples=n_samples,
    seed=123
)

# Calculate quantiles from predicted distribution
pred_quantiles = xgblss.predict(
    dtest,
    pred_type="quantiles",
    n_samples=n_samples,
    quantiles=quant_sel
)

# Return predicted distributional parameters
pred_params = xgblss.predict(
    dtest,
    pred_type="parameters"
)

また、次のようにして特徴量の重要度(Feature Importance)も計算できます。

# Feature Importance of scale parameter
xgblss.plot(
    x_test,
    parameter="scale",
    plot_type="Feature_Importance",
)

以上、XGBoostLSSについて、基本的な使い方を解説しましたが、より詳しい情報については、公式ドキュメントを参照してください。また以下のように、多くの公式のサンプルも公開されているので、業務で利用する際の参考になるかと思います。

おわりに

今回は、XGBoostを拡張し、確率的推論を可能にするXGBoostLSSについて解説しました。XGBoostLSSは、従来のXGBoostの限界を克服し、予測の不確実性を考慮したより高度な分析を可能にします。

XGBoostLSSの主なポイントは以下の通りです。

  • 位置(Location)、スケール(Scale)、形状(Shape)パラメータの同時推定により、確率分布全体をモデル化できる
  • 勾配ブースティングを用いたパラメータ最適化により、高い予測精度を維持できる
  • カスタム損失関数の実装により、様々な確率分布に対応できる

確率的推論は、金融、医療、リスク管理など、多くの分野で重要な役割を果たします。XGBoostLSSは、これらの分野における予測モデルの精度と信頼性を向上させるための強力なツールとなります。

More Information