use nanogbm::{Config, DatasetBuilder, GbdtTrainer};
fn main() {
let n = 2000;
let d = 6;
let mut features = vec![0.0f64; n * d];
let mut labels = vec![0f32; n];
let mut s: u64 = 0xABCDEF;
let mut rand = || {
s ^= s << 13;
s ^= s >> 7;
s ^= s << 17;
(s as f64 / u64::MAX as f64) * 2.0 - 1.0
};
for i in 0..n {
for j in 0..d {
features[i * d + j] = rand();
}
let z = 2.0 * features[i * d] + features[i * d + 2];
labels[i] = if z > 0.0 { 1.0 } else { 0.0 };
if rand() > 0.8 {
features[i * d + 3] = f64::NAN;
}
if rand() > 0.9 {
features[i * d] = f64::NAN;
}
}
let mut cfg = Config::default();
cfg.num_iterations = 100;
cfg.num_leaves = 15;
cfg.learning_rate = 0.1;
cfg.seed = 0;
let ds = DatasetBuilder::from_rows(&features, n, d, &labels, &cfg).unwrap();
let model = GbdtTrainer::new(&cfg).fit(&ds, None).unwrap();
let split = model.feature_importance_split();
let gain = model.feature_importance_gain();
println!("feature | splits | gain");
for j in 0..d {
println!(" f{j} | {:5} | {:.3}", split[j], gain[j]);
}
let probs = model.predict_proba(&features[..5 * d], 5);
for (i, p) in probs.iter().enumerate() {
let row = &features[i * d..(i + 1) * d];
println!("row {i} {row:?} -> p={p:.4}");
}
}