Skip to content

scikit-learn estimator

hqnn_forge.sklearn

hqnn_forge.sklearn

A scikit-learn estimator around the hybrid classifiers.

QuantumKernelClassifier is the quantum-kernel SVM (QSVM) as an estimator: the same bookkeeping around SVC(kernel="precomputed") that hqnn_forge.kernels otherwise leaves to the caller.

HybridClassifierEstimator implements fit / predict / predict_proba / get_params / set_params, so a hybrid model can be dropped into cross_val_score, GridSearchCV and Pipeline like any other classifier. Training is delegated to hqnn_forge.training.train_model.

scikit-learn (>= 1.6) is an optional dependency, declared by the sklearn extra; importing this module without it raises an ImportError saying how to install it.

Example

::

from sklearn.model_selection import cross_val_score
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from hqnn_forge.sklearn import HybridClassifierEstimator

clf = make_pipeline(
    StandardScaler(),
    HybridClassifierEstimator(n_qubits=4, n_layers=2, max_epochs=20),
)
scores = cross_val_score(clf, X, y, cv=5, scoring="matthews_corrcoef")

ModelName module-attribute

ModelName = Literal['serial', 'parallel']

LossName module-attribute

LossName = Literal['focal', 'bce']

StrategyName module-attribute

StrategyName = Literal['softmax', 'one_vs_rest']

CalibrationName module-attribute

CalibrationName = Literal['temperature', 'platt']

CALIBRATORS module-attribute

CALIBRATORS: dict[str, type[TemperatureScaler | PlattScaler]] = {'temperature': TemperatureScaler, 'platt': PlattScaler}

KernelEncoding module-attribute

KernelEncoding = Literal['angle', 'iqp', 'reuploading', 'amplitude']

HybridClassifierEstimator

Bases: ClassifierMixin, BaseEstimator

scikit-learn classifier training a hybrid quantum-classical model.

Binary or multiclass, decided by y in fit, like any scikit-learn classifier: two classes train a HybridBinaryClassifier (or the parallel model), three or more a MulticlassHybridClassifier with the same circuit options.

Parameters:

Name Type Description Default
model ModelName

"serial" (HybridBinaryClassifier) or "parallel" (ParallelHybridClassifier). With more than two classes only "serial" exists (MulticlassHybridClassifier); "parallel" raises in fit.

'serial'
n_qubits int
8
n_layers int
8
encoding_type int
8
init_strategy int
8
use_classical_encoder int
8
dropout_p float

Passed to the model constructor. n_input_features is taken from the data in fit.

0.0
device_name float

Passed to the model constructor. n_input_features is taken from the data in fit.

0.0
diff_method float

Passed to the model constructor. n_input_features is taken from the data in fit.

0.0
classical_hidden_dim int

MLP width; used by the parallel model only.

16
loss LossName

"focal" (FocalLoss(), the library default for imbalanced data) or "bce" (BCEWithLogitsLoss).

'focal'
lr float

Adam learning rate.

0.01
max_epochs int

Passed to train_model. Early stopping needs a validation split: with validation_fraction=0 the run always lasts max_epochs, whatever patience says. patience=None disables early stopping even when there is a split.

20
batch_size int

Passed to train_model. Early stopping needs a validation split: with validation_fraction=0 the run always lasts max_epochs, whatever patience says. patience=None disables early stopping even when there is a split.

20
patience int

Passed to train_model. Early stopping needs a validation split: with validation_fraction=0 the run always lasts max_epochs, whatever patience says. patience=None disables early stopping even when there is a split.

20
monitor int

Passed to train_model. Early stopping needs a validation split: with validation_fraction=0 the run always lasts max_epochs, whatever patience says. patience=None disables early stopping even when there is a split.

20
validation_fraction float

Share of the training data held out (stratified) for early stopping and threshold selection. 0 trains on everything.

0.0
strategy StrategyName

More than two classes only: "softmax" (default; trained with cross-entropy, or its focal version) or "one_vs_rest" (one binary head per class, trained with BCE, or the focal loss, on one-hot targets). See MulticlassHybridClassifier.

'softmax'
threshold float | Literal['optimal']

