<commit_before>package hex.gbm;

import hex.gbm.DTree.DecidedNode;
import hex.gbm.DTree.LeafNode;
import hex.gbm.DTree.UndecidedNode;
import water.*;
import water.api.DocGen;
import water.api.GBMProgressPage;
import water.fvec.Chunk;
import water.fvec.Frame;
import water.util.*;
import water.util.Log.Tag.Sys;

// Gradient Boosted Trees
//
// Based on "Elements of Statistical Learning, Second Edition, page 387"
public class GBM extends SharedTreeModelBuilder {
  static final int API_WEAVER = 1; // This file has auto-gen'd doc & json fields
  static public DocGen.FieldDoc[] DOC_FIELDS; // Initialized from Auto-Gen code.

  @API(help = "Learning rate, from 0. to 1.0", filter = Default.class, dmin=0, dmax=1)
  public double learn_rate = 0.1;

  @API(help = "Grid search parallelism", filter = Default.class, lmax = 4)
  public int grid_parallelism = 1;

  public static class GBMModel extends DTree.TreeModel {
    static final int API_WEAVER = 1; // This file has auto-gen'd doc & json fields
    static public DocGen.FieldDoc[] DOC_FIELDS; // Initialized from Auto-Gen code.
    public GBMModel(Key key, Key dataKey, Key testKey, String names[], String domains[][], int ntrees) { super(key,dataKey,testKey,names,domains,ntrees); }
    public GBMModel(GBMModel prior, DTree[] trees, double err, long [][] cm) { super(prior, trees, err, cm); }
  }
  public Frame score( Frame fr ) { return ((GBMModel)UKV.get(dest())).score(fr,true);  }

  @Override protected Log.Tag.Sys logTag() { return Sys.GBM__; }
  public GBM() { description = "Distributed GBM"; }

  /** Return the query link to this page */
  public static String link(Key k, String content) {
    RString rs = new RString("<a href='GBM.query?source=%$key'>%content</a>");
    rs.replace("key", k.toString());
    rs.replace("content", content);
    return rs.toString();
  }

  @Override protected void logStart() {
    Log.info("Starting GBM model build...");
    super.logStart();
    Log.info("    learn_rate: " + learn_rate);
  }

  @Override protected void exec() {
    logStart();
    buildModel();
  }

  @Override public int gridParallelism() {
    return grid_parallelism;
  }

  @Override protected Response redirect() {
    return GBMProgressPage.redirect(this, self(), dest());
  }

  // ==========================================================================
  // Compute a GBM tree.

  // Start by splitting all the data according to some criteria (minimize
  // variance at the leaves).  Record on each row which split it goes to, and
  // assign a split number to it (for next pass).  On *this* pass, use the
  // split-number to build a per-split histogram, with a per-histogram-bucket
  // variance.
  @Override protected void buildModel( final Frame fr, String names[], String domains[][], final Key outputKey, final Key dataKey, final Key testKey, final Timer t_build ) {
    GBMModel model = new GBMModel(outputKey, dataKey, testKey, names, domains, ntrees);
    DKV.put(outputKey, model);
    // Build trees until we hit the limit
    int tid;
    DTree[] ktrees = null;
    for( tid=0; tid<ntrees; tid++) {
      // ESL2, page 387
      // Step 2a: Compute prediction (prob distribution) from prior tree results:
      //   Work <== f(Tree)
      new ComputeProb().doAll(fr);

      // ESL2, page 387
      // Step 2b i: Compute residuals from the prediction (probability distribution)
      //   Work <== f(Work)
      new ComputeRes().doAll(fr);

      // ESL2, page 387, Step 2b ii, iii, iv
      ktrees = buildNextKTrees(fr);
      if( cancelled() ) break; // If canceled during building, do not bulkscore

      // Check latest predictions
      Score sc = new Score().doIt(model,fr,validation,_validResponse).report(Sys.GBM__,tid+1,ktrees);
      model = new GBMModel(model, ktrees, (float)sc._sum/_nrows, sc._cm);
      DKV.put(outputKey, model);
    }
    Score sc = new Score().doIt(model,fr,validation,_validResponse).report(Sys.GBM__,tid+1,ktrees);
    model = new GBMModel(model, null, (float)sc._sum/_nrows, sc._cm);
    DKV.put(outputKey, model);
    cleanUp(fr,t_build); // Shared cleanup
  }

