code: def grid_search(init_classifier, X, y, param_grid, n_folds=3):
      """Searches for the most optimal parameters in the grid
      Returns trained model and optimal parameters
      """
      best_params = {}
  
      if param_grid:  # Avoid corner case when param_grid is empty
          param_names, param_values_lists = zip(*param_grid.items())
          best_acc = -1.0
          for param_values in itertools.product(*param_values_lists):
              params = dict(zip(param_names, param_values))
              classifier = init_classifier(**params)
              acc = neoml.CrossValidation.cross_validation_score(
                  classifier, X, y, parts=5
              ).mean()
              if acc > best_acc:
                  best_acc = acc
                  best_params = params
  
      best_classifier = init_classifier(**best_params)
      return best_classifier.train(X, y), best_params
  
imports: import neoml
  import numpy
  import itertools
  from sklearn.datasets import fetch_20newsgroups_vectorized
label_desc: Use image node_id 2 for calling a global function with example usage: grid_search(init_classifier, X, y, param_grid, n_folds) and returns: best_classifier,  best_params