class_docstr: Local Search Algorithm.
  
  This algorithm expects to start with a very good hyperparameter
  configuration. It changes one hyperparameter at a time to see if better
  results can be obtained.
  
  Args:
      seed_configuration (dict): hyperparameter configuration to start with.
      perturbation_factors (Union[tuple,list]): continuous parameters will be
          multiplied by these.
      repeat_trials (int): number of times that identical configurations are
          repeated to test for random fluctuations.
class_docstr_tok: ["Local","Search","Algorithm",".","This","algorithm","expects","to","start","with","a","very","good","hyperparameter","configuration",".","It","changes","one","hyperparameter","at","a","time","to","see","if","better","results","can","be","obtained",".","Args",":","seed_configuration","(","dict",")",":","hyperparameter","configuration","to","start","with",".","perturbation_factors","(","Union","[","tuple",",","list","]",")",":","continuous","parameters","will","be","multiplied","by","these",".","repeat_trials","(","int",")",":","number","of","times","that","identical","configurations","are","repeated","to","test","for","random","fluctuations","."]
code: def _get_next_trials(self, parameters, results, lower_is_better):
      self.count += 1
      if self.count == 1:
          self.submitted.append(self.seed_configuration)
          return [self.seed_configuration] * self.repeat_trials
  
      # Get best result so far
      if len(results) > 0:
          completed = results.query("Status == 'COMPLETED'")
          if len(completed) > 0:
              best_idx = (
                  completed.loc[:, "Objective"].idxmin()
                  if lower_is_better
                  else completed.loc[:, "Objective"].idxmax()
              )
              self.seed_configuration = completed.loc[
                  best_idx, [p.name for p in parameters]
              ].to_dict()
  
      # Randomly sample perturbations and return first that hasn't been tried
      for param in random.sample(parameters, len(parameters)):
          if isinstance(param, Choice):
              values = random.sample(param.range, len(param.range))
              for val in values:
                  new_params = self.seed_configuration.copy()
                  new_params[param.name] = val
                  if new_params not in self.submitted:
                      self.submitted.append(new_params)
                      return [new_params] * self.repeat_trials
          else:
              for incr in random.sample([True, False], 2):
                  new_params = self._perturb(
                      candidate=self.seed_configuration.copy(),
                      parameter=param,
                      increase=incr,
                  )
                  if new_params not in self.submitted:
                      self.submitted.append(new_params)
                      return [new_params] * self.repeat_trials
      else:
          alglogger.info(
              "All local perturbations have been exhausted and "
              "no better local optimum was found."
          )
          return [None] * self.repeat_trials
  
imports: import os
  import random
  import numpy
  import logging
  import sherpa
  import pandas
  import sklearn.gaussian_process
  from sherpa.core import Choice, Continuous, Discrete, Ordinal, AlgorithmState
  from sherpa.core import rng
  import sklearn.model_selection
  import collections
label_desc: Use image node_id 3 for calling the LocalSearch obj's underlying member method code with example usage: obj._get_next_trials(parameters, results, lower_is_better) and returns: unknown, unknown, unknown, unknown