Binary only. "optimal" uses the validation-optimal threshold found by train_model; a float in [0, 1] fixes it. train_model searches a threshold for the metric monitors only, so "optimal" falls back to 0.5 both without a validation split and under monitor="val_loss".

'optimal'
calibration CalibrationName | None

Binary only. None (default): the model's own probabilities. "temperature" or "platt": a TemperatureScaler or PlattScaler fitted on the validation logits after training, which minimises the validation log loss, and applied in predict_proba. Focal loss, the default, trades calibration for focus on hard examples, so its probabilities can be under-confident. Needs validation_fraction > 0. A split with no finite fit (non-finite logits, logits that separate the classes or rank them no better than chance) warns and leaves the probabilities uncalibrated, calibrator_ being None. Both maps are increasing in the logit (Platt's whenever its slope is positive), so they change no ranking, and with threshold="optimal" predict keeps deciding on the uncalibrated probabilities: it returns exactly what it would uncalibrated, and threshold_ reports the threshold mapped through the same function. That holds under monitor="val_loss" too, where the threshold is the 0.5 fallback on the uncalibrated probabilities and threshold_ its image (σ(b) for Platt, 0.5 for a temperature). A Platt slope ≤ 0 (a model anti-correlated with the labels) reverses the order instead, and the threshold is then searched again on the calibrated validation probabilities (under monitor="val_loss", which searches none, 0.5 applies to them). A fixed threshold applies to the calibrated probabilities as given.

None
random_state int | None

Seeds weight initialisation, dropout, the validation split and batch order. The initial weights are the model's init_seed=random_state draws; dropout and batch order use seeds spawned from it, so they are independent of the init. A seeded fit is reproducible and leaves the global torch RNG exactly as it was; None draws everything from the global RNG. The draws of noise_method="trajectories" share the dropout stream, so a seeded noisy fit is reproducible too.

None
noise_level float

