mrkeyoor.com_
Sat 19 Sept 15:51 UTC
PyPIAI / MLupdated 19 Sept 2026

xgboost review

xgboost trains gradient-boosted decision trees for tabular classification, regression, ranking, survival, and forecasting tasks. A compiled C++ core sits behind scikit-learn estimators, a lower-level DMatrix and Booster API, GPU training, external-memory iterators, and Dask or Spark integrations. Version 3.4.1 is a narrow patch: it fixes model slicing when categorical containers are present and repairs JVM batch prediction for SparseVector features. Our Python 3.12 sandbox imported the compiled package successfully, but the installed environment occupied 540 MB.

Verdict

xgboost 3.4.1 is a strong choice for serious tabular models, especially when GPU, ranking, external-memory, or distributed paths matter. Skip it for small services that cannot justify a 540 MB environment, older Python, or the operational work of feature-schema and model-version control.

We installed it

Lab card: what happened when we installed xgboostScreenshot of xgboost documentation
Install✓ · 5.2s4 packages on disk · 540 MB
Importimport xgboost in 1.12s · compiled extensions · py.typed · requires Python >=3.12
Known vulns0(pip-audit)

Answers from our run

Does xgboost install cleanly?

Yes. In a fresh container with an empty cache, pip install xgboost finished in 5 seconds, leaving 4 packages and 540 MB on disk. pip-audit reported no known vulnerabilities.

What does xgboost need to run?

Python >=3.12, and a platform wheel with compiled extensions. In our run import xgboost succeeded in 1.12s, and the package ships py.typed for type checkers.

xgboost or lightgbm: which should you use?

lightgbm: Choose it when CPU training throughput and a smaller deployment fit matter more than matching XGBoost APIs. xgboost 3.4.1 is a strong choice for serious tabular models, especially when GPU, ranking, external-memory, or distributed paths matter.

When should you not use xgboost?

The input is raw image, audio, or long-form text. XGBoost consumes engineered features and does not learn those representations itself.

API stability4/5The sklearn estimator and native Booster APIs remain broadly compatible, while major releases have moved commonly copied options. Current code uses device='cuda' instead of gpu_hist or gpu_id, and sklearn early_stopping_rounds belongs on the constructor rather than fit(). The 3.4.1 patch fixes categorical model slicing without introducing a new call shape. Deprecation notices are generally available, but old notebooks are common enough that upgrades need targeted tests.
Docs4/5The official site covers Python estimators, DMatrix, Booster parameters, callbacks, categorical data, model I/O, GPU support, external memory, Dask, Spark, ranking, survival, forecasting, and custom objectives. Release notes name the exact fixes in 3.4.1. The parameter reference is dense and presents many interacting choices without a single production recipe, while search results often surface tutorials written for removed GPU and early-stopping arguments.
Maintenance5/5Version 3.4.1 shipped on August 15, 2026, ten days after 3.4.0, with focused categorical and JVM fixes. GitHub reports 28,690 stars, 421 open issues and pull requests, an unarchived repository, and a push on August 25, 2026. The project maintains C++, Python, JVM, R, GPU, distributed, and packaging paths, so the open count reflects a large surface. Fast patch follow-up and same-day repository activity are strong current signals.
Ecosystem5/5The provided latest-week count is 10,869,920 downloads. XGBoost works through native Python objects and scikit-learn estimators, with documented Dask and Spark routes plus GPU training and plotting hooks. Model explainers, experiment trackers, and tuning systems widely recognize Booster and estimator objects. That compatibility does not remove deployment coupling: NumPy, SciPy, dataframe category metadata, CUDA, feature order, and serialized model format must agree across training and serving.

Use it if

  • Structured rows with numeric, sparse, missing, or controlled categorical features need a strong boosted-tree baseline.
  • A scikit-learn pipeline needs early stopping, class weighting, custom metrics, or probability estimates from a mature tree estimator.
  • Large training jobs can use CUDA, QuantileDMatrix, external memory, Dask, or Spark rather than loading one dense matrix into RAM.
  • The task is ranking, survival analysis, quantile regression, or another objective already implemented by XGBoost.
Skip it if

Setup reality

We installed xgboost 3.4.1 in a fresh Python 3.12 Bookworm container. Installation completed in 5.2 seconds, left 4 packages, and used 540 MB. The package metadata contains 13 direct requirements across base dependencies and extras and requires Python >=3.12. pip-audit found no known vulnerabilities. The wheel includes compiled shared objects and py.typed. import xgboost succeeded in 1.12 seconds. The installed metadata did not identify a license, so our measurement records it as unknown.

There are no credentials or mandatory config files. The main setup choice is device and data representation. CPU training uses device='cpu'; CUDA training uses device='cuda' with a compatible driver and build. An available GPU does not move pandas or NumPy input there for free, so repeated host-to-device copies can erase gains on small fits. Set n_jobs deliberately inside servers and tuning jobs to avoid each model taking every CPU thread.

Categorical training needs category-aware dataframe columns plus enable_categorical=True and a supported tree method. Train and inference data must preserve the same category encoding. Save such models as JSON or UBJSON because those formats retain categorical metadata; pickle and memory snapshots are tied more closely to library internals. Version 3.4.1 specifically fixes slicing a model with a category container, so 3.4.0 users doing sliced categorical inference should upgrade.

