code: def test_mean_per_class_error_grid():
      gbm = H2OGradientBoostingEstimator(
          nfolds=3, fold_assignment="Random", seed=1234
      )
      cars = h2o.import_file(
          pyunit_utils.locate("smalldata/junit/cars_20mpg.csv")
      )
      cars["cylinders"] = cars["cylinders"].asfactor()
      r = cars[0].runif(seed=1234)
      train = cars[r > 0.2]
      valid = cars[r <= 0.2]
      response_col = "cylinders"
      predictors = [
          "displacement",
          "power",
          "weight",
          "acceleration",
          "year",
      ]
      gbm.distribution = "multinomial"
  
      ## Early stopping
      gbm.stopping_rounds = 2
      gbm.stopping_metric = "mean_per_class_error"
      gbm.ntrees = 10000
      gbm.max_depth = 3
      gbm.min_rows = 1
      gbm.learn_rate = 0.01
      gbm.score_tree_interval = 1
      gbm.nfolds = None
      gbm.fold_assignment = None
      gbm.train(
          x=predictors,
          y=response_col,
          training_frame=train,
          validation_frame=valid,
      )
      print(gbm)
      print(gbm.scoring_history())
  
      ## Grid search
      hyper_params_tune = {
          "max_depth": list(range(1, 10 + 1, 1)),
          "sample_rate": [x / 100.0 for x in range(20, 101)],
          "col_sample_rate": [x / 100.0 for x in range(20, 101)],
          "col_sample_rate_per_tree": [
              x / 100.0 for x in range(20, 101)
          ],
          "col_sample_rate_change_per_level": [
              x / 100.0 for x in range(90, 111)
          ],
          "min_rows": [
              2**x
              for x in range(0, int(math.log(train.nrow, 2) - 2) + 1)
          ],
          "nbins": [2**x for x in range(4, 11)],
          "nbins_cats": [2**x for x in range(4, 13)],
          "min_split_improvement": [0, 1e-8, 1e-6, 1e-4],
          "histogram_type": [
              "UniformAdaptive",
              "QuantilesGlobal",
              "RoundRobin",
          ],
      }
  
      search_criteria_tune = {
          "strategy": "RandomDiscrete",
          "max_runtime_secs": 600,  ## limit the runtime to 10 minutes
          "max_models": 10,
          "seed": 1234,
          "stopping_rounds": 5,
          "stopping_metric": "mean_per_class_error",
          "stopping_tolerance": 1e-3,
      }
  
      grid = H2OGridSearch(
          H2OGradientBoostingEstimator,
          hyper_params=hyper_params_tune,
          search_criteria=search_criteria_tune,
      )
      grid.train(
          x=predictors,
          y=response_col,
          training_frame=train,
          validation_frame=valid,
          distribution="multinomial",
          seed=1234,
          stopping_rounds=10,
          stopping_metric="mean_per_class_error",
          stopping_tolerance=1e-3,
      )
  
      print(grid)  ## sorted by logloss
      print(grid.get_grid("mean_per_class_error"))
  
file_path: h2o-3/h2o-py/tests/testdir_misc/pyunit_mean_per_class_error.py
imports: import sys
  import h2o
  import math
  from tests import pyunit_utils
  from h2o.estimators.gbm import H2OGradientBoostingEstimator
  from h2o.grid import H2OGridSearch
label_desc: Use image node_id 3 for calling a global function with example usage: test_mean_per_class_error_grid() without return types