class_docstr: This class represents a simulation of hypothetical machine learning algorithm hyper-parameter spaces.
  
  It is mostly used for conducting abstract research into hyper-parameter optimization.
class_docstr_tok: ["This","class","represents","a","simulation","of","hypothetical","machine","learning","algorithm","hyper-parameter","spaces",".","It","is","mostly","used","for","conducting","abstract","research","into","hyper-parameter","optimization","."]
code: def runSearch(self, currentResults, trials=10, atpeParams=None):
      losses = []
  
      if atpeParams is None:
          atpeParams = {
              "gamma": 1.0,
              "nEICandidates": 24,
              "secondaryCutoff": 0,
              "secondaryCorrelationExponent": 1.0,
              "secondaryProbabilityMode": {
                  "mode": "fixed",
                  "probability": 0.0,
              },
              "secondaryLockingMode": {
                  "locking": "random",
                  "percentile": 0,
              },
              "resultFilteringMode": {"filtering": "none"},
          }
  
      def getValue(result, parameter):
          if parameter["group"] == "primary":
              return result[parameter["name"]]
          elif parameter["name"] in result["group"]:
              return result["group"][parameter["name"]]
          else:
              return None
  
      initializationRounds = 10
  
      best = None
      bestLoss = None
  
      newResults = []
  
      def computePrimarySecondary():
          if len(currentResults) < initializationRounds:
              return (
                  self.parameters,
                  [],
                  [0.5] * len(self.parameters),
              )  # Put all parameters as primary
  
          if len(set(result["loss"] for result in currentResults)) < 5:
              return (
                  self.parameters,
                  [],
                  [0.5] * len(self.parameters),
              )  # Put all parameters as primary
  
          cutoffForTrial = atpeParams["secondaryCutoff"]
  
          def getValue(result, parameter):
              if parameter["group"] == "primary":
                  return result[parameter["name"]]
              elif parameter["name"] in result["group"]:
                  return result["group"][parameter["name"]]
              else:
                  return None
  
          totalWeight = 0
          correlations = {}
          for parameter in self.parameters:
              if (
                  len(
                      set(
                          getValue(result, parameter)
                          for result in currentResults
                          if getValue(result, parameter) is not None
                      )
                  )
                  < 2
              ):
                  correlations[parameter["name"]] = 0
              else:
                  values = []
                  valueLosses = []
                  for result in currentResults:
                      if isinstance(
                          getValue(result, parameter), float
                      ) or isinstance(getValue(result, parameter), int):
                          values.append(getValue(result, parameter))
                          valueLosses.append(result["loss"])
  
                  correlation = math.pow(
                      abs(
                          scipy.stats.spearmanr(values, valueLosses)[0]
                      ),
                      atpeParams["secondaryCorrelationExponent"],
                  )
                  correlations[parameter["name"]] = correlation
                  totalWeight += correlation
  
          threshold = totalWeight * abs(cutoffForTrial)
  
          if cutoffForTrial < 0:
              # Reverse order - we lock in the highest correlated parameters
              sortedParameters = sorted(
                  self.parameters,
                  key=lambda parameter: correlations[parameter["name"]],
              )
          else:
              # Normal order - sort properties by their correlation to lock in lowest correlated parameters
              sortedParameters = sorted(
                  self.parameters,
                  key=lambda parameter: -correlations[
                      parameter["name"]
                  ],
              )
  
          primaryParameters = []
          secondaryParameters = []
          cumulative = totalWeight
          for parameter in sortedParameters:
              if cumulative < threshold:
                  secondaryParameters.append(parameter)
              else:
                  primaryParameters.append(parameter)
  
              cumulative -= correlations[parameter["name"]]
  
          return primaryParameters, secondaryParameters, correlations
  
      while len(newResults) < trials:
          nextParams = {}
  
          def sample(parameters):
              nonlocal nextParams
              nextParams = parameters
              return {"loss": 0.5, "status": "ok"}
  
          lockedValues = {}
          filteredResults = []
          removedResults = []
          if len(currentResults) > initializationRounds:
              (
                  primaryParameters,
                  secondaryParameters,
                  correlations,
              ) = computePrimarySecondary()
  
              sortedResults = list(
                  sorted(
                      list(currentResults),
                      key=lambda result: (
                          result["loss"]
                          if result["loss"] is not None
                          else 1.0
                      ),
                  )
              )
              topResults = sortedResults
              if atpeParams["secondaryLockingMode"]["locking"] == "top":
                  topResultsN = max(
                      1,
                      int(
                          math.ceil(
                              len(sortedResults)
                              * atpeParams["secondaryLockingMode"][
                                  "percentile"
                              ]
                              / 100.0
                          )
                      ),
                  )
                  topResults = sortedResults[:topResultsN]
  
              if best is not None:
                  # Any secondary parameters have may be locked to either the current best value or any value within the result pool.
                  for secondary in secondaryParameters:
                      if (
                          atpeParams["secondaryProbabilityMode"]["mode"]
                          == "fixed"
                      ):
                          if (
                              random.uniform(0, 1)
                              < atpeParams["secondaryProbabilityMode"][
                                  "probability"
                              ]
                          ):
                              if (
                                  atpeParams["secondaryLockingMode"][
                                      "locking"
                                  ]
                                  == "top"
                              ):
                                  lockResult = random.choice(topResults)
                                  if (
                                      getValue(lockResult, secondary)
                                      is not None
                                  ):
                                      lockedValues[
                                          secondary["name"]
                                      ] = getValue(
                                          lockResult, secondary
                                      )
                              elif (
                                  atpeParams["secondaryLockingMode"][
                                      "locking"
                                  ]
                                  == "random"
                              ):
                                  if "rounding" in secondary["space"]:
                                      lockedValues[
                                          secondary["name"]
                                      ] = random.choice(
                                          numpy.linspace(
                                              0.0,
                                              1.0,
                                              num=(
                                                  secondary[
                                                      "cardinality"
                                                  ]
                                                  + 1
                                              ),
                                          )
                                      )
                                  else:
                                      lockedValues[
                                          secondary["name"]
                                      ] = random.uniform(0.0, 1.0)
                      elif (
                          atpeParams["secondaryProbabilityMode"]["mode"]
                          == "correlation"
                      ):
                          probability = max(
                              0,
                              min(
                                  1,
                                  abs(correlations[secondary["name"]])
                                  * atpeParams[
                                      "secondaryProbabilityMode"
                                  ]["multiplier"],
                              ),
                          )
                          if random.uniform(0, 1) < probability:
                              if (
                                  atpeParams["secondaryLockingMode"][
                                      "locking"
                                  ]
                                  == "top"
                              ):
                                  lockResult = random.choice(topResults)
                                  if (
                                      getValue(lockResult, secondary)
                                      is not None
                                  ):
                                      lockedValues[
                                          secondary["name"]
                                      ] = getValue(
                                          lockResult, secondary
                                      )
                              elif (
                                  atpeParams["secondaryLockingMode"][
                                      "locking"
                                  ]
                                  == "random"
                              ):
                                  if "rounding" in secondary["space"]:
                                      lockedValues[
                                          secondary["name"]
                                      ] = random.choice(
                                          numpy.linspace(
                                              0.0,
                                              1.0,
                                              num=(
                                                  secondary[
                                                      "cardinality"
                                                  ]
                                                  + 1
                                              ),
                                          )
                                      )
                                  else:
                                      lockedValues[
                                          secondary["name"]
                                      ] = random.uniform(0.0, 1.0)
  
              # Now last step, we filter results prior to sending them into ATPE
              for resultIndex, result in enumerate(currentResults):
                  if (
                      atpeParams["resultFilteringMode"]["filtering"]
                      == "none"
                  ):
                      filteredResults.append(result)
                  elif (
                      atpeParams["resultFilteringMode"]["filtering"]
                      == "random"
                  ):
                      if (
                          random.uniform(0, 1)
                          < atpeParams["resultFilteringMode"][
                              "probability"
                          ]
                      ):
                          filteredResults.append(result)
                      else:
                          removedResults.append(result)
                  elif (
                      atpeParams["resultFilteringMode"]["filtering"]
                      == "age"
                  ):
                      age = float(resultIndex) / float(
                          len(currentResults)
                      )
                      if random.uniform(0, 1) < (
                          atpeParams["resultFilteringMode"][
                              "multiplier"
                          ]
                          * age
                      ):
                          filteredResults.append(result)
                      else:
                          removedResults.append(result)
                  elif (
                      atpeParams["resultFilteringMode"]["filtering"]
                      == "loss_rank"
                  ):
                      rank = 1.0 - (
                          float(sortedResults.index(result))
                          / float(len(currentResults))
                      )
                      if random.uniform(0, 1) < (
                          atpeParams["resultFilteringMode"][
                              "multiplier"
                          ]
                          * rank
                      ):
                          filteredResults.append(result)
                      else:
                          removedResults.append(result)
  
          # If we are in initialization, or by some other fluke of random nature that we end up with no results after filtering,
          # then just use all the results
          if len(filteredResults) == 0:
              filteredResults = currentResults
  
          space = {}
          for parameter in self.parameters:
              if parameter["group"] == "primary":
                  if parameter["name"] in lockedValues:
                      space[parameter["name"]] = lockedValues[
                          parameter["name"]
                      ]
                  elif "rounding" in parameter["space"]:
                      space[parameter["name"]] = hyperopt.hp.quniform(
                          parameter["name"],
                          0,
                          1,
                          parameter["space"]["rounding"],
                      )
                  else:
                      space[parameter["name"]] = hyperopt.hp.uniform(
                          parameter["name"], 0, 1
                      )
  
          groups = []
          for groupIndex, group in enumerate(self.subGroups):
              groupSpace = {"group": "group" + str(groupIndex + 1)}
              for parameter in group["parameters"]:
                  if parameter["name"] in lockedValues:
                      groupSpace[parameter["name"]] = lockedValues[
                          parameter["name"]
                      ]
                  elif "rounding" in parameter["space"]:
                      groupSpace[
                          parameter["name"]
                      ] = hyperopt.hp.quniform(
                          parameter["name"],
                          0,
                          1,
                          parameter["space"]["rounding"],
                      )
                  else:
                      groupSpace[
                          parameter["name"]
                      ] = hyperopt.hp.uniform(parameter["name"], 0, 1)
              groups.append(groupSpace)
  
          space["group"] = hyperopt.hp.choice("groupIndex", groups)
  
          hyperopt.fmin(
              fn=sample,
              space=space,
              algo=functools.partial(
                  hyperopt.tpe.suggest,
                  n_startup_jobs=initializationRounds,
                  gamma=atpeParams["gamma"],
                  n_EI_candidates=int(atpeParams["nEICandidates"]),
              ),
              max_evals=1,
              trials=self.convertResultsToTrials(filteredResults),
              rstate=numpy.random.RandomState(
                  seed=int(random.randint(1, 2**32 - 1))
              ),
          )
  
          result = self.execute(nextParams)
          loss = result["loss"]
          losses.append(loss)
          data = dict(nextParams)  # Clone the next dict
          data["loss"] = loss
          data["trial"] = len(currentResults)
          currentResults.append(data)
          newResults.append(data)
  
          if best is None or loss < bestLoss:
              best = data
              bestLoss = loss
      return best, newResults
  
imports: import hyperopt
  import math
  import json
  import random
  import numpy
  import functools
  import concurrent.futures
  import os
  import sys
  import time
  import datetime
  import subprocess
  import scipy.stats
  import csv
  import pickle
  import matplotlib.pyplot
  from scipy.stats import norm
  import scipy.interpolate
  import copy
  import sklearn.preprocessing
  import sklearn.cluster
  from hypermax.utils import roundPrecision
  from hypermax.hyperparameter import Hyperparameter
  from pprint import pprint
  import psutil
  import lightgbm
label_desc: Use image node_id 10 for calling the AlgorithmSimulation obj's underlying member method code with example usage: obj.runSearch(currentResults, trials, atpeParams) and returns: best,  newResults, primaryParameters,  secondaryParameters,  correlations, result, self,  list,  unknown, self,  list,  unknown, dict, result, None, result, result, None