8000 [MRG] Add constant property to dimension for allowing to plot spaces with constant dimensions by holgern · Pull Request #883 · scikit-optimize/scikit-optimize · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Feb 28, 2024. It is now read-only.

[MRG] Add constant property to dimension for allowing to plot spaces with constant dimensions #883

Merged
merged 10 commits into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/whats_new/v0.8.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ Version 0.8.0
- |Enhancement| Improve sampler and add grid sampler
:pr:`851` by :user:`Holger Nahrstaedt <holgern>`

:mod:`skopt.space`
------------------
- |Enhancement| Add `is_constant` property to dimension and
`n_constant_dimensions` property to Space
:pr:`883` by :user:`Holger Nahrstaedt <holgern>`

:mod:`skopt.utils`
------------------
- |Fix| Fix Optimizer for full categorical spaces
Expand Down
3 changes: 0 additions & 3 deletions examples/plots/partial-dependence-plot-with-categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,3 @@ def objective(params):

_ = plot_objective(result, n_points=10, sample_source=[15, 4, 7, 15, 'b', 'entropy', 'e'],
minimum=[15, 4, 7, 15, 'b', 'entropy', 'e'])



2 changes: 0 additions & 2 deletions examples/plots/partial-dependence-plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
np.random.seed(123)
import matplotlib.pyplot as plt


#############################################################################
# Objective function
# ==================
Expand All @@ -33,7 +32,6 @@ def funny_func(x):
s += (x[i] * i) ** 2
return s


#############################################################################
# Optimisation using decision trees
# =================================
Expand Down
62 changes: 49 additions & 13 deletions skopt/space/space.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ def transformed_size(self):
def bounds(self):
raise NotImplementedError

@property
def is_constant(self):
raise NotImplementedError

@property
def transformed_bounds(self):
raise NotImplementedError
Expand Down Expand Up @@ -202,6 +206,7 @@ class Real(Dimension):

prior : "uniform" or "log-uniform", default="uniform"
Distribution to use when sampling random points for this dimension.

- If `"uniform"`, points are sampled uniformly between the lower
and upper bounds.
- If `"log-uniform"`, points are sampled uniformly between
Expand All @@ -226,6 +231,7 @@ class Real(Dimension):
dtype : str or dtype, default=np.float
float type which will be used in inverse_transform,
can be float.

"""
def __init__(self, low, high, prior="uniform", base=10, transform=None,
name=None, dtype=np.float):
Expand Down Expand Up @@ -329,6 +335,10 @@ def inverse_transform(self, Xt):
def bounds(self):
return (self.low, self.high)

@property
def is_constant(self):
return self.low == self.high

def __contains__(self, point):
if isinstance(point, list):
point = np.array(point)
Expand Down Expand Up @@ -375,6 +385,7 @@ class Integer(Dimension):
prior : "uniform" or "log-uniform", default="uniform"
Distribution to use when sampling random integers for
this dimension.

- If `"uniform"`, intgers are sampled uniformly between the lower
and upper bounds.
- If `"log-uniform"`, intgers are sampled uniformly between
Expand All @@ -383,6 +394,7 @@ class Integer(Dimension):

base : int
The logarithmic base to use for a log-uniform prior.

- Default 10, otherwise commonly 2.

transform : "identity", "normalize", optional
Expand All @@ -401,6 +413,7 @@ class Integer(Dimension):
can be int, np.int16, np.uint32, np.int32, np.int64 (default).
When set to int, `inverse_transform` returns a list instead of
a numpy array

"""
def __init__(self, low, high, prior="uniform", base=10, transform=None,
name=None, dtype=np.int64):
Expand Down Expand Up @@ -504,6 +517,10 @@ def inverse_transform(self, Xt):
def bounds(self):
return (self.low, self.high)

@property
def is_constant(self):
return self.low == self.high

def __contains__(self, point):
if isinstance(point, list):
point = np.array(point)
Expand Down Expand Up @@ -548,7 +565,7 @@ class Categorical(Dimension):
transform : "onehot", "string", "identity", "label", default="onehot"
- "identity", the transformed space is the same as the original
space.
- "string", the transformed space is a string encoded
- "string", the transformed space is a string encoded
representation of the original space.
- "label", the transformed space is a label encoded
representation (integer) of the original space.
Expand All @@ -557,6 +574,7 @@ class Categorical(Dimension):

name : str or None
Name associated with dimension, e.g., "colors".

"""
def __init__(self, categories, prior=None, transform=None, name=None):
self.categories = tuple(categories)
Expand Down Expand Up @@ -669,6 +687,10 @@ def transformed_size(self):
def bounds(self):
return self.categories

@property
def is_constant(self):
return len(self.categories) <= 1

def __contains__(self, point):
return point in self.categories

Expand Down Expand Up @@ -752,25 +774,28 @@ def from_yaml(cls, yml_path, namespace=None):
yml_path : str
Full path to yaml configuration file, example YaML below:
Space:
- Integer:
low: -5
high: 5
- Categorical:
categories:
- a
- b
- Real:
low: 1.0
high: 5.0
prior: log-uniform

- Integer:
low: -5
high: 5
- Categorical:
categories:
- a
- b
- Real:
low: 1.0
high: 5.0
prior: log-uniform

namespace : str, default=None
Namespace within configuration file to use, will use first
namespace if not provided
namespace if not provided

Returns
-------
space : Space
Instantiated Space object

"""
with open(yml_path, 'rb') as f:
config = yaml.safe_load(f)
Expand Down Expand Up @@ -1018,6 +1043,17 @@ def is_partly_categorical(self):
"""Space contains any categorical dimensions"""
return any([isinstance(dim, Categorical) for dim in self.dimensions])

@property
def n_constant_dimensions(self):
"""Returns the number of constant dimensions which have zero degree of
freedom, e.g. an Integer dimensions with (0., 0.) as bounds.
"""
n = 0
for dim in self.dimensions:
if dim.is_constant:
n += 1
return n

def distance(self, point_a, point_b):
"""Compute distance between two points in this space.

Expand Down
11 changes: 11 additions & 0 deletions skopt/tests/test_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,17 @@ def test_space_from_space():
assert_equal(space, space2)


@pytest.mark.fast_test
def test_constant_property():
space = Space([(0.0, 1.0), (1,),
("a", "b", "c"), (1.0, 5.0, "log-uniform"), ("e",)])
assert space.n_constant_dimensions == 2
for i in [1, 4]:
assert space.dimensions[i].is_constant
for i in [0, 2, 3]:
assert not space.dimensions[i].is_constant


@pytest.mark.fast_test
def test_set_get_transformer():
# can you pass a Space instance to the Space constructor?
Expand Down
0