mrkeyoor.com_
Wed 05 Aug 19:56 UTC
PyPIAI / MLupdated 05 Aug 2026

lightgbm

LightGBM is a gradient boosting framework built around histogram-based, leaf-wise tree growth: a C++ core with a Python package exposing both a native API (lgb.Dataset, lgb.train) and scikit-learn estimators (LGBMClassifier, LGBMRegressor, LGBMRanker). On tabular data it usually trains faster and uses less memory than other boosting libraries at comparable accuracy, handles categorical features without one-hot encoding, and supports distributed and GPU training. It moved from the Microsoft org to lightgbm-org on GitHub in March 2026 under the same maintainers.

Verdict

The speed choice for gradient boosting on CPU and the default for large tabular and ranking workloads, with maintenance continuing under a community org after leaving Microsoft. Pick xgboost if an easy GPU wheel matters more than raw CPU throughput.

API stability4/5Core APIs are stable and the project follows EffVer versioning with clearly flagged breaks, but 4.0 removed fit() arguments (early_stopping_rounds, verbose) in favor of callbacks, invalidating years of tutorials and answers.
Docs4/5readthedocs covers installation, parameters, tuning, GPU and distributed learning in depth, and the parameters page is the canonical reference; like most boosting docs it is exhaustive rather than opinionated, so practical tuning advice comes from the community.
Maintenance4/5Pushed the day before this review with regular releases, and the March 2026 move to lightgbm-org kept the same maintainers including the original creator; the backlog of around five hundred open issues and PRs shows a small team behind a big project.
Ecosystem5/5Optuna and FLAML tuners, SHAP explanations, ONNX/PMML/Treelite/lleaves converters, Spark (SynapseML), Ray and Dask integrations, R, Julia, Rust and .NET bindings, and time series wrappers like mlforecast and darts all target it.

Use it if

  • You train on large tabular datasets where CPU speed is the bottleneck: leaf-wise histogram growth is typically the fastest of the major boosting libraries
  • Your features include categoricals you do not want to encode: pandas category columns are handled natively and usually beat one-hot encoding on both speed and accuracy
  • You need learning-to-rank: LGBMRanker with the lambdarank objective is a production standard for search and recommendation ranking
  • Memory is tight: histogram binning keeps the training footprint well below equivalent exact-split implementations
Skip it if

Setup reality

The pip wheel is compact and CPU-only; that is pleasant until you want GPU, which requires building with CMake plus OpenCL or CUDA, or pip install with --config-settings flags, and it is the single biggest source of setup questions. On macOS you need libomp from Homebrew, and mismatched libomp copies across ML libraries have caused segfaults. API churn to know: 4.x removed early_stopping_rounds and verbose from fit(), so you pass callbacks=[lgb.early_stopping(50), lgb.log_evaluation(100)] instead, and sklearn-wrapper models warn if prediction-time feature names differ from training. The GitHub org also changed to lightgbm-org in March 2026; old Microsoft links redirect.

Patterns

Train a classifier with the sklearn APItrain-classifier

from lightgbm import LGBMClassifier
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

model = LGBMClassifier(n_estimators=500, learning_rate=0.05, num_leaves=31)
model.fit(X_train, y_train)
print(model.score(X_test, y_test))

num_leaves is the main capacity knob, not max_depth; the default 31 is sane, and doubling it without raising min_data_in_leaf is the classic overfit.

Early stopping with callbacks (4.x style)early-stopping

import lightgbm as lgb

model = lgb.LGBMClassifier(n_estimators=2000, learning_rate=0.05)
model.fit(
    X_train, y_train,
    eval_set=[(X_val, y_val)],
    eval_metric='auc',
    callbacks=[lgb.early_stopping(50), lgb.log_evaluation(100)],
)
print(model.best_iteration_)

Passing early_stopping_rounds or verbose directly to fit() was removed in 4.0; callbacks are the only supported route now.

Native API with lgb.Datasetnative-train-api

import lightgbm as lgb

train_set = lgb.Dataset(X_train, label=y_train)
val_set = lgb.Dataset(X_val, label=y_val, reference=train_set)

booster = lgb.train(
    {'objective': 'binary', 'learning_rate': 0.05, 'num_leaves': 31},
    train_set,
    num_boost_round=2000,
    valid_sets=[val_set],
    callbacks=[lgb.early_stopping(50)],
)
preds = booster.predict(X_test)

