Classification benchmark: Circles dataset using eigenkit
Why this problem matters
The circles dataset is a standard benchmark for non-linear classification. It checks whether a model can separate classes with a curved boundary, where simple linear classifiers usually fail.
Dataset
This example uses the synthetic circles dataset from eigenkit.datasets: two
concentric circles, a large one and a small one.
Our approach: Hybrid Quantum-Classical Classification (HQNC)
In this example, we train the hybrid quantum neural network classifier (HQNC) of eigenkit, and we measure the quality of its predictions on a test split that is kept out of training.
Import libraries
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score, classification_report, f1_score
from eigenkit.datasets import STYLE_COLORS, load_dataset, rc_params
from eigenkit import HQNC
Loading the selected dataset
# Load and split synthetic circles dataset
data = load_dataset("circles", split=True, test_size=0.2, random_state=42)
X_train, y_train = data["X_train"], data["y_train"]
X_test, y_test = data["X_test"], data["y_test"]
# Convert to NumPy arrays used by model API.
X_train = np.asarray(X_train, dtype=np.float32)
X_test = np.asarray(X_test, dtype=np.float32)
y_train = np.asarray(y_train)
y_test = np.asarray(y_test)
print("Train shape:", X_train.shape, y_train.shape)
print("Test shape:", X_test.shape, y_test.shape)
print("Classes:", np.unique(y_train))
Model creation and training
# Configure HQNC classifier for binary classes
model = HQNC(
in_features=X_train.shape[1],
n_qubits=X_train.shape[1],
depth=5,
n_classes=len(np.unique(y_train)),
layer_type="Basic",
variational_type="strong",
basis="Y",
lr=0.02,
optimizer="adam",
epochs=500,
batch_size=len(X_train),
random_state=42,
)
# Train model parameters
model.fit(X_train, y_train)
print("Training complete. Last epoch loss:", round(float(model.train_losses_[-1]), 6))
HQNC training | Epoch 1/500 | loss=0.697751 | elapsed=0.1s | eta=27.4s
HQNC training | Epoch 2/500 | loss=0.656395 | elapsed=0.1s | eta=18.8s
HQNC training | Epoch 3/500 | loss=0.626758 | elapsed=0.1s | eta=16.2s
...
HQNC training | Epoch 499/500 | loss=0.028733 | elapsed=22.2s | eta=0.0s
HQNC training | Epoch 500/500 | loss=0.028657 | elapsed=22.2s | eta=0.0s
Training complete. Last epoch loss: 0.028657
Evaluation
# Predict labels for the test subset
y_pred = model.predict(X_test)
# Compute summary classification metrics
acc = accuracy_score(y_test, y_pred)
macro_f1 = f1_score(y_test, y_pred, average="macro")
print(f"Accuracy: {acc:.4f}")
print(f"Macro F1: {macro_f1:.4f}")
print("Classification report:")
print(classification_report(y_test, y_pred, digits=4, zero_division=0))
Accuracy: 1.0000
Macro F1: 1.0000
Classification report:
precision recall f1-score support
0 1.0000 1.0000 1.0000 20
1 1.0000 1.0000 1.0000 20
accuracy 1.0000 40
macro avg 1.0000 1.0000 1.0000 40
weighted avg 1.0000 1.0000 1.0000 40
Plotting results
# Plot test predictions and training loss in one figure
from matplotlib.colors import ListedColormap
with matplotlib.rc_context(rc_params(theme="light")):
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
class_cmap = ListedColormap([STYLE_COLORS[0], STYLE_COLORS[3]])
axes[0].scatter(
X_test[:, 0], X_test[:, 1], c=y_pred, cmap=class_cmap, s=18, alpha=0.8
)
axes[0].set_title("HQNC predictions on circles (test set)")
axes[0].set_xlabel("x1")
axes[0].set_ylabel("x2")
axes[1].plot(model.train_losses_, color=STYLE_COLORS[0], label="train loss")
axes[1].set_xlabel("Epoch")
axes[1].set_ylabel("Cross-entropy loss")
axes[1].set_title("HQNC training curve on circles")
axes[1].legend()
plt.tight_layout()
plt.show()

Takeaway
An HQNC with 2 qubits and depth=5 separates the two circles exactly. The
accuracy and the macro F1 score are both 1.0000 on the test split of 40
samples, and the loss falls to 0.028657 over 500 epochs. Linear classifiers
cannot solve circles, so the result shows that the model can represent a curved
decision boundary. This holds on a small, clean and synthetic dataset.
Breast cancer applies the same estimator to a real
dataset.