Esempio n. 1
0
    def __init__(self,
                 pipeline_hyperparameter_ranges,
                 random_seed=0,
                 with_replacement=False,
                 replacement_max_attempts=10):
        """ Sets up check for duplication if needed.

        Arguments:
            pipeline_hyperparameter_ranges (dict): a set of hyperparameter ranges corresponding to a pipeline's parameters
            random_state (int): Unused in this class. Defaults to 0.
            with_replacement (bool): If false, only unique hyperparameters will be shown
            replacement_max_attempts (int): The maximum number of tries to get a unique
                set of random parameters. Only used if tuner is initalized with
                with_replacement=True
            random_seed (int): Seed for random number generator. Defaults to 0.
        """
        super().__init__(pipeline_hyperparameter_ranges,
                         random_seed=random_seed)
        self._space = Space(self._search_space_ranges)
        self._random_state = get_random_state(random_seed)
        self._with_replacement = with_replacement
        self._replacement_max_attempts = replacement_max_attempts
        self._used_parameters = set()
        self._used_parameters.add(())
        self.curr_params = None
Esempio n. 2
0
    def _init_space(self, space) -> Space:
        if space is None:
            self._domain = None
        elif len(space) == len(self.free_variables):
            self._domain = Space(space)
        elif len(space) == 1:
            self._domain = Space(space * len(self.free_variables))
        else:
            raise ValueError("space is not correct")

        return self.domain
Esempio n. 3
0
	def initial_sampling(self, sampling_method=None):
		if sampling_method is not None:
			self.sampling_method = sampling_method
		
		if self.sampling_method.lower() in ['lh', 'lhs', 'latin hypercube', 'lh-maximin']:
			if self.sampling_method.lower() in ['lh', 'lhs', 'latin hypercube']:
				print('Using maximin criteria for latin hypercube sampling.')
				print('To use classic, centered, correlation or ratio-optimised criteria, input sampling_method') 
				print('as lh-classic, lh-centered, lh-correlation and lh-ratio-optimised respectively.')
			samp = smp.Lhs(criterion="maximin", iterations=10000) 
		elif self.sampling_method.lower() in ['lh-classic']:
			samp = smp.Lhs(lhs_type="classic", criterion=None)
		elif self.sampling_method.lower() in ['lh-centered']:
			samp = smp.Lhs(lhs_type="centered", criterion=None)
		elif self.sampling_method.lower() in ['lh-correlation']:
			samp = smp.Lhs(criterion="correlation", iterations=10000)	
		elif self.sampling_method.lower() in ['lh-ratio-optimised']:
			samp = smp.Lhs(criterion="ratio", iterations=10000)
		elif self.sampling_method.lower() in ['sobol']:
			samp = smp.Sobol()
		elif self.sampling_method.lower() in ['halton']:
			samp = smp.Halton()
		elif self.sampling_method.lower() in ['hammersly']:
			samp = smp.Hammersly()
		elif self.sampling_method.lower() in ['grid']:
			samp = smp.Grid(border="include", use_full_layout=False)

		# print('Creating initial sampling...')
		# space = Space([(self.range_param[ke][0],self.range_param[ke][1]) for ke in self.range_param.keys()]) 
		space = Space([(0,self.n_samples) for ke in self.range_param.keys()]) 
		self.init_points = np.array(samp.generate(space.dimensions, self.n_samples)).astype(float)
		for i,ke in enumerate(self.range_param.keys()):
			self.init_points[:,i] = self.init_points[:,i]*(self.range_param[ke][1]-self.range_param[ke][0])/self.n_samples+self.range_param[ke][0]
Esempio n. 4
0
def orion_space_to_skopt_space(orion_space):
    """Convert Oríon's definition of problem's domain to a skopt compatible."""
    dimensions = []
    for key, dimension in orion_space.items():
        low, high = dimension.interval()
        shape = dimension.shape
        assert not shape or shape == [1]
        if not shape:
            shape = (1,)
            low = (low,)
            high = (high,)
        dimensions.append(Real(name=key, prior="uniform", low=low[0], high=high[0]))

    return Space(dimensions)
Esempio n. 5
0
def convert_orion_space_to_skopt_space(orion_space):

    dimensions = []
    for key, dimension in orion_space.items():
        dimension_class = globals()[dimension.__class__.__name__]

        low = dimension._args[0]
        high = low + dimension._args[1]
        # NOTE: A hack, because orion priors have non-inclusive higher bound
        #       while scikit-optimizer have inclusive ones.
        high = high - numpy.abs(high - 0.0001) * 0.0001
        dimensions.append(
            dimension_class(
                name=key, prior=dimension._prior_name,
                low=low, high=high))

    return Space(dimensions)
