Source code for scikit_quri.qkrr.qkrr

# mypy: ignore-errors
from typing import List

import numpy as np
from numpy.typing import NDArray
from quri_parts.core.state import QuantumState, quantum_state
from scipy.stats import loguniform
from sklearn.kernel_ridge import KernelRidge
from sklearn.model_selection import RandomizedSearchCV


from scikit_quri.circuit import LearningCircuit
from scikit_quri.state.overlap_estimator import overlap_estimator


[docs]class QKRR: """class to solve regression problems with kernel ridge regressor with a quantum kernel""" def __init__(self, circuit: LearningCircuit, n_iteration=10) -> None: """ :param circuit: circuit to generate quantum feature """ self.krr = KernelRidge(kernel="precomputed") self.kernel_ridge_tuned = None self.circuit = circuit self.data_states: List[QuantumState] = [] self.n_qubit: int = circuit.n_qubits self.n_iteration = n_iteration
[docs] def run_circuit(self, x: NDArray[np.float64]): # ここにはparametrizeされたcircuitは入ってこないはず... circuit = self.circuit.bind_input_and_parameters(x, np.array([])) state = quantum_state(n_qubits=self.n_qubit, circuit=circuit) return state
[docs] def fit(self, x: NDArray[np.float64], y: NDArray[np.int_]) -> None: """ train the machine. :param x: training inputs :param y: training teacher values """ kar = np.zeros((len(x), len(x))) # Compute UΦx to get kernel of `x` and `y`. for i in range(len(x)): self.data_states.append(self.run_circuit(x[i])) self.estimator = overlap_estimator(self.data_states.copy()) for i in range(len(x)): for j in range(len(x)): kar[i][j] = self.estimator.estimate(i, j) self.krr.fit(kar, y) # hyperparameter tuning alpha_low = 1e-3 alpha_high = 1e2 n_iteration = 5 random_state = 0 param_distributions = { "alpha": loguniform( alpha_low, alpha_high ), # Hyperparameter in the cost function for the regularizaton # "kernel__length_scale": loguniform(1e-3, 1e3), # Hyperparameter of the Kernel (If we apply the Quantum Kernel, this must be ignored) # "kernel__periodicity": loguniform(1e0, 1e1), # For periodic Kernel } kernel_ridge_tuned = RandomizedSearchCV( self.krr, param_distributions=param_distributions, n_iter=n_iteration, random_state=random_state, ) kernel_ridge_tuned.fit(kar, y) print(kernel_ridge_tuned.best_params_) self.kernel_ridge_tuned = kernel_ridge_tuned
[docs] def predict(self, xs: NDArray[np.float64]) -> NDArray[np.float64]: """ predict y values for each of xs :param xs: inputs to make predictions :return: List[int], predicted values of y """ if self.kernel_ridge_tuned is None: raise ValueError("run fit() before predict") kar = np.zeros((len(xs), len(self.data_states))) new_status = [] for i in range(len(xs)): x_qc = self.run_circuit(xs[i]) new_status.append(x_qc) self.estimator.add_data(new_status) offset = len(self.data_states) for i in range(len(xs)): for j in range(len(self.data_states)): kar[i][j] = self.estimator.estimate(offset + i, j) pred: NDArray[np.float64] = self.kernel_ridge_tuned.predict(kar) return pred