Skip to content
v0.1.0 · Reproducing Zozoulenko et al. (2026)

Second-order boosting, regularized to convergence.

A faithful, dependency-free reproduction of Gradient Regularized Newton Boosting Trees — the algorithm that turns Newton's second-order signal into a globally convergent boosting iteration. Vanilla Newton diverges. GRN converges.

Live · Figure 1 · Wine Quality (Charbonnier)

When Newton diverges, GRN converges.

Loss per iteration, log scale — paper reproduction on Wine Quality with the Charbonnier loss.

Vanilla · λ_base = 0 Static · λ_base = 10 GRN · adaptive λ_k
0.02 0.05 0.1 0.2 0.5 1 0 25 50 75 100 Iteration Charbonnier loss (log)
Reproduced from experiments/wine_charbonnier.py λk = λbase + √(M · ||gk||H)

Reproducing & extending

139
Test cases covering identities & edge cases
4
Analytic losses with known M0
0
Runtime dependencies beyond NumPy
6
Mathematical guarantees, byte-faithful

Overview

The second-order story, written cleanly.

A reference implementation of Newton boosting you can actually read, with no C extensions, no framework lock-in, and no mystery in the iteration. Every closed-form in the paper has a name, a test, and a diagnostic.

  • Newton's signal

    Use the Hessian — without losing the loss.

    Gradient boosting uses first-order signal. Newton boosting uses the curvature. Faster convergence per iteration, but unstable: unregularized Newton can diverge when the Hessian is non-constant.

  • Adaptive regularization

    One scalar that learns with you.

    GRN replaces the static λ with λk = λbase + √(M · ||gk||H), where M = M0 · √N. The Hessian-Lipschitz constant M0 is analytic for four standard losses.

  • Global convergence

    Provably converging iterations.

    Proposition 5.1 of the paper guarantees global convergence. The implementation ships with Hilbert-space diagnostics to verify Θk, γk, and Lemma 4.2 on every trained model.

Algorithms

Two engines. One elegant difference.

Vanilla Newton boosting (Algorithm 1) and Gradient Regularized Newton boosting (Algorithm 2) share everything — loss, tree builder, diagnostics — except a single line that changes the entire convergence behaviour.

Vanilla Newton Boosting

Static λ

Algorithm 1. Uses a fixed λbase at every iteration. On losses with non-constant Hessians — e.g. Charbonnier or cross-entropy — the iteration can diverge.

for k = 1, 2, …, K:
    g_k, h_k = ∇L(F_k),  H(F_k)
    f_k = NewtonTree(g_k, h_k, λ_base)
    F_{k+1} = F_k + η · f_k
Paper §3 · Algorithm 1 λ_base
Recommended

Gradient Regularized Newton

Adaptive λk

Algorithm 2. λk scales with the gradient norm (Proposition 5.1). The iteration converges — steadily and provably.

for k = 1, 2, …, K:
    g_k, h_k = ∇L(F_k),  H(F_k)
    λ_k = λ_base + √(M·||g_k||_H)
    f_k = NewtonTree(g_k, h_k, λ_k)
    F_{k+1} = F_k + η · f_k
        
Paper §5 · Algorithm 2 λk = λbase + √(M · ||gk||H)
Closed-form leaf

w = -Σg / (Σh + λ)

Algorithm 1, line 4 — exact, no gradient descent on leaves.

Exact Newton gain

½[ G²_L/(H_L+λ) + … − G²/(H+λ) ]

Used for greedy split selection; closed form, no approximations.

Lipschitz M0

M0 ∈ {0, ¼, 1}

Analytic Hessian-Lipschitz constants for MSE, BCE/CCE and Charbonnier.

Capabilities

Everything the paper promises, nothing you don't need.

A focused surface area: six core APIs, four losses, three engines. Built for clarity, not for benchmarks on big data.

Newton tree learner

Closed-form leaves & splits.

Exact greedy splits with closed-form leaf weights and exact Newton gain. No gradient descent on leaves, no approximations.

Multi-class boosting

K-class softmax output.

Vector-valued tree leaves share split structure across classes. Block Hessians diag(p) − ppᵀ extracted to per-class diagonals.

Four analytic losses

MSE, Charbonnier, BCE, CCE.

Each loss ships with its analytic Hessian-Lipschitz constant M₀ ∈ {0, ¼, 1}, ready to plug into Proposition 5.1.

Hilbert-space diagnostics

Verify the paper on your model.

Exact Newton direction f = -g/(h+λ), cosine angle Θₖ, weak gradient edge γₖ, and Lemma 4.2 — all numerically checked.

Pure NumPy

No C extensions. No frameworks.

A single runtime dependency. Optional extras: scikit-learn for datasets, matplotlib for the experiment plots.

139 tests

Correctness, identities, edge cases.

Every closed-form in the paper has a test. Mathematical identities are checked numerically, byte-faithful to the formulas.

Mathematical guarantees

Six identities. One implementation.

Every closed-form in the paper maps to a test. The library is byte-faithful to Zozoulenko et al. (2026); see docs/fidelity.md for the section-by-section report.

01 Verified

Closed-form leaf weight

w = -Σg / (Σh + λ)

Algorithm 1, line 4. Each leaf's weight is the exact Newton step on its share of the loss.

02 Verified

Exact Newton gain

½[ G²_L/(H_L+λ) + G²_R/(H_R+λ) − G²/(H+λ) ]

Used to rank candidate splits greedily, with no approximation.

03 Verified

