LightGBMLSS

repository·master·Indexed 18 days ago

https://github.com/statmixedml/lightgbmlss

A Python framework extending LightGBM for probabilistic modelling of univariate targets. It enables the estimation of full conditional distributions using a variety of continuous, discrete, and mixed distributions, including Mixture-Densities and Normalizing Flows. The library utilizes PyTorch for automatic differentiation of Gradients and Hessians, integrates with Optuna for hyperparameter optimization, and supports model interpretability via SHAP.

Tokens
7.3K
Snippets
23
Records
31
Agent score
63%

What's inside lightgbmlss

  1. Overview of LightGBMLSS features

    master

    LightGBMLSS is an extension of LightGBM designed for probabilistic modelling. It models the full conditional distribution of a univariate target as a function of covariates, allowing for probabilistic forecasts, prediction intervals, and quantiles.

    Key capabilities include:

    • Distributional Estimation: Estimates all parameters of chosen distributions.
    • Complex Distributions: Supports Normalizing Flows (for multi-modal distributions), Mixture-Densities, and Zero-Adjusted/Zero-Inflated distributions (for excess zeros).
    • Automatic Differentiation: Uses PyTorch to automatically derive Gradients and Hessians of all distributional parameters.
    • Optimization & Explainability: Integrates with Optuna for automated hyper-parameter search and SHAP (SHapley Additive exPlanations) for model interpretability.
    • Compatibility: Maintains full compatibility with standard LightGBM features.
  2. What is Distributional Gradient Boosting?

    master

    Distributional Gradient Boosting Machines extend standard LightGBM to model the entire conditional distribution $F_{Y}(y|\mathbf{x})$ of a response variable, rather than just the conditional mean $\mathbb{E}(Y|\mathbf{X} = \mathbf{x})$.

    While standard regression models (like those using $\ell_{2}$ loss) assume a Normal distribution with constant variance, distributional modeling allows for the estimation of higher moments such as heteroskedasticity (varying variance), skewness, and kurtosis. This is achieved by modeling all distributional parameters as functions of the explanatory variables $\mathbf{x}$.

  3. Understand LightGBMLSS runtime complexity

    master

    LightGBMLSS uses a one vs. all estimation strategy. This means a separate tree is grown for every distributional parameter being estimated.

    Runtime Comparison:

    • LightGBM: Trains [number of iterations] trees.
    • LightGBMLSS: Trains [number of iterations] * [number of distributional parameters] trees.

    As a result, the training runtime for LightGBMLSS is generally higher than standard LightGBM, scaling linearly with the number of parameters in the chosen distribution.

  4. Use Normalizing Flows for complex non-parametric distributions

    master

    When parametric distributions (like those in GAMLSS) are not flexible enough to approximate complex or multi-modal distributions, Normalizing Flows can be used to approximate the data non-parametrically.

    Normalizing Flows transform a simple base distribution (e.g., a standard Normal $N(0,1)$) into a complex target distribution $F_{Y}(\mathbf{y})$ through a series of bijective (invertible) transformations $h_{j}$.

    Implementation Details:

    • The framework uses element-wise rational splines of linear or quadratic order.
    • This approach is implemented via Pyro.
    • It allows for sampling from the complex distribution by applying the inverse transformations to samples from the base distribution.
  5. How LightGBMLSS models parameters

    master

    LightGBMLSS (LightGBM for Location, Scale and Shape) uses a multi-parameter optimization approach. Instead of predicting a single value, the framework grows a separate tree for each parameter of a specified distribution.

    Key characteristics of the modeling process:

    • Simultaneous Estimation: Gradients, Hessians, and loss function evaluations are performed simultaneously for all parameters.
    • Automatic Differentiation: Gradients and Hessians (the first and second order derivatives of the log-likelihood) are derived using PyTorch's automatic differentiation. This allows for the use of custom parametric distributions or Normalizing Flows without manual derivation.
    • Stability via Offsets: To improve convergence and stability, the model uses unconditional Maximum Likelihood estimates of the parameters as offset values.
    • Interpretability: The framework provides attribute importance and partial dependence plots using the Shapley-Value (SHAP) approach to help understand the data generating process.
  6. Use Mixture Distributions for multi-modal data

    master

    Mixture distributions (or mixture densities) extend univariate modeling by allowing the data to arise from multiple underlying processes. This is useful when a single parametric distribution cannot capture the data, such as when the distribution is multi-modal.

    A mixture distribution is a weighted combination of $M$ component distributions:

    $$f\bigl(y_{i} | \boldsymbol{\theta}{i}(x{i})\bigr) = \sum_{m=1}^{M} w_{i,m}(x_{i}) \cdot f_{m}\bigl(y_{i} | \boldsymbol{\theta}{i,m}(x{i})\bigr)$$

    Key components:

    • Component Densities ($f_m$): Each component has its own parameters $\boldsymbol{\theta}_{i,m}$ that depend on covariates.
    • Mixing Coefficients ($w_{i,m}$): Weights that indicate the importance of each component, also modeled as functions of covariates.

    LightGBMLSS supports combinations like Gaussian-Mixture or StudentT-Mixture, where the same distribution type is used with different parameterizations.

  7. Understand GAMLSS for Univariate Targets

    master

    Generalized Additive Models for Location, Scale and Shape (GAMLSS) is a framework used to model the entire conditional distribution of a univariate response $y$.

    In this framework, the response $y$ follows a distribution $\mathcal{D}(\boldsymbol{\theta}(x))$ where the parameters $\boldsymbol{\theta}(x)$ are functions of covariates. A distribution can be characterized by up to four parameters:

    • Location ($\mu$): The central tendency.
    • Scale ($\sigma^2$): The spread or variance.
    • Shape ($\nu, \tau$): Parameters representing skewness and kurtosis.

    Unlike Generalized Linear Models (GLM), GAMLSS relaxes the assumption of the exponential family, allowing for highly skewed, kurtotic, discrete, or zero-inflated distributions. LightGBMLSS extends this by using tree-based models to estimate these parameters $\eta_{k} = f_{k}(\mathbf{x})$.

  8. Improve convergence and stability in LightGBMLSS

    master

    LightGBMLSS optimizes Gradients and Hessians to update parameter estimates. If these values have highly variable magnitudes across different distributional parameters, convergence may become unstable or slow.

    To mitigate this, you can use two approaches:

    1. Built-in Stabilization: LightGBMLSS includes internal mechanisms to stabilize Gradients and Hessians.
    2. Response Standardization: Manually standardize your continuous response variable (e.g., by dividing it by a constant like y/100). This is particularly effective when the response range differs significantly from the range of the Gradients and Hessians.

    It is recommended to evaluate both techniques based on your specific dataset.

  9. Install LightGBMLSS

    master

    To install LightGBMLSS, install it directly from the GitHub repository using pip. If you intend to use SHAP for model explanations, you must also install the shap dependency from its source.

    pip install git+https://github.com/StatMixedML/LightGBMLSS.git
    pip install git+https://github.com/dsgibbons/shap.git
  10. Train a model with optimized hyperparameters

    master

    After running hyper_opt, the resulting opt_param dictionary contains the best parameters found, including a special key "opt_rounds" which represents the optimal number of boosting rounds. To train the model, you must copy the dictionary and remove the "opt_rounds" key before passing it to lgblss.train.

    # Assume opt_param was returned from hyper_opt
    opt_params = opt_param.copy()
    n_rounds = opt_params["opt_rounds"]
    del opt_params["opt_rounds"]
    
    lgblss.train(opt_params, dtrain, num_boost_round=n_rounds)
  11. Supported univariate distributions in LightGBMLSS

    master

    LightGBMLSS supports a wide variety of univariate distributions for probabilistic modeling and uncertainty estimation, built upon PyTorch and Pyro. These distributions are categorized by their type (Continuous, Discrete Count, or Discrete-Continuous) and their support (the range of possible values for $y$).

    When selecting a distribution, consider the support of your target variable $y$ and the number of parameters required for the model.

    | Distribution | Usage | Type | Support | Number of Parameters |
    |:---|:---|:---|:---|:---|
    | Beta | `Beta()` | Continuous | $y \in (0, 1)$ | 2 |
    | Cauchy | `Cauchy()` | Continuous | $y \in (-\infty,\infty)$ | 2 |
    | Expectile | `Expectile()` | Continuous | $y \in (-\infty,\infty)$ | Number of expectiles |
    | Gamma | `Gamma()` | Continuous | $y \in (0, \infty)$ | 2 |
    | Gaussian | `Gaussian()` | Continuous | $y \in (-\infty,\infty)$ | 2 |
    | Gumbel | `Gumbel()` | Continuous | $y \in (-\infty,\infty)$ | 2 |
    | Laplace | `Laplace()` | Continuous | $y \in (-\infty,\infty)$ | 2 |
    | Logistic | `Logistic()` | Continuous | $y \in (-\infty,\infty)$ | 2 |
    | LogNormal | `LogNormal()` | Continuous | $y \in (0,\infty)$ | 2 |
    | Mixture | `Mixture(CompDist(), M)` | Continuous & Discrete Count | $y \in (-\infty,\infty)$, $[0, \infty)$, $(0, 1)$, or $[0, 1, 2, \dots)$ | CompDist + M |
    | Negative Binomial | `NegativeBinomial()` | Discrete Count | $y \in [0, 1, 2, 3, \dots)$ | 2 |
    | Poisson | `Poisson()` | Discrete Count | $y \in [0, 1, 2, 3, \dots)$ | 1 |
    | Spline Flow | `SplineFlow()` | Continuous & Discrete Count | $y \in (-\infty,\infty)$, $[0, \infty)$, $(0, 1)$, or $[0, 1, 2, \dots)$ | 2xcount_bins + (count_bins-1) (quadratic) or 3xcount_bins + (count_bins-1) (linear) |
    | Student-T | `StudentT()` | Continuous | $y \in (-\infty,\infty)$ | 3 |
    | Weibull | `Weibull()` | Continuous | $y \in [0, \infty)$ | 2 |
    | Zero-Adjusted Beta | `ZABeta()` | Discrete-Continuous | $y \in [0, 1)$ | 3 |
    | Zero-Adjusted Gamma | `ZAGamma()` | Discrete-Continuous | $y \in [0, \infty)$ | 3 |
    | Zero-Adjusted LogNormal | `ZALN()` | Discrete-Continuous | $y \in [0, \infty)$ | 3 |
    | Zero-Inflated Negative Binomial | `ZINB()` | Discrete-Count | $y \in [0, 1, 2, 3, \dots)$ | 3 |
    | Zero-Inflated Poisson | `ZIPoisson()` | Discrete-Count | $y \in [0, 1, 2, 3, \dots)$ | 2 |
  12. Select a univariate distribution using dist_select

    master

    To find the best-fitting distribution for a univariate target variable, use the dist_select method from DistributionClass.

    1. Define a list of candidate distribution classes (e.g., Gaussian, StudentT, Gamma).
    2. Call dist_select passing your training target data and the list of candidates.
    3. The method returns the negative log-likelihood (NLL) for each distribution. The distribution with the lowest NLL is considered the best fit.
    4. If plot=True is passed, the method will visualize the density of the target variable against the fitted density of the best-selected distribution.

    Note on selection: Choose candidate distributions based on the nature of your data. For count data, include Poisson or NegativeBinomial. For positive real-scale data, select appropriate continuous distributions.

    from lightgbmlss.distributions import *
    from lightgbmlss.distributions.distribution_utils import DistributionClass
    
    # Initialize the distribution utility class
    lgblss_dist_class = DistributionClass()
    
    # Define candidate distributions
    candidate_distributions = [Gaussian, StudentT, Gamma, Cauchy, LogNormal, Weibull, Gumbel, Laplace]
    
    # Select the best distribution based on negative log-likelihood
    dist_nll = lgblss_dist_class.dist_select(
        target=y_train, 
        candidate_distributions=candidate_distributions, 
        max_iter=50, 
        plot=True, 
        figure_size=(10, 5)
    )
    
    print(dist_nll)