Datasets
eigenkit includes a registry of standard datasets for classification, regression and time series, which you can use directly in quantum machine learning pipelines.
The datasets need the datasets extra, which installs scikit-learn:
pip install eigenkit[datasets]. This is enough to load a dataset and to call
DatasetReport.summarize(). The plots of the exploratory data analysis (EDA),
DatasetReport.plot*, also need matplotlib, which the viz extra installs. The
benchmark extra installs it too.
Load a dataset
from eigenkit.datasets import load_dataset
data = load_dataset("iris")
X_train, y_train = data["X_train"], data["y_train"]
X_test, y_test = data["X_test"], data["y_test"]
To also get a validation split, pass validation_size:
data = load_dataset("iris", test_size=0.15, validation_size=0.15)
X_val, y_val = data["X_val"], data["y_val"]
To get the whole dataset without a train/test split, pass split=False:
load_dataset parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
Required | The name of the dataset in the registry. It is one of the names in the table below. |
split |
bool |
True |
With True, the data is split into X_train and X_test. With False, the whole dataset is returned as X and y. |
test_size |
float |
0.2 |
The fraction of the samples held out for the test split. |
validation_size |
float |
0.0 |
The fraction of the samples held out for validation. Any value above 0 adds X_val and y_val. |
random_state |
int \| None |
42 |
The seed of the split, and of the generator for the synthetic datasets. With None, the split is not seeded. It does not affect the split of the timeseries datasets, which always follows the time order without shuffling. |
cache_dir |
str \| None |
None |
The directory where the downloaded datasets are stored. With None, it is the EIGENKIT_DATA_DIR environment variable when it is set, and ~/.eigenkit/datasets otherwise. |
Available datasets
The registry holds twelve datasets. The Reference column names the loader or the generator that produces the data.
| Dataset | Task | Description | Reference |
|---|---|---|---|
iris |
classification | Fisher's iris dataset. The task is to classify iris flowers into three species from 4 measurements of the flowers. |
sklearn.datasets.load_iris |
wine |
classification | The wine recognition dataset. The task is to classify wines into three cultivars from 13 features of a chemical analysis. |
sklearn.datasets.load_wine |
breast_cancer_wisconsin |
classification | The Wisconsin diagnostic breast cancer dataset. The task is to classify tumours as malignant or benign from 30 real-valued features. |
sklearn.datasets.load_breast_cancer |
moons |
classification | Two half-circles that interleave. It is a binary benchmark whose classes cannot be separated by a straight line. | generate_moons |
circles |
classification | Two concentric circles, a large one and a small one. It is a binary benchmark. | generate_circles |
checkerboard |
classification | A checkerboard pattern. It is a binary benchmark with a very non-linear decision boundary. | generate_checkerboard |
diabetes |
regression | The task is to predict a score of disease progression from 10 features. |
sklearn.datasets.load_diabetes |
california_housing |
regression | The task is to predict the median house value from 8 features. |
sklearn.datasets.fetch_california_housing |
concrete |
regression | The compressive strength of concrete, in megapascals. The task is to predict it from 8 features: the amounts of cement, slag, fly ash, water, superplasticiser, coarse aggregate and fine aggregate, and the age of the concrete. |
UC Irvine Machine Learning Repository, dataset 165, by I-Cheng Yeh, under the CC BY 4.0 licence, downloaded from a hosted CSV file |
sine_wave |
timeseries | A sine wave with noise. The task is to predict the next value from a window of past values. | generate_timeseries(kind="sine") |
ar_process |
timeseries | A synthetic autoregressive process of order 1, written AR(1). Its dependence over time is more realistic than that of a sine wave. |
generate_timeseries(kind="ar") |
beijing_pm25 |
timeseries | The hourly air quality in Beijing. The task is to predict the concentration of fine particulate matter (PM2.5) from the weather and the wind direction. | UC Irvine Machine Learning Repository, dataset 381, by Song Xi Chen, under the CC BY 4.0 licence, downloaded from a hosted CSV file |
list_datasets() returns the same list when your code runs, with all the metadata
of each dataset:
from eigenkit.datasets import list_datasets
for ds in list_datasets():
print(ds.name, ds.task, ds.n_features, ds.n_classes)
Synthetic generators
To choose the size and the seed of a synthetic dataset, call its generator function directly:
from eigenkit.datasets import (
generate_ad_hoc,
generate_moons,
generate_circles,
generate_checkerboard,
generate_regression,
generate_timeseries,
)
X, y = generate_moons(random_state=0)
X, y = generate_circles(random_state=42)
X, y = generate_regression(random_state=7)
X, y = generate_ad_hoc(n_samples=200, n_qubits=2, gap=0.3, random_state=0)
generate_ad_hoc builds the "ad hoc" dataset of
Havlíček et al., which is designed so that a
quantum kernel separates it. Each point in [0, 2π)^n is encoded with the ZZ
feature map, and its label is the sign of a Z parity measured after a fixed
random unitary. The points closer than gap to the decision boundary are dropped,
and the two classes have the same size. A kernel built from the same ZZ feature map
classifies the data almost perfectly, and classical kernels usually do not. It is a
test case for quantum kernels. It says nothing about an advantage on real data.
Exploratory data analysis report and plots
Use DatasetReport to run an exploratory data analysis in one call, on a built-in
dataset or on your own data.
from eigenkit.datasets import DatasetReport, load_dataset
data = load_dataset("iris", split=False)
report = DatasetReport.from_data(data, theme="light")
figures = report.plot_overview()
summary = report.summarize()
print(summary["text"])
For your own data:
import numpy as np
from eigenkit.datasets import DatasetReport
X = np.random.randn(300, 6)
y = (X[:, 0] + 0.3 * X[:, 1] > 0).astype(int)
report = DatasetReport.from_data(
X=X,
y=y,
feature_names=[f"f{i}" for i in range(X.shape[1])],
task="classification",
theme="light",
)
figures = report.plot_overview(max_features=4)
For a real hourly time series, try the
Beijing PM2.5 dataset
(dataset 381 of the UC Irvine Machine Learning Repository). It is split in time
order automatically, with the first 80% of the samples for training and the last
20% for testing:
data = load_dataset("beijing_pm25")
X_train, y_train = data["X_train"], data["y_train"]
X_test, y_test = data["X_test"], data["y_test"]
For a time-series target, pass a time index to get the seasonal analysis:
data = load_dataset("sine_wave", split=False)
report = DatasetReport.from_data(
data,
task="timeseries",
time_index=data["X"], # datetime-like index also supported
theme="light",
)
ts_fig = report.plot(kind="timeseries_target")
ts_summary = report.summarize()["timeseries"]
print(ts_summary["recommended_lags"])
With theme="dark", the backgrounds of the plots and the legends are transparent,
and the text is white.
The same style for your own figures
DatasetReport draws inside a matplotlib context that gives every figure of the
library the same palette, font sizes and spines. This context is public, so your
own plots can use the same style. Examples are a training curve next to an EDA
report, a figure for a paper, or the plots in the
worked examples:
import matplotlib
import matplotlib.pyplot as plt
from eigenkit.datasets import STYLE_COLORS, rc_params
with matplotlib.rc_context(rc_params(theme="light")):
fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(model.train_losses_, color=STYLE_COLORS[0], label="train loss")
ax.plot(model.validation_losses_, color=STYLE_COLORS[1], label="validation loss")
ax.set_xlabel("epoch")
ax.set_ylabel("loss")
ax.legend()
| Name | What it is |
|---|---|
rc_params(theme="light") |
The settings for one figure, as a dictionary for matplotlib.rc_context(). The theme is "light" or "dark", and any other value raises a ValueError. |
STYLE_COLORS |
The palette, as a tuple of eight hexadecimal colour strings in the order of the colour cycle. rc_params() sets it as axes.prop_cycle, so index it only when a series needs a fixed colour. |
FONTSIZE_AXES |
20, the font size of the axis labels and the titles. |
FONTSIZE_LEGEND |
18, the font size of the legend entries. |
FONTSIZE_TICKS |
16, the font size of the tick labels, which is also the base font.size. |
rc_params() returns a new dictionary and never changes the global
matplotlib.rcParams, so the settings apply only inside the rc_context block.
Two calls with the same theme return equal dictionaries. This is why a figure can
be drawn again with the other theme and differ only in its background and in the
colour of its text and lines.
API reference
eigenkit.datasets
The datasets of eigenkit: the registry of their metadata, and the loaders.
FONTSIZE_AXES = 20
module-attribute
The font size, in points, that rc_params() gives the axis labels and titles.
FONTSIZE_LEGEND = 18
module-attribute
The font size, in points, that rc_params() gives the legend entries.
FONTSIZE_TICKS = 16
module-attribute
The font size, in points, of the tick labels, which is also the base font.size.
STYLE_COLORS = ('#CE2173', '#AA5EFF', '#7D4ECF', '#43CDFF', '#3333FB', '#11E57A', '#E6C541', '#94A3B8')
module-attribute
The plot palette of the library, in the order of the colour cycle.
rc_params() sets it as axes.prop_cycle, so a plot drawn inside that context
uses these colours without naming them. Index it when a series needs a fixed
colour, and not the next one in the cycle. For example, use STYLE_COLORS[0] for
a training curve and STYLE_COLORS[1] for validation, so that the two curves
keep their colours across figures. It is a tuple, so that an append by mistake
cannot change how every later plot in the process looks.
DatasetInfo
Bases: BaseModel
The metadata of a dataset that eigenkit provides.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The unique name of the dataset, which is also its key in
|
required |
source
|
str
|
Where the dataset comes from. It is one of these values:
|
required |
url
|
str
|
The web address of the file to download. It is used
only when |
None
|
sha256
|
str
|
The SHA-256 hash, in hexadecimal, that the
downloaded file must match. A downloaded file that does not match is
deleted, and a |
None
|
sklearn_loader
|
str
|
The name of the |
None
|
synthetic_generator
|
str
|
The name of the generator function, for
example |
None
|
task
|
str
|
The type of task: |
required |
n_features
|
int
|
The number of input features. It must be at least |
required |
n_samples
|
int
|
The total number of samples. It is |
None
|
n_classes
|
int
|
The number of classes. It is |
None
|
feature_names
|
list[str]
|
Readable names of the input features. |
None
|
target_names
|
list[str]
|
Readable names of the classes, or of the output. |
None
|
window_size
|
int
|
The recommended size of the sliding window, for time-series datasets. |
None
|
description
|
str
|
A short description of the dataset. |
required |
Example
DatasetReport
dataclass
An exploratory data analysis (EDA) report for a built-in or custom dataset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
ndarray
|
The feature matrix, of shape |
required |
y
|
ndarray
|
The target vector, of shape |
required |
feature_names
|
list[str]
|
Readable names of the features, in the order of
the columns of |
required |
target_name
|
str
|
The name of the target in the plots and the summary. |
required |
task
|
str
|
The type of task, usually |
required |
metadata
|
Any
|
The metadata of the dataset, for example a
|
None
|
time_index
|
Any
|
The time axis for the time-series plots. It can
be numeric (array-like) or a |
None
|
theme
|
str
|
The theme of the plots, |
'light'
|
Notes
The recommended way to build a report is from_data(), which accepts the
dictionaries returned by load_dataset(...) as well as your own X and
y.
Example
from_data(data=None, *, X=None, y=None, feature_names=None, target_name='target', task=None, time_index=None, theme='light')
classmethod
Build a report from a dataset dictionary, or from your own arrays or tensors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
dict[str, Any]
|
A dataset dictionary in the format of
eigenkit, either |
None
|
X
|
Any
|
Your own feature matrix, as a NumPy array, a pandas object, a PyTorch tensor or another array-like. |
None
|
y
|
Any
|
Your own target vector, in the same formats as |
None
|
feature_names
|
list[str]
|
The names of the features. If they are
not given, the names come from the metadata, or they are |
None
|
target_name
|
str
|
The name of the target in the plots and the summary. |
'target'
|
task
|
str
|
The type of task. If it is not given, it is taken
from the metadata, or guessed from |
None
|
time_index
|
Any
|
The time axis for the time-series analysis. |
None
|
theme
|
str
|
The theme of the plots, |
'light'
|
Returns:
| Type | Description |
|---|---|
'DatasetReport'
|
The report, ready for plotting and for the summary. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the inputs are missing or do not agree, for example if the
shapes do not match, or if |
plot(kind, **kwargs)
Build one plot, chosen by its kind.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
str
|
The kind of plot: |
required |
**kwargs
|
Any
|
Options of the plot, such as |
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
The matplotlib figure. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
plot_overview(*, max_features=None, bins=30, max_points=2000, path=None)
Build the default set of plots of the exploratory data analysis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_features
|
int
|
The largest number of features shown in the
panels about features. |
None
|
bins
|
int
|
The number of histogram bins in the distribution plots. |
30
|
max_points
|
int
|
The largest number of points in the scatter plots. Larger datasets are subsampled. |
2000
|
path
|
str | Path
|
A directory where every overview plot is saved
as a PNG file. With |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
A dictionary from each kind of plot to its matplotlib figure. The
|
summarize()
Build a reproducible summary of the dataset, with recommendations.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
A dictionary with statistics about the shape and the quality of the data,
signals specific to the task when there are any, and a readable summary
under the |
generate_ad_hoc(n_samples=200, n_qubits=2, gap=0.3, random_state=42)
Generate the "ad hoc" dataset of Havlíček et al., Nature 567, 209 (2019).
The dataset is designed so that a quantum kernel separates it. Each point x in
[0, 2π)^n is encoded with the ZZ feature map, with two repetitions as in
Qiskit's ZZFeatureMap. Its label is the sign of ⟨ψ(x)| V† Z^{⊗n} V |ψ(x)⟩
for a fixed random unitary V. The points closer than gap to the decision
boundary are dropped, and the two classes are balanced. A kernel built from the
same ZZ feature map classifies the data almost perfectly, and classical kernels
usually do not.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples
|
int
|
The number of points, split evenly between the two classes. |
200
|
n_qubits
|
int
|
The number of features, which is also the number of qubits of the circuit that generates the data. |
2
|
gap
|
float
|
The margin around the decision boundary, in |
0.3
|
random_state
|
int | None
|
The seed of the unitary |
42
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
The pair |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
generate_checkerboard(n_samples=200, grid_size=2, random_state=42)
Generate a dataset with a checkerboard pattern.
The points are drawn uniformly in [0, grid_size]². The label is
(floor(x) + floor(y)) % 2, which gives regions of alternating classes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples
|
int
|
The number of points to generate. |
200
|
grid_size
|
int
|
The number of cells along each axis. |
2
|
random_state
|
int | None
|
The random seed, for reproducible results. |
42
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
The pair |
generate_circles(n_samples=200, noise=0.05, factor=0.5, random_state=42)
Generate two concentric circles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples
|
int
|
The number of points to generate. |
200
|
noise
|
float
|
The standard deviation of the Gaussian noise added to the data. |
0.05
|
factor
|
float
|
The ratio of the inner circle to the outer circle, between |
0.5
|
random_state
|
int | None
|
The random seed, for reproducible results. |
42
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
The pair |
generate_moons(n_samples=200, noise=0.1, random_state=42)
Generate two half-circles that interleave, called moons.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples
|
int
|
The number of points to generate. |
200
|
noise
|
float
|
The standard deviation of the Gaussian noise added to the data. |
0.1
|
random_state
|
int | None
|
The random seed, for reproducible results. |
42
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
The pair |
generate_regression(n_samples=200, n_features=4, noise=0.1, random_state=42)
Generate a synthetic regression dataset with scikit-learn's make_regression.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples
|
int
|
The number of samples to generate. |
200
|
n_features
|
int
|
The number of input features. |
4
|
noise
|
float
|
The standard deviation of the Gaussian noise on the output. |
0.1
|
random_state
|
int | None
|
The random seed, for reproducible results. |
42
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
The pair |
generate_timeseries(n_samples=300, kind='sine', noise=0.05, random_state=42)
Generate a 1-D time series, as the pair (t, y).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_samples
|
int
|
The number of time steps. |
300
|
kind
|
str
|
The shape of the series: |
'sine'
|
noise
|
float
|
The standard deviation of the Gaussian noise. |
0.05
|
random_state
|
int | None
|
The random seed, for reproducible results. |
42
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
The pair |
get_dataset_info(name)
Return the DatasetInfo of a dataset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The key of the dataset in |
required |
Returns:
| Type | Description |
|---|---|
DatasetInfo
|
The metadata of the dataset. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
list_datasets()
Return the metadata of every available dataset.
Returns:
| Type | Description |
|---|---|
list[DatasetInfo]
|
One |
load_dataset(name, *, split=True, test_size=0.2, validation_size=0.0, random_state=42, cache_dir=None)
Load a dataset by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the dataset in |
required |
split
|
bool
|
If |
True
|
test_size
|
float
|
The fraction of the samples used for the test set. |
0.2
|
validation_size
|
float
|
The fraction of the samples used for the validation set.
With |
0.0
|
random_state
|
int | None
|
The random seed of the split, and of the generator for the synthetic datasets. |
42
|
cache_dir
|
str | None
|
A cache directory for the downloaded datasets, in place of the default one. |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
A dictionary with these keys:
The synthetic time-series datasets also have a |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
rc_params(theme='light')
Return the matplotlib settings of the library for one plot, as rcParams.
Every figure that the library draws uses these settings:
DatasetReport.plot_overview(), the benchmark curves and the plots in the worked
examples. This is what makes them look like one set. Pass the result to
matplotlib.rc_context() and draw as usual. The settings apply only inside that
block, because the returned dictionary is a new copy and the global
matplotlib.rcParams is never changed.
The two themes differ only in what has to change for a dark page. "dark" makes
the backgrounds of the figure, the axes and the legend transparent, and makes the
text, the ticks and the spines white. The sizes, the spines, the grid and
STYLE_COLORS are the same in both themes, so
a figure saved with each theme differs only in its background and in the colour
of its text and lines.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
theme
|
str
|
|
'light'
|
Returns:
| Type | Description |
|---|---|
dict
|
The rcParams to draw with, ready for |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Example
import matplotlib
import matplotlib.pyplot as plt
from eigenkit.datasets import STYLE_COLORS, rc_params
with matplotlib.rc_context(rc_params(theme="light")):
fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(history, color=STYLE_COLORS[0], label="train loss")
ax.legend()
fig.savefig("loss.png", bbox_inches="tight")