Skip to content

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:

data = load_dataset("moons", split=False)
X, y = data["X"], data["y"]

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 REGISTRY.

required
source str

Where the dataset comes from. It is one of these values:

  • 'sklearn': the dataset is loaded with a function of sklearn.datasets.
  • 'url': the dataset is downloaded from a web address.
  • 'synthetic': the dataset is generated by a function, for example make_moons.
required
url str

The web address of the file to download. It is used only when source='url'.

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 ValueError is raised. A cached file that does not match is downloaded again. It is used only when source='url'.

None
sklearn_loader str

The name of the sklearn.datasets function, for example 'load_iris'. It is used only when source='sklearn'.

None
synthetic_generator str

The name of the generator function, for example 'make_moons'. It is used only when source='synthetic'.

None
task str

The type of task: 'classification', 'regression', 'timeseries', 'optimization' or 'chemistry'.

required
n_features int

The number of input features. It must be at least 1.

required
n_samples int

The total number of samples. It is None when the number is not recorded, for example for the synthetic datasets, whose size is chosen when they are generated.

None
n_classes int

The number of classes. It is None for regression and time-series tasks.

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
info = DatasetInfo(
    name="iris",
    source="sklearn",
    sklearn_loader="load_iris",
    task="classification",
    n_features=4,
    n_samples=150,
    n_classes=3,
    description="Classic multi-class classification dataset.",
)

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 (n_samples, n_features).

required
y ndarray

The target vector, of shape (n_samples,).

required
feature_names list[str]

Readable names of the features, in the order of the columns of X.

required
target_name str

The name of the target in the plots and the summary.

required
task str

The type of task, usually "classification", "regression" or "timeseries".

required
metadata Any

The metadata of the dataset, for example a DatasetInfo.

None
time_index Any

The time axis for the time-series plots. It can be numeric (array-like) or a pd.DatetimeIndex.

None
theme str

The theme of the plots, "light" or "dark".

'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 eigenkit.datasets import DatasetReport, load_dataset

data = load_dataset("iris", split=False)
report = DatasetReport.from_data(data)
figs = report.plot_overview()
summary = report.summarize()
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 {"X", "y"} or {"X_train", "y_train", "X_test", "y_test"}. The training and test sets are combined.

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 X.

None
feature_names list[str]

The names of the features. If they are not given, the names come from the metadata, or they are feature_0, feature_1 and so on.

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 y.

None
time_index Any

The time axis for the time-series analysis.

None
theme str

The theme of the plots, "light" or "dark".

'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 feature_names does not have one name per feature.

plot(kind, **kwargs)

Build one plot, chosen by its kind.

Parameters:

Name Type Description Default
kind str

The kind of plot: "data_health", "target", "distributions", "correlation", "feature_target" or "timeseries_target".

required
**kwargs Any

Options of the plot, such as bins, max_features and max_points.

{}

Returns:

Type Description
Any

The matplotlib figure.

Raises:

Type Description
ValueError

If kind is not one of the kinds above.

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 shows every feature.

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, the plots are not saved.

None

Returns:

Type Description
dict[str, Any]

A dictionary from each kind of plot to its matplotlib figure. The "timeseries_target" plot is included only for a time-series task.

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 "text" key.

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, 1).

0.3
random_state int | None

The seed of the unitary V and of the sampled points.

42

Returns:

Type Description
tuple[ndarray, ndarray]

The pair (X, y), with X of shape (n_samples, n_qubits) and y of shape (n_samples,). The labels are 0 and 1.

Raises:

Type Description
ValueError

If gap is not in [0, 1), or if n_qubits < 1.

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 (X, y), with X of shape (n_samples, 2) and y of shape (n_samples,).

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 and 1.

0.5
random_state int | None

The random seed, for reproducible results.

42

Returns:

Type Description
tuple[ndarray, ndarray]

The pair (X, y), with X of shape (n_samples, 2) and y of shape (n_samples,).

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 (X, y), with X of shape (n_samples, 2) and y of shape (n_samples,).

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 (X, y), with X of shape (n_samples, n_features) and y of shape (n_samples,), both of type float32.

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" for a sine wave with noise, or "ar" for an autoregressive process of order 1, written AR(1).

'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 (t, y), two arrays of shape (n_samples,) and type float32. t holds time values spaced evenly in [0, 1], and y is the signal. The arrays are not cut into windows, because the algorithms do that.

get_dataset_info(name)

Return the DatasetInfo of a dataset.

Parameters:

Name Type Description Default
name str

The key of the dataset in REGISTRY.

required

Returns:

Type Description
DatasetInfo

The metadata of the dataset.

Raises:

Type Description
ValueError

If name is not in the registry. The message lists every available name.

Example
info = get_dataset_info("iris")

list_datasets()

Return the metadata of every available dataset.

Returns:

Type Description
list[DatasetInfo]

One DatasetInfo for each dataset in the registry.

Example
datasets = list_datasets()
print(datasets[0].name)  # 'breast_cancer_wisconsin'

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 REGISTRY, for example "iris".

required
split bool

If True, the default, the data is split into a training set and a test set.

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, the default, there is no validation set.

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:

  • With split=True: "X_train", "y_train", "X_test", "y_test" and "metadata", and also "X_val" and "y_val" when validation_size is above 0.
  • With split=False: "X", "y" and "metadata".

The synthetic time-series datasets also have a "sequence" key, which holds the whole series. "metadata" is the DatasetInfo of the dataset.

Raises:

Type Description
ValueError

If name is not in the registry, if validation_size is not in [0, 1), or if test_size + validation_size is 1 or more with split=True.

Example
data = load_dataset("iris")
X_train, y_train = data["X_train"], data["y_train"]

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" or "dark". The case and any surrounding spaces are ignored.

'light'

Returns:

Type Description
dict

The rcParams to draw with, ready for matplotlib.rc_context().

Raises:

Type Description
ValueError

If theme is neither "light" nor "dark".

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")