[object Object]

by The digiLab Team

Updated 5 March 2024

twinLab Feature Release: Initial Design Spaces

If you're building a model or set of experiments from scratch, sometimes you need a particular scheme of sampling to effectively span the entire design space at hand. You can do this with a simple function call in twinLab.
[object Object]

In this article, we will see how to get recommendations of points to be sampled in the design space before training an emulator.

Let's start by importing all the necessary packages and dependencies. You'll need an API key to use twinLab - get one by hitting the "Try twinLab" button in the top right of the website!

# Package imports
import matplotlib.pyplot as plt
import plotly.graph_objects as go

# twinLab imports
import twinlab as tl
tl.set_api_key("Your-API-Key")

twinLab allows the user to specify the prior distribution for each of the input dimensions. Here, these priors are in the form of uniform distributions that are defined with a lower and upper bound. Let's go ahead and create priors for a two-dimensional input.

# Define the upper and lower bounds for the uniform distribution
xmin1, xmax1 = 4.0, 6.0
xmin2, xmax2 = -1.0, 1.0

# Define the number of points to be sampled
num_samples = 10

# Create a list of Prior objects that contains the distribution for each dimension
priors = [
    tl.Prior("x1", tl.distributions.Uniform(xmin1, xmax1)),
    tl.Prior("x2", tl.distributions.Uniform(xmin2, xmax2)),
]

Now, we can call the design method of the Emulator class. The function takes in a list of priors (one prior for each input variable), a sampling method which specifies the strategy, and a number of points to be sampled. This function returns a pandas DataFrame that contains the recommended points.

Let's first generate some samples with the Latin Hypercube Sampling method.

# Initialise an emulator
emulator = tl.Emulator("test_emulator")

# Call the design method to sample some data points with Latin Hypercube sampling
initial_points_lhc = emulator.design(priors, num_samples, tl.DesignParams())
display(initial_points_lhc)

We can also generate some samples with a Uniform Random method by using sampling_method = tl.sampling.UniformRandom().

# Define the InitialDesignParams object with Uniform Random Sampling Method
params = tl.DesignParams(sampling_method=tl.sampling.UniformRandom())

# Call the design method to sample some data points with Uniform Random sampling
initial_points_random = emulator.design(
    priors=priors, num_points=num_samples, params=params
)
display(initial_points_random)

We can plot the generated samples on a two-dimensional plot and visualise them.

# Create 2-D scatter plot to visualise the generated data points
plt.scatter(initial_points_lhc["x1"], initial_points_lhc["x2"], color="red", label="Latin Hypercube")
plt.scatter(initial_points_random["x1"], initial_points_random["x2"], color="blue", label="Uniform Random")
plt.xlim(xmin1, xmax1)
plt.ylim(xmin2, xmax2)
plt.legend()
plt.gca().set_aspect("equal")
plt.show()
2-D Scatter Plot

2-D Scatter Plot

We can see that the recommended points are from different regions of the space and this is a good way to start with when there is no initial data at hand. Moreover, we can see that the Latin Hypercube design fills the space more evenly than Uniform Random sampling.

Three-dimensional plots

To understand this better, let's also try visualising some data in three dimensions. As in two dimensions, we start with defining the priors for each dimension.

# Define the priors for the 3 dimensions
xmin1, xmax1 = 0, 1
xmin2, xmax2 = -1, 1
xmin3, xmax3 = 1, 5
num_samples = 20
priors = [
    tl.Prior("x1", tl.distributions.Uniform(xmin1, xmax1)),
    tl.Prior("x3", tl.distributions.Uniform(xmin3, xmax3)),
    tl.Prior("x2", tl.distributions.Uniform(xmin2, xmax2)),
]

Generate some points in the three-dimensional space using the Latin HyperCube sampling method.

# Initialise an emulator
new_emulator = tl.Emulator("3D_emulator")

# Define the InitialDesignParams object
params = tl.DesignParams()

# Call the design method to sample some data points with Latin Hypercube sampling
initial_points_lhc = emulator.design(
    priors, num_samples, params=params
)
display(initial_points_lhc)

Let's also do the same with Uniform Random sampling for comparison.

# Define the DesignParams object with Uniform Random Sampling Method
params = tl.DesignParams(sampling_method=tl.sampling.UniformRandom())

# Generate the points with Uniform Random sampling and display
initial_points_random = emulator.design(
    priors, num_samples, params=params
)
display(initial_points_random)

Let's plot a nice three-dimensional visualisation of the data points generated using the design method with both the Latin Hypercube and Uniform Random sampling schemes.

# Create 3D scatter plot
fig = go.Figure()

# Add the first set of points
fig.add_trace(
    go.Scatter3d(
        x=initial_points_random["x1"],
        y=initial_points_random["x2"],
        z=initial_points_random["x3"],
        mode="markers",
        name="Uniform Random",
    )
)

# Add the second set of points
fig.add_trace(
    go.Scatter3d(
        x=initial_points_lhc["x1"],
        y=initial_points_lhc["x2"],
        z=initial_points_lhc["x3"],
        mode="markers",
        name="Latin Hypercube",
    )
)

# Set labels and title
fig.update_layout(
    scene=dict(xaxis_title="x1", yaxis_title="x2", zaxis_title="x3"),
    title="3D Scatter Plot",
    width=900,
    height=600,
)

# Show plot
fig.show()
3D Scatter Plot

3D Scatter Plot

So that's how you can kick off your initial design space using twinLab!

Probabilistic ML with twinLab

twinLab is already being used to solve next-generation engineering and sustainability challenges at organisations like the UKAEA, Airbus, and Rolls-Royce. Our vision with twinLab is to help more people and organisations to use probabilistic ML.

Just hit "Try twinLab" at the top-right, and we'll set you up with an API key, the documentation, and some example solutions.

Alternatively, if you've got a particular data challenge, book a free call with one of our solution engineers.

The digiLab Team
We are a 30+ strong team of ML Experts, Software Developers, Solution Engineers, and Product Experts. As a spinout from the University of Exeter, we build on years of cutting-edge academic research. At our core is a commitment to helping engineering and infrastructure companies become data-driven.

Featured Posts

If you found this post helpful, you might enjoy some of these other news updates.