Early stopping in the sklearn API belongs on the estimator constructor in current releases, while the validation set is passed to fit(). Old tutorials using gpu_hist, gpu_id, or fit(early_stopping_rounds=...) describe earlier majors. Use a validation set that is separate from final test data. QuantileDMatrix reduces histogram memory, and its validation matrix should reference the training matrix for matching cut points. Never unpickle a model from an untrusted source; use save_model() artifacts and record XGBoost plus feature-schema versions.

Patterns

Fit a binary classifier train-classifier

from xgboost import XGBClassifier

model = XGBClassifier(
    n_estimators=500,
    learning_rate=0.05,
    max_depth=6,
    tree_method='hist',
    n_jobs=4,
    random_state=42,
)
model.fit(X_train, y_train)
probability = model.predict_proba(X_test)[:, 1]

Multiclass labels must be zero-based integers. Set n_jobs to avoid oversubscribing CPUs in concurrent workers.

Stop against a validation set early-stop

model = XGBClassifier(
    n_estimators=2000,
    learning_rate=0.03,
    eval_metric='logloss',
    early_stopping_rounds=50,
)
model.fit(
    X_train, y_train,
    eval_set=[(X_valid, y_valid)],
    verbose=False,
)
print(model.best_iteration)

In current sklearn wrappers, early_stopping_rounds is a constructor argument. Keep the final test set out of this decision.

Train through DMatrix and Booster train-native-api

import xgboost as xgb

train = xgb.DMatrix(X_train, label=y_train)
valid = xgb.DMatrix(X_valid, label=y_valid)
booster = xgb.train(
    {'objective': 'binary:logistic', 'eta': 0.05, 'max_depth': 6},
    train,
    num_boost_round=2000,
    evals=[(valid, 'valid')],
    early_stopping_rounds=50,
)
probability = booster.predict(xgb.DMatrix(X_test))

The native API returns objective output, such as probabilities for binary:logistic, rather than sklearn-style class labels.

Select CUDA training train-on-gpu

model = XGBClassifier(
    device='cuda',
    tree_method='hist',
    n_estimators=1000,
)
model.fit(X_train, y_train)

device='cuda' replaces older gpu_hist and gpu_id examples. Verify the driver and measure data-transfer overhead on the real dataset.

Preserve native categorical columns train-categorical

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

model = XGBClassifier(
    enable_categorical=True,
    tree_method='hist',
)
model.fit(X, labels)

Inference must use compatible category definitions. Save with JSON or UBJSON so category information is retained.

Persist a portable model artifact save-model

model.save_model('model.ubj')

from xgboost import XGBClassifier
restored = XGBClassifier()
restored.load_model('model.ubj')

Use save_model() for durable artifacts. Pickles capture Python internals and must never be loaded from untrusted input.

Keep only a range of boosted trees slice-model

booster = model.get_booster()
first_hundred = booster[:100]
first_hundred.save_model('first-100.ubj')

Version 3.4.1 fixes slicing when the model has a category container. Upgrade from 3.4.0 before relying on sliced categorical models.

Weight a rare positive class balance-binary-target

negative = int((y_train == 0).sum())
positive = int((y_train == 1).sum())

model = XGBClassifier(
    scale_pos_weight=negative / positive,
    eval_metric='aucpr',
)
model.fit(X_train, y_train)

Class weighting changes probability calibration. Recalibrate predictions if downstream code treats them as absolute risk.

Estimate the boosting-round count cross-validate-rounds

import xgboost as xgb

data = xgb.DMatrix(X, label=y)
result = xgb.cv(
    {'objective': 'binary:logistic', 'eta': 0.05, 'max_depth': 6},
    data,
    num_boost_round=1000,
    nfold=5,
    metrics='auc',
    early_stopping_rounds=50,
    seed=42,
)
best_rounds = len(result)

xgb.cv returns one row per retained boosting round. Preserve the split and seed details with the chosen count.

Train with QuantileDMatrix reduce-histogram-memory

import xgboost as xgb

train = xgb.QuantileDMatrix(X_train, label=y_train)
valid = xgb.QuantileDMatrix(X_valid, label=y_valid, ref=train)
booster = xgb.train(
    {'tree_method': 'hist'},
    train,
    num_boost_round=500,
    evals=[(valid, 'valid')],
)

Pass ref=train for validation data so both matrices use the same quantile cuts.

Read split gain by feature inspect-feature-gain

scores = model.get_booster().get_score(importance_type='gain')
ranking = sorted(scores.items(), key=lambda item: item[1], reverse=True)
print(ranking[:10])

Built-in importance can favor features with many possible splits. Use held-out permutation or SHAP analysis when decisions depend on the ranking.

Run bounded inference batches predict-in-batches

import numpy as np

parts = []
for start in range(0, len(X), 10_000):
    batch = X.iloc[start:start + 10_000]
    parts.append(model.predict_proba(batch)[:, 1])
predictions = np.concatenate(parts)

Batching limits temporary memory. Preserve column order, dtypes, missing-value treatment, and category metadata from training.

Alternatives

PackageRegistryPick it when
lightgbmPyPIChoose it when CPU training throughput and a smaller deployment fit matter more than matching XGBoost APIs.
catboostPyPIChoose it for datasets dominated by categorical features where ordered category handling should require less preprocessing.
scikit-learnPyPIChoose its HistGradientBoosting estimators when one existing dependency and a simpler deployment outweigh XGBoost-specific objectives.

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.