  // --------------------------------------------------------------------------
  // Compute Prediction from prior tree results.<commit_msg>Tiny bug fix. GBM validation reporting was +1 off.<commit_after>package hex.gbm;

import hex.gbm.DTree.DecidedNode;
import hex.gbm.DTree.LeafNode;
import hex.gbm.DTree.UndecidedNode;
import water.*;
import water.api.DocGen;
import water.api.GBMProgressPage;
import water.fvec.Chunk;
import water.fvec.Frame;
import water.util.*;
import water.util.Log.Tag.Sys;

// Gradient Boosted Trees
//
// Based on "Elements of Statistical Learning, Second Edition, page 387"
public class GBM extends SharedTreeModelBuilder {
  static final int API_WEAVER = 1; // This file has auto-gen'd doc & json fields
  static public DocGen.FieldDoc[] DOC_FIELDS; // Initialized from Auto-Gen code.

  @API(help = "Learning rate, from 0. to 1.0", filter = Default.class, dmin=0, dmax=1)
  public double learn_rate = 0.1;

  @API(help = "Grid search parallelism", filter = Default.class, lmax = 4)
  public int grid_parallelism = 1;

  public static class GBMModel extends DTree.TreeModel {
    static final int API_WEAVER = 1; // This file has auto-gen'd doc & json fields
    static public DocGen.FieldDoc[] DOC_FIELDS; // Initialized from Auto-Gen code.
    public GBMModel(Key key, Key dataKey, Key testKey, String names[], String domains[][], int ntrees) { super(key,dataKey,testKey,names,domains,ntrees); }
    public GBMModel(GBMModel prior, DTree[] trees, double err, long [][] cm) { super(prior, trees, err, cm); }
  }
  public Frame score( Frame fr ) { return ((GBMModel)UKV.get(dest())).score(fr,true);  }

  @Override protected Log.Tag.Sys logTag() { return Sys.GBM__; }
  public GBM() { description = "Distributed GBM"; }

  /** Return the query link to this page */
  public static String link(Key k, String content) {
    RString rs = new RString("<a href='GBM.query?source=%$key'>%content</a>");
    rs.replace("key", k.toString());
    rs.replace("content", content);
    return rs.toString();
  }

  @Override protected void logStart() {
    Log.info("Starting GBM model build...");
    super.logStart();
    Log.info("    learn_rate: " + learn_rate);
  }

  @Override protected void exec() {
    logStart();
    buildModel();
  }

  @Override public int gridParallelism() {
    return grid_parallelism;
  }

  @Override protected Response redirect() {
    return GBMProgressPage.redirect(this, self(), dest());
  }

  // ==========================================================================
  // Compute a GBM tree.

  // Start by splitting all the data according to some criteria (minimize
  // variance at the leaves).  Record on each row which split it goes to, and
  // assign a split number to it (for next pass).  On *this* pass, use the
  // split-number to build a per-split histogram, with a per-histogram-bucket
  // variance.
  @Override protected void buildModel( final Frame fr, String names[], String domains[][], final Key outputKey, final Key dataKey, final Key testKey, final Timer t_build ) {
    GBMModel model = new GBMModel(outputKey, dataKey, testKey, names, domains, ntrees);
    DKV.put(outputKey, model);
    // Build trees until we hit the limit
    int tid;
    DTree[] ktrees = null;
    for( tid=0; tid<ntrees; tid++) {
      // ESL2, page 387
      // Step 2a: Compute prediction (prob distribution) from prior tree results:
      //   Work <== f(Tree)
      new ComputeProb().doAll(fr);

      // ESL2, page 387
      // Step 2b i: Compute residuals from the prediction (probability distribution)
      //   Work <== f(Work)
      new ComputeRes().doAll(fr);

      // ESL2, page 387, Step 2b ii, iii, iv
      ktrees = buildNextKTrees(fr);
      if( cancelled() ) break; // If canceled during building, do not bulkscore

      // Check latest predictions
      Score sc = new Score().doIt(model,fr,validation,_validResponse).report(Sys.GBM__,tid,ktrees);
      model = new GBMModel(model, ktrees, (float)sc._sum/_nrows, sc._cm);
      DKV.put(outputKey, model);
    }
    Score sc = new Score().doIt(model,fr,validation,_validResponse).report(Sys.GBM__,tid,ktrees);
    model = new GBMModel(model, null, (float)sc._sum/_nrows, sc._cm);
    DKV.put(outputKey, model);
    cleanUp(fr,t_build); // Shared cleanup
  }

  // --------------------------------------------------------------------------
  // Compute Prediction from prior tree results.
{'fraction_non_alphanumeric': 0.15795654726952438, 'fraction_numerical': 0.007398708162066941, 'mean_word_length': 3.2643965948923386, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6320412', 'n_tokens_mistral': 2716, 'n_tokens_neox': 2542, 'n_words': 823}