Validation Datasets should pass reference=train_set so they share bin edges; predict returns probabilities for binary objectives, threshold them yourself.

Use categorical columns without one-hot encodingcategorical-features

import pandas as pd

X = df.copy()
for col in ['city', 'plan']:
    X[col] = X[col].astype('category')

model = LGBMClassifier()
model.fit(X, y)  # category dtype columns are auto-detected

Auto-detection needs pandas category dtype; plain object columns raise. Category codes must match between train and predict, so persist the dtype categories.

Cross-validate boosting roundscross-validation

import lightgbm as lgb

cv = lgb.cv(
    {'objective': 'binary', 'learning_rate': 0.05, 'metric': 'auc'},
    lgb.Dataset(X, label=y),
    num_boost_round=1000,
    nfold=5,
    callbacks=[lgb.early_stopping(50)],
)
print(len(cv['valid auc-mean']), cv['valid auc-mean'][-1])

lgb.cv returns a dict of metric lists; the list length is the surviving round count to reuse when fitting the final model.

Feature importance by gainfeature-importance

import pandas as pd

imp = pd.Series(
    model.booster_.feature_importance(importance_type='gain'),
    index=model.booster_.feature_name(),
)
print(imp.sort_values(ascending=False).head(10))

The sklearn attribute feature_importances_ uses split counts by default, which favors high-cardinality features; gain is usually what you actually want, and SHAP is better still for decisions.

Save and load a model safelysave-load-model

model.booster_.save_model('model.txt')

import lightgbm as lgb
booster = lgb.Booster(model_file='model.txt')
preds = booster.predict(X_new)

The text model format survives library upgrades; pickling the sklearn wrapper works within a version but is fragile across them.

Handle class imbalanceimbalanced-classes

neg, pos = (y_train == 0).sum(), (y_train == 1).sum()

model = LGBMClassifier(
    scale_pos_weight=neg / pos,  # or is_unbalance=True
)
model.fit(X_train, y_train, eval_set=[(X_val, y_val)], eval_metric='average_precision')

Use scale_pos_weight or is_unbalance, never both. Reweighting skews predicted probabilities, so recalibrate if you need real probabilities rather than a ranking.

Predict quantiles instead of the meanquantile-regression

from lightgbm import LGBMRegressor

p90 = LGBMRegressor(objective='quantile', alpha=0.9, n_estimators=500)
p90.fit(X_train, y_train)

p10 = LGBMRegressor(objective='quantile', alpha=0.1, n_estimators=500)
p10.fit(X_train, y_train)
# p10/p90 predictions form a rough 80% interval

One model per quantile; nothing forces the quantile curves not to cross, so sanity-check intervals before shipping them.

Learning-to-rank with LGBMRankerranking-lambdarank

from lightgbm import LGBMRanker

# group = number of rows per query, in row order
ranker = LGBMRanker(objective='lambdarank', n_estimators=500)
ranker.fit(
    X_train, y_train,
    group=train_group_sizes,
    eval_set=[(X_val, y_val)],
    eval_group=[val_group_sizes],
    eval_at=[10],
)

Rows must be sorted so each query's documents are contiguous and group sizes sum to the row count; labels are relevance grades (0, 1, 2, ...), not clicks.

The parameters that actually mattertune-key-parameters

model = LGBMClassifier(
    n_estimators=2000,        # large, rely on early stopping
    learning_rate=0.05,
    num_leaves=63,            # capacity; pair with min_data_in_leaf
    min_data_in_leaf=50,      # overfitting brake
    feature_fraction=0.8,     # column subsampling
    bagging_fraction=0.8,
    bagging_freq=1,
)

num_leaves, learning_rate and min_data_in_leaf carry most of the signal; for serious tuning use Optuna's LightGBM tuner, which the docs point to.

Alternatives

PackageRegistryPick it when
xgboostPyPIComparable accuracy with CUDA support included in the standard wheel and a larger deployment tooling ecosystem
catboostPyPIHigh-cardinality categorical features and strong defaults with minimal tuning effort
scikit-learnPyPIHistGradientBoosting, itself inspired by LightGBM, covers everyday cases with no extra dependency