Our reality check on quantum machine learning covers the caveats: most QML speedup claims assume data already sitting conveniently in a quantum state, an assumption that rarely holds for real classical datasets. Quantum kernel methods sidestep part of that problem, because a kernel-based classifier only ever needs the result of a quantum computation, a similarity score between data points, not the full quantum state itself. This post builds one with Qiskit Machine Learning (version 0.9).
pip install qiskit-machine-learning
What a kernel does, classical or quantum
Support vector classifiers separate data by finding a boundary in feature space, and a kernel function is what defines the notion of "similarity" the classifier uses to compare data points, without ever explicitly constructing that feature space. Classical kernels (RBF, polynomial) compute similarity using ordinary vector math. A quantum kernel encodes each classical data point into a quantum state via a parameterized circuit, then defines similarity as how much two such states overlap, a quantity that's exponentially expensive to compute classically for a general quantum state but comes directly out of running a simple circuit on real qubits.
Encoding data with a feature map
from qiskit.circuit.library import zz_feature_map
feature_map = zz_feature_map(feature_dimension=2, reps=2, entanglement="linear")
The feature map is the circuit that turns a classical data vector into a quantum state, parameterized by the data itself. zz_feature_map uses ZZ-interaction gates between qubits, which is a common choice specifically because it's believed hard to simulate classically for enough qubits and repetitions, the same property that would need to hold for a genuine quantum advantage to show up in the kernel's expressiveness.
Building the quantum kernel
from qiskit.primitives import StatevectorSampler as Sampler
from qiskit_machine_learning.state_fidelities import ComputeUncompute
from qiskit_machine_learning.kernels import FidelityQuantumKernel
sampler = Sampler()
fidelity = ComputeUncompute(sampler=sampler)
kernel = FidelityQuantumKernel(fidelity=fidelity, feature_map=feature_map)
ComputeUncompute is the mechanism that measures overlap: it runs the feature map circuit for one data point, then the inverse of the feature map circuit for the other, and the probability of landing back in the all-zero state is the fidelity between the two encoded quantum states, exactly the similarity score the kernel needs. FidelityQuantumKernel wraps that computation into the standard kernel interface scikit-learn expects.
Plugging into a classifier two ways
Directly with scikit-learn's SVC, passing the kernel's evaluate method as a callable kernel:
from sklearn.svm import SVC
svc = SVC(kernel=kernel.evaluate)
svc.fit(train_features, train_labels)
score = svc.score(test_features, test_labels)
Or with QSVC, Qiskit Machine Learning's own wrapper that takes the kernel object directly without the callable indirection:
from qiskit_machine_learning.algorithms import QSVC
qsvc = QSVC(quantum_kernel=kernel)
qsvc.fit(train_features, train_labels)
qsvc_score = qsvc.score(test_features, test_labels)
Both produce the same underlying computation. QSVC is the more idiomatic choice inside Qiskit Machine Learning code, while the SVC(kernel=...) route is useful if you're integrating a quantum kernel into an existing scikit-learn pipeline that expects a standard estimator interface.
What made this work (and what didn't)
Qiskit's own tutorial demonstrates this on an "ad hoc" dataset specifically constructed so that a quantum kernel achieves separation a classical kernel struggles with, and both approaches above score 100% on it. That result is real, but it's worth reading correctly: the dataset was designed around the feature map's structure to showcase the technique, not sampled from a real-world problem. This is the same caution our QML reality check raises about the field generally. A quantum kernel's practical advantage on genuinely hard, real-world classification tasks, where you didn't get to choose the data generation process to match the feature map, remains an open, actively studied question rather than a settled one.
Where the cost lives
Every kernel evaluation between two data points costs one circuit execution (state preparation plus its inverse plus measurement), and a training set of size N needs on the order of N² such evaluations to build the full kernel matrix. That's the same quadratic scaling classical kernel methods have, but each individual evaluation now costs a quantum circuit execution rather than a vector dot product, which is why quantum kernel methods are currently practical for small datasets and toy problems rather than production-scale classification, the same NISQ-era constraint that shows up across most near-term QML approaches.
Try this next
- Swap
zz_feature_mapfor a different feature map (zFeatureMap, or a custom parameterized circuit) and compare classification accuracy on the same dataset, since the feature map choice is the real design decision that determines what the kernel separates well and what it doesn't. - Time the kernel matrix computation as you increase the training set size, and watch the quadratic-in-N cost show up directly in wall-clock time.
- Read our VQE with PennyLane guide for a different flavor of hybrid quantum-classical algorithm, one that trains circuit parameters directly rather than using a fixed circuit as a fixed kernel.