Adaptive λₖ (Proposition 5.1)

λₖ = λ_base + √(M · ||gₖ||_H)

With M = M₀ · √N and ||gₖ||_H = ||gₖ|| / √N, matching the paper's notation.

04 Verified

Lemma 4.2 identities

λ||f|| ≤ ||g||, ||f||²_K = -⟨g, f⟩

Verified numerically per iteration by verify_lemma_4_2.

05 Verified

Analytic M₀ (Appendix A)

MSE = 0 · Charbonnier = 1 · BCE/CCE = ¼

Hessian-Lipschitz constants, hard-coded per loss — no estimation step.

06 Verified

Multi-class block Hessian

diag(p) − p pᵀ

Extracted to per-class diagonals for the K-class Newton tree builder.

Developer experience

A scikit-learn feel, without the framework.

Familiar .fit / .predict surface, strict type hints, mypy-clean, and four short lines to a paper-faithful training run.

vanilla_regression.py
import numpy as np
from grnbt import VanillaNewtonBoosting, MSELoss

rng = np.random.default_rng(42)
X = rng.standard_normal((500, 8))
y = X[:, 0] + 0.5 * X[:, 1] ** 2 + 0.1 * rng.standard_normal(500)

model = VanillaNewtonBoosting(
    loss=MSELoss(),
    n_estimators=100,
    learning_rate=0.1,
    max_depth=4,
)
model.fit(X, y)
preds = model.predict(X)
print(f"final loss: {model.history['loss'][-1]:.6f}")
Runtime deps
1
(NumPy)
Public classes
6
engines + losses
Tests
139
all passing
Type-check
mypy
--strict

Reproducible experiments

Paper figures, not promises.

Three experiment scripts reproduce Figures 1, 2 and the hyperparameter ablations from Zozoulenko et al. (2026). Machine-readable artifacts written to experiments/.

Paper Figure 1 · Wine Quality (Charbonnier)

Three engines, one plot, three behaviours.

Vanilla Newton diverges. The static-high-λ baseline plateaus biased. GRN's adaptive λₖ converges — steadily and provably.

Vanilla · divergesGRN · convergesStatic · plateau
Paper Figure 2 · Higgs (BCE)

Diagnostics you can plot.

Record the cosine angle Θₖ and weak gradient edge γₖ per iteration. Verify Lemma 4.2 numerically on a trained model.

ΘₖγₖLemma 4.2
Hyperparameter ablations

108 configurations × 3 seeds.

Loss × engine × η × depth × λ_base grid, written to a tidy CSV. Aggregate with one line of pandas.

324 runsCSV output

When to use GRNBT

Designed for research, not for production scale.

GRNBT is the right tool when clarity matters more than throughput. For big-data production workloads, prefer a system built for it.

Verifying theory

Run experiments that reproduce Figures 1 and 2 of the paper. Trace every identity numerically.

Teaching Newton boosting

Use it in a graduate ML seminar. Every line maps to a closed-form on the projector slide.

Starting a research fork

Drop in a custom loss with its analytic M₀, swap in your own tree, and run.

API surface

A short list. A long reach.

Three engines, four losses, two tree learners, four diagnostics — everything you need to reproduce the paper and explore beyond it.

grnbt / public API 13 symbols
  • VanillaNewtonBoosting Static-λ second-order GBDT (Algorithm 1)
  • GradientRegularizedNewtonBoosting Adaptive-λ boosting (Algorithm 2)
  • MultiClassNewtonBoosting K-class softmax boosting
  • MSELoss Mean-squared-error loss (M₀ = 0)
  • CharbonnierLoss Pseudo-Huber-style loss (M₀ = 1)
  • BinaryCrossEntropyLoss BCE loss (M₀ = ¼)
  • CategoricalCrossEntropyLoss Multi-class CCE loss (M₀ = ¼)
  • NewtonTree Scalar-output greedy Newton tree
  • MultiClassNewtonTree Vector-output K-class Newton tree
  • cosine_angle_theta Hilbert-space angle Θₖ
  • exact_newton_direction Closed-form f = -g/(h+λ)
  • verify_lemma_4_2 Lemma 4.2 identity check
  • weak_gradient_edge_gamma γₖ weak gradient edge

Quick start

From pip install to paper-faithful training in seconds.

The package is pure NumPy. Optional extras pull in scikit-learn for datasets and matplotlib for plots.

  • Python 3.9 → 3.13 supported
  • NumPy ≥ 1.21 (only runtime dep)
  • MIT licensed · No telemetry
PyPI
pip install grnbt
From source
git clone https://github.com/sachncs/gradient-regularized-newton-boosting-trees.git
cd gradient-regularized-newton-boosting-trees
pip install -e .
With extras
pip install -e ".[dev]"   # adds pytest, mypy, scikit-learn, matplotlib

Reference

Cite the paper. Build on the code.

If you use this implementation in your research, please cite the accompanying preprint. The library is reproduction code only; the paper contents remain the property of the original authors.

citation.bib
@article{zozoulenko2026grnbt,
  title  = {Gradient Regularized Newton Boosting Trees
            with Global Convergence},
  author = {Zozoulenko, Nikita and
            Falkowski, Daniel and
            Cass, Thomas and
            Gonon, Lucien},
  journal = {Preprint (arXiv id verification pending)},
  year   = {2026}
}
v0.1.0 · MIT

Read the paper. Run the code.

A faithful, dependency-free reference implementation of Newton's second-order boosting — regularized, proven, and ready to inspect.