hessboost 0.2.2

Fast, deterministic gradient boosting (GBDT) in Rust: conformal intervals, explainable boosting machines, distributional boosting, tree-based diffusion, and XGBoost model interchange
Documentation
//! Learning-to-rank with LambdaMART (`rank:ndcg`) over query groups. Run:
//! `cargo run --release --example ranking`.

use hessboost::objective::LambdaRank;
use hessboost::prelude::*;

mod common;
use common::lcg;

fn main() -> Result<()> {
    // `n_groups` queries, each with `per` documents. A document's single feature
    // is correlated with its relevance grade (0..per-1), plus noise.
    let (n_groups, per) = (200usize, 6usize);
    let n = n_groups * per;
    let mut rng = lcg(11);
    let mut x = Vec::with_capacity(n);
    let mut y = Vec::with_capacity(n);
    for _ in 0..n_groups {
        for d in 0..per {
            let rel = d as f32; // graded relevance
            x.push(rel + (rng() - 0.5) * 0.9);
            y.push(rel);
        }
    }
    // `with_group_sizes` marks the query boundaries (each group has `per` rows).
    let sizes = vec![per; n_groups];
    let dtrain = DMatrix::from_dense(&x, n, 1)?
        .with_labels(&y)?
        .with_group_sizes(&sizes)?;

    let params = TrainingParams::builder()
        .objective(Objective::RankNdcg(LambdaRank::default()))
        .max_depth(3)
        .eta(0.2)
        .build()?;

    // Watch NDCG on the training set to see it improve. rank:ndcg's default
    // metric is XGBoost's `ndcg@32` (NDCG of each query's top 32).
    let out = Trainer::new(&params, &dtrain, 40)
        .eval(&dtrain, "train")
        .train()?;
    let ndcg = |r: hessboost::training::RoundEval| r.score("train", "ndcg@32").unwrap();
    println!(
        "NDCG: round 0 = {:.3}  →  final = {:.3}",
        ndcg(out.history.round(0).unwrap()),
        ndcg(out.history.last().unwrap())
    );
    Ok(())
}