Noise-aware training, passed to the model: depolarizing noise of probability noise_level (in [0, 0.75]) applied to the circuit in train mode only, so fit trains through the noisy circuit and predict / predict_proba are noiseless. noise_position is "all" or "end"; noise_method is "density" (exact, practical up to about 6 qubits) or "trajectories" (sampled, at pure-state cost), with noise_trajectories draws per sample. Use 8 or more draws at noise of a few percent per gate: with fewer, some runs on the breast-cancer proxy had not started to train within 30 epochs (#347, #480). The defaults (no noise) train exactly as without these parameters. Like every other parameter they are validated in fit, so they can be tuned with GridSearchCV. See hqnn_forge.noise.

0.0
noise_position float

Noise-aware training, passed to the model: depolarizing noise of probability noise_level (in [0, 0.75]) applied to the circuit in train mode only, so fit trains through the noisy circuit and predict / predict_proba are noiseless. noise_position is "all" or "end"; noise_method is "density" (exact, practical up to about 6 qubits) or "trajectories" (sampled, at pure-state cost), with noise_trajectories draws per sample. Use 8 or more draws at noise of a few percent per gate: with fewer, some runs on the breast-cancer proxy had not started to train within 30 epochs (#347, #480). The defaults (no noise) train exactly as without these parameters. Like every other parameter they are validated in fit, so they can be tuned with GridSearchCV. See hqnn_forge.noise.

0.0
noise_method float

Noise-aware training, passed to the model: depolarizing noise of probability noise_level (in [0, 0.75]) applied to the circuit in train mode only, so fit trains through the noisy circuit and predict / predict_proba are noiseless. noise_position is "all" or "end"; noise_method is "density" (exact, practical up to about 6 qubits) or "trajectories" (sampled, at pure-state cost), with noise_trajectories draws per sample. Use 8 or more draws at noise of a few percent per gate: with fewer, some runs on the breast-cancer proxy had not started to train within 30 epochs (#347, #480). The defaults (no noise) train exactly as without these parameters. Like every other parameter they are validated in fit, so they can be tuned with GridSearchCV. See hqnn_forge.noise.

0.0
noise_trajectories float

Noise-aware training, passed to the model: depolarizing noise of probability noise_level (in [0, 0.75]) applied to the circuit in train mode only, so fit trains through the noisy circuit and predict / predict_proba are noiseless. noise_position is "all" or "end"; noise_method is "density" (exact, practical up to about 6 qubits) or "trajectories" (sampled, at pure-state cost), with noise_trajectories draws per sample. Use 8 or more draws at noise of a few percent per gate: with fewer, some runs on the breast-cancer proxy had not started to train within 30 epochs (#347, #480). The defaults (no noise) train exactly as without these parameters. Like every other parameter they are validated in fit, so they can be tuned with GridSearchCV. See hqnn_forge.noise.

0.0

Attributes:

Name Type Description
classes_ ndarray of shape (n_classes,)

The labels, sorted; with two, classes_[1] is the positive class.

n_features_in_ int
model_ Module

The trained model.

history_ TrainingHistory
threshold_ float or None

Decision threshold used by predict; None with more than two classes, where predict is the argmax. With threshold="optimal" and an increasing calibration it is the image of the uncalibrated threshold: predict compares the uncalibrated float32 probabilities with that one, and predict_proba(X)[:, 1] >= threshold_ gives the same labels with two exceptions. A logit whose float32 sigmoid rounds onto the threshold from below is positive for predict and negative there; that can happen at any threshold, over a wider stretch of logits as the sigmoid saturates. And the image itself rounds to exactly 1.0 (or 0.0) once the calibrated sigmoid saturates in float64, which a Platt slope above 1 or a temperature below 1 brings on well inside the float32 range; every probability saturated with it then compares equal to it, whichever side of the threshold its logit is.

calibrator_ (TemperatureScaler, PlattScaler or None)

The fitted calibration; None without calibration, or when the validation split had no finite fit.

model instance-attribute

model = model

n_qubits instance-attribute

n_qubits = n_qubits

n_layers instance-attribute

n_layers = n_layers

encoding_type instance-attribute

encoding_type = encoding_type

init_strategy instance-attribute

init_strategy = init_strategy

use_classical_encoder instance-attribute

use_classical_encoder = use_classical_encoder

classical_hidden_dim instance-attribute

classical_hidden_dim = classical_hidden_dim

dropout_p instance-attribute

dropout_p = dropout_p

device_name instance-attribute

device_name = device_name

diff_method instance-attribute

diff_method = diff_method

loss instance-attribute

loss = loss

lr instance-attribute

lr = lr

max_epochs instance-attribute

max_epochs = max_epochs

batch_size instance-attribute

batch_size = batch_size

validation_fraction instance-attribute

validation_fraction = validation_fraction

patience instance-attribute

patience = patience

monitor instance-attribute

monitor = monitor

threshold instance-attribute

threshold = threshold

calibration instance-attribute

calibration = calibration

random_state instance-attribute

random_state = random_state

noise_level instance-attribute

noise_level = noise_level

noise_position instance-attribute

noise_position = noise_position

noise_method instance-attribute

noise_method = noise_method

noise_trajectories instance-attribute

noise_trajectories = noise_trajectories

strategy instance-attribute

strategy = strategy

fit

fit(X: ArrayLike, y: ArrayLike) -> HybridClassifierEstimator

Build the model for X's width and train it on (X, y).

predict_proba

predict_proba(X: ArrayLike) -> npt.NDArray[np.float64]

Class probabilities, shape (n_samples, n_classes), columns in classes_ order.

predict

predict(X: ArrayLike) -> npt.NDArray[Any]

Labels from classes_: the positive probability thresholded at threshold_ for two classes, the argmax of the logits for more.

QuantumKernelClassifier

Bases: ClassifierMixin, BaseEstimator

Support vector classifier on a quantum fidelity kernel (QSVM).

fit builds an encoding layer for the width of X, optionally trains it by kernel-target alignment, computes the Gram matrix K[i, j] = |⟨Φ(x_i)|Φ(x_j)⟩|² with hqnn_forge.kernels.quantum_kernel_matrix and fits SVC(kernel="precomputed") on it. predict and friends compute the kernel between new samples and the training set -- rows new, columns training, the orientation SVC needs -- from the training states cached at fit, so only the new samples are simulated. So the estimator works in cross_val_score, GridSearchCV and Pipeline like any other.

Parameters:

Name Type Description Default
encoding KernelEncoding

"angle" (default), "iqp", "reuploading" or "amplitude".

'angle'
n_qubits int | None

Default: one qubit per feature, or max(2, ceil(log2(n_features))) for "amplitude" (whose features are zero-padded to 2**n_qubits). With one feature per qubit it must equal n_features.

None
n_layers int

Variational layers of the encoding layer. For the single-upload encoders the ansatz cancels in the fidelity kernel (see hqnn_forge.kernels); it matters for "reuploading", where the weights sit between uploads. Default: 2.

2
trainable_input_scaling bool

"reuploading" only: a trainable scale per upload. Default: False.

False
align_steps int

With align_steps > 0, train the layer by kernel-target alignment before fitting the SVM (hqnn_forge.kernels.train_kernel_alignment). Only for "reuploading" (the single-upload ansatz cancels in the kernel, so there is nothing to train), two classes and noise_level=0 (alignment trains the noiseless kernel). Default: 0.

0
align_lr int

With align_steps > 0, train the layer by kernel-target alignment before fitting the SVM (hqnn_forge.kernels.train_kernel_alignment). Only for "reuploading" (the single-upload ansatz cancels in the kernel, so there is nothing to train), two classes and noise_level=0 (alignment trains the noiseless kernel). Default: 0.

0
align_subset_size int

With align_steps > 0, train the layer by kernel-target alignment before fitting the SVM (hqnn_forge.kernels.train_kernel_alignment). Only for "reuploading" (the single-upload ansatz cancels in the kernel, so there is nothing to train), two classes and noise_level=0 (alignment trains the noiseless kernel). Default: 0.

0
noise_level float

Estimate the kernel under depolarising noise from density matrices; 0 (default) is the exact state-vector kernel.

0.0
noise_position float

Estimate the kernel under depolarising noise from density matrices; 0 (default) is the exact state-vector kernel.

0.0
C float

Passed to SVC.

1.0
class_weight float

Passed to SVC.

1.0
probability bool

Enable predict_proba: Platt (sigmoid) scaling of the SVM's decision values, fitted on out-of-fold predictions by CalibratedClassifierCV(..., ensemble=False), which splits the precomputed kernel by rows and columns. (SVC(probability=True), which did the same internally, is deprecated from scikit-learn 1.9.) predict and decision_function stay those of the plain SVM. Default: False.

False
batch_size int | None

Samples simulated at a time, to bound memory. Default: all.

None
random_state int | None

Seeds the layer's initialisation, the alignment subsets and SVC, from private streams: the caller's global torch RNG is left untouched.

None

Attributes:

Name Type Description
classes_ ndarray
n_features_in_ int
layer_ Module

The (possibly aligned) encoding layer.

svc_ SVC
calibrator_ CalibratedClassifierCV or None

The probability model, with probability=True.

alignment_history_ list of float

The alignment at each training step; empty without alignment.

encoding instance-attribute

encoding = encoding

n_qubits instance-attribute

n_qubits = n_qubits

n_layers instance-attribute

n_layers = n_layers

trainable_input_scaling instance-attribute

trainable_input_scaling = trainable_input_scaling

align_steps instance-attribute

align_steps = align_steps

align_lr instance-attribute

align_lr = align_lr

align_subset_size instance-attribute

align_subset_size = align_subset_size

noise_level instance-attribute

noise_level = noise_level

noise_position instance-attribute

noise_position = noise_position

C instance-attribute

C = C

class_weight instance-attribute

class_weight = class_weight

probability instance-attribute

probability = probability

batch_size instance-attribute

batch_size = batch_size

random_state instance-attribute

random_state = random_state

fit

fit(X: ArrayLike, y: ArrayLike) -> QuantumKernelClassifier

Build (and optionally align) the layer, then fit the SVM on the Gram matrix.

decision_function

decision_function(X: ArrayLike) -> npt.NDArray[np.float64]

SVC.decision_function on the kernel between X and the training set.

predict

predict(X: ArrayLike) -> npt.NDArray[Any]

Labels from classes_.

predict_proba

predict_proba(X: ArrayLike) -> npt.NDArray[np.float64]

Platt-scaled probabilities; only present with probability=True, as in SVC.