lightgbm review
LightGBM 4.7.0 is a compiled gradient-boosted tree engine for tabular classification, regression, and ranking. Python users can choose the native `Dataset` and `train()` API or scikit-learn estimators such as `LGBMClassifier` and `LGBMRanker`. Trees grow leaf-wise from histogram bins, and categorical columns can stay categorical instead of becoming one-hot matrices. Version 4.7 adds Polars and Arrow input support, `decision_function()`, the first ROCm builds, and NVIDIA multi-GPU training through NCCL. Our sandbox import finished in 1.33 seconds after a 180 MB install.
LightGBM 4.7.0 installed in 2.1 seconds as 4 packages and imported in 1.33 seconds with 0 known vulnerabilities in our sandbox. It is a strong fit for tabular boosting and ranking, but compiled-platform constraints and 4.7's evaluation API transition make XGBoost or scikit-learn easier in some deployments.
We installed it
| Install | ✓ · 2.1s | 4 packages on disk · 180 MB |
| Import | ✓ | import lightgbm in 1.33s · compiled extensions · py.typed · requires Python >=3.10 |
| Known vulns | 0 | (pip-audit) |
Answers from our run
Does lightgbm install cleanly?
Yes. In a fresh container with an empty cache, pip install lightgbm finished in 2 seconds, leaving 4 packages and 180 MB on disk. pip-audit reported no known vulnerabilities.
What does lightgbm need to run?
Python >=3.10, and a platform wheel with compiled extensions. In our run import lightgbm succeeded in 1.33s, and the package ships py.typed for type checkers.
lightgbm or xgboost: which should you use?
xgboost: Choose XGBoost when its wheel, CUDA path, and deployment converters fit your platform better. LightGBM 4.7.0 installed in 2.1 seconds as 4 packages and imported in 1.33 seconds with 0 known vulnerabilities in our sandbox.
When should you not use lightgbm?
Your inputs are raw images, audio, or text. LightGBM learns splits over prepared columns; it does not learn image or language representations
Use it if
- You need histogram-based boosting for a large tabular classification or regression job and want both native and scikit-learn APIs
- Pandas categorical columns should train directly without building a wide one-hot matrix
- Search or recommendation work needs `LGBMRanker` with grouped queries and a ranking objective such as `lambdarank`
- Polars or PyArrow tables should feed a tree model without first being converted into pandas in application code
- Your inputs are raw images, audio, or text. LightGBM learns splits over prepared columns; it does not learn image or language representations
- A small dataset needs conservative defaults with little tuning. Leaf-wise growth can overfit unless `num_leaves` and `min_data_in_leaf` are controlled
- You need a pure-Python dependency or a platform without a published wheel. Version 4.7.0 ships compiled `.so` extensions and source builds require CMake plus a C++17 toolchain
- Old `fit()` examples must run unchanged. LightGBM 4.x uses callbacks for early stopping and logging, and 4.7 deprecates `eval_set` in favor of `eval_X` and `eval_y`
- You need license metadata to be explicit in the wheel metadata. Our package inspection reported the license as unknown, even though the GitHub repository identifies an MIT license
Setup reality
We installed LightGBM 4.7.0 in 2.1 seconds in a fresh Python 3.12 container. It left 4 packages and 180 MB on disk, and import lightgbm completed in 1.33 seconds. Pip-audit found 0 known vulnerabilities. The wheel contains compiled .so extensions, ships py.typed, declares 15 direct dependencies, and requires Python 3.10 or newer. Package inspection could not identify a license, while the repository publishes MIT license text.
The ordinary wheel is the easy CPU path. A source build needs CMake and a C++17 compiler. GPU use is a separate choice: version 4.7.0 adds ROCm builds and multi-GPU CUDA through NCCL, but drivers, toolkits, device visibility, and matching build options remain your responsibility. macOS users commonly need an OpenMP runtime. A wheel built for the wrong architecture or C library fails before model code runs because the Python layer must load lib_lightgbm.
For 4.x training, put early stopping and evaluation logging in callbacks such as lgb.early_stopping(50) and lgb.log_evaluation(100). Version 4.7.0 adds eval_X and eval_y to scikit-learn fit() and deprecates eval_set, so pin the exact minor version before changing shared training helpers. Prediction data must keep the training feature names, column order, and pandas category definitions. Persist those category levels with the preprocessing pipeline.
LightGBM uses CPU threads by default, which can oversubscribe a web worker, Dask process, or cross-validation job. Set n_jobs or num_threads at the correct layer instead of letting each nested worker claim every core. Ranking rows must be contiguous by query, and group sizes must sum to the row count. Our measurement setup covered one import on 3 CPUs, not CUDA, ROCm, multi-GPU NCCL, Dask, or distributed socket training.
Patterns
Fit a binary classifier through sklearn train-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` controls tree capacity directly. Raising it above 31 without also constraining leaf size can fit small training sets too closely.
Stop through callbacks on 4.x 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_)LightGBM 4.x moved early stopping and evaluation logging into callbacks. Version 4.7 also starts the move from `eval_set` toward `eval_X` and `eval_y`.
Train from a binned Dataset native-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)Pass the training Dataset as the validation reference so both use compatible bins. Binary `predict()` returns scores or probabilities, so choose the threshold separately.
Keep pandas columns categorical categorical-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-detectedAutomatic handling expects pandas `category` dtype. Preserve its category vocabulary and ordering for prediction data instead of rebuilding codes independently.
Estimate the useful round count cross-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])The metric list length is the number of rounds left after early stopping. Use that count when fitting a final model on all training rows.
Rank features by accumulated gain feature-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))Default importance counts splits and can favor columns with many cut points. Gain reports training loss reduction, while SHAP answers per-row attribution questions.
Persist the native text model save-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 native text format avoids Python pickle's class-version coupling. Store preprocessing and exact feature order beside the model.
Weight the positive class imbalanced-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')Set either `scale_pos_weight` or `is_unbalance`, not both. Class weighting changes calibration, so validate scores used as probabilities.
Fit separate conditional quantiles quantile-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% intervalEach alpha needs its own model. The 0.1 and 0.9 predictions can cross because separately fitted quantiles have no ordering constraint.
Fit LambdaRank query groups ranking-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 for each query must be contiguous, and group sizes must sum to the row count. Labels are ordered relevance grades used by the ranking objective.
Constrain leaf-wise growth tune-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,
)Tune `num_leaves` with `min_data_in_leaf`, then trade learning rate against round count. Sampling parameters help regularize larger datasets.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| xgboost | PyPI | Choose XGBoost when its wheel, CUDA path, and deployment converters fit your platform better. |
| catboost | PyPI | Choose CatBoost when high-cardinality categorical columns and low-tuning defaults matter most. |
| scikit-learn | PyPI | Choose scikit-learn's histogram boosters when the existing sklearn dependency is enough for a modest dataset. |
More ai / ml guides
openai · mcp · huggingface-hub · @modelcontextprotocol/sdk · scikit-learn · tiktoken · the whole shelf →
How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.

