code: def hyperopt_search(
      self, parallel=False
  ):  # TODO: implement parallel search with MongoTrials
      def objective(kwargs):
          start = dt.now()
  
          self.current_trial += 1
          self.logger.info(
              "\n\nStarting trial no.%d" % self.current_trial
          )
          self.get_hyperparam_string(**kwargs)
          self.fit_vw()
          self.validate_vw()
          loss = self.validation_metric_vw()
  
          finish = dt.now()
          elapsed = finish - start
          self.logger.info(
              "evaluation time for this step: %s" % str(elapsed)
          )
  
          # clean up
          subprocess.call(
              shlex.split(
                  "rm %s %s" % (self.train_model, self.holdout_pred)
              )
          )
  
          to_return = {
              "status": STATUS_OK,
              "loss": loss,  # TODO: include also train loss tracking in order to prevent overfitting
              "eval_time": elapsed.seconds,
              "train_command": self.train_command,
              "current_trial": self.current_trial,
          }
          return to_return
  
      self.trials = Trials()
      if self.searcher == "tpe":
          algo = tpe.suggest
      elif self.searcher == "rand":
          algo = rand.suggest
      else:
          raise KeyError("Invalid searcher")
  
      logging.debug("starting hypersearch...")
      best_params = fmin(
          objective,
          space=self.space,
          trials=self.trials,
          algo=algo,
          max_evals=self.max_evals,
      )
      self.logger.debug(
          "the best hyperopt parameters: %s" % str(best_params)
      )
  
      json.dump(self.trials.results, open(self.trials_output, "w"))
      self.logger.info(
          "All the trials results are saved at %s" % self.trials_output
      )
  
      best_configuration = self.trials.results[
          np.argmin(self.trials.losses())
      ]["train_command"]
      best_loss = self.trials.results[np.argmin(self.trials.losses())][
          "loss"
      ]
      self.logger.info(
          "\n\nA full training command with the best hyperparameters: \n%s\n\n"
          % best_configuration
      )
      self.logger.info(
          "\n\nThe best holdout loss value: \n%s\n\n" % best_loss
      )
  
      return best_configuration, best_loss
  
imports: from hyperopt import hp, fmin, tpe, rand, Trials, STATUS_OK
  from hyperopt.pyll import scope
  from sklearn.metrics import roc_curve, auc, log_loss, average_precision_score, hinge_loss, mean_squared_error
  import numpy
  from datetime import datetime
  import subprocess, shlex
  from math import exp, log
  import argparse
  import re
  import logging
  import json
  from matplotlib import pyplot
  import itertools
  from collections import Counter
label_desc: Use image node_id 12 for calling the HyperOptimizer obj's underlying member method code with example usage: obj.hyperopt_search(parallel) and returns: best_configuration,  best_loss, to_return