Esempio n. 6
0
def skopt_main():
    from skopt import Optimizer, dump, load, Space
    from skopt.learning import GaussianProcessRegressor
    from skopt.space import Real, Integer
    fname = 'optimizer-exp-pendulum-4.pkl'
    dims = [Integer(15, 500), Real(0.025, 0.1, prior="log-uniform")]
    try:
        optimizer = load(fname)
        optimizer.space = Space(dims)
    except:
        optimizer = Optimizer(dimensions=dims, random_state=1)
    n_jobs = 2
    for i in range(3):
        pool = Pool(n_jobs, initializer=mute)
        x = optimizer.ask(n_points=n_jobs)  # x is a list of n_points points
        print(x)
        y = pool.map(f, x)
        pool.close()
        optimizer.tell(x, y)
        print('Iteration %d. Best yi %.2f' % (i, min(optimizer.yi)))

    dump(optimizer, fname)
Esempio n. 7
0
def convert_orion_space_to_skopt_space(orion_space):
    """Convert Oríon's definition of problem's domain to a skopt compatible."""
    dimensions = []
    for key, dimension in orion_space.items():
        #  low = dimension._args[0]
        #  high = low + dimension._args[1]
        low, high = dimension.interval()
        # NOTE: A hack, because orion priors have non-inclusive higher bound
        #       while scikit-optimizer have inclusive ones.
        high = numpy.nextafter(high, high - 1)
        shape = dimension.shape
        assert not shape or len(shape) == 1
        if not shape:
            shape = (1, )
        # Unpack dimension
        for i in range(shape[0]):
            dimensions.append(
                Real(name=key + '_' + str(i),
                     prior='uniform',
                     low=low,
                     high=high))

    return Space(dimensions)
Esempio n. 8
0
def test_categorical_gp_has_gradients():
    space = Space([('a', 'b')])

    assert not has_gradients(cook_estimator('GP', space=space))
Esempio n. 9
0
def test_has_gradients(estimator, gradients):
    space = Space([(-2.0, 2.0)])

    assert has_gradients(cook_estimator(estimator, space=space)) == gradients
Esempio n. 10
0
class RandomSearchTuner(Tuner):
    """Random Search Optimizer.

    Example:
        >>> tuner = RandomSearchTuner({'My Component': {'param a': [0.0, 10.0], 'param b': ['a', 'b', 'c']}}, random_seed=42)
        >>> proposal = tuner.propose()
        >>> assert proposal.keys() == {'My Component'}
        >>> assert proposal['My Component'] == {'param a': 3.7454011884736254, 'param b': 'c'}
    """
    def __init__(self,
                 pipeline_hyperparameter_ranges,
                 random_seed=0,
                 with_replacement=False,
                 replacement_max_attempts=10):
        """ Sets up check for duplication if needed.

        Arguments:
            pipeline_hyperparameter_ranges (dict): a set of hyperparameter ranges corresponding to a pipeline's parameters
            random_state (int): Unused in this class. Defaults to 0.
            with_replacement (bool): If false, only unique hyperparameters will be shown
            replacement_max_attempts (int): The maximum number of tries to get a unique
                set of random parameters. Only used if tuner is initalized with
                with_replacement=True
            random_seed (int): Seed for random number generator. Defaults to 0.
        """
        super().__init__(pipeline_hyperparameter_ranges,
                         random_seed=random_seed)
        self._space = Space(self._search_space_ranges)
        self._random_state = get_random_state(random_seed)
        self._with_replacement = with_replacement
        self._replacement_max_attempts = replacement_max_attempts
        self._used_parameters = set()
        self._used_parameters.add(())
        self.curr_params = None

    def add(self, pipeline_parameters, score):
        """Not applicable to random search tuner as generated parameters are
        not dependent on scores of previous parameters.

        Arguments:
            pipeline_parameters (dict): A dict of the parameters used to evaluate a pipeline
            score (float): The score obtained by evaluating the pipeline with the provided parameters
        """
        pass

    def _get_sample(self):
        return tuple(self._space.rvs(random_state=self._random_state)[0])

    def propose(self):
        """Generate a unique set of parameters.

        If tuner was initialized with ``with_replacement=True`` and the tuner is unable to
        generate a unique set of parameters after ``replacement_max_attempts`` tries, then ``NoParamsException`` is raised.

        Returns:
            dict: Proposed pipeline parameters
        """
        if not len(self._search_space_ranges):
            return self._convert_to_pipeline_parameters({})
        if self._with_replacement:
            return self._convert_to_pipeline_parameters(self._get_sample())
        elif not self.curr_params:
            self.is_search_space_exhausted()
        params = self.curr_params
        self.curr_params = None
        return self._convert_to_pipeline_parameters(params)

    def is_search_space_exhausted(self):
        """Checks if it is possible to generate a set of valid parameters. Stores generated parameters in
        ``self.curr_params`` to be returned by ``propose()``.

        Raises:
            NoParamsException: If a search space is exhausted, then this exception is thrown.

        Returns:
            bool: If no more valid parameters exists in the search space, return false.
        """
        if self._with_replacement:
            return False
        else:
            curr_params = ()
            attempts = 0
            while curr_params in self._used_parameters:
                if attempts >= self._replacement_max_attempts:
                    raise NoParamsException(
                        "Cannot create a unique set of unexplored parameters. Try expanding the search space."
                    )
                    return True
                attempts += 1
                curr_params = self._get_sample()
            self._used_parameters.add(curr_params)
            self.curr_params = curr_params
            return False