lazyqml 2.0.5__py2.py3-none-any.whl → 3.0.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lazyqml/Factories/Circuits/AmplitudeEmbedding.py +1 -1
- lazyqml/Factories/Circuits/HCzRx.py +1 -1
- lazyqml/Factories/Circuits/HardwareEfficient.py +1 -1
- lazyqml/Factories/Circuits/RxEmbedding.py +1 -1
- lazyqml/Factories/Circuits/RyEmbedding.py +1 -1
- lazyqml/Factories/Circuits/RzEmbedding.py +1 -1
- lazyqml/Factories/Circuits/TreeTensor.py +1 -1
- lazyqml/Factories/Circuits/TwoLocal.py +1 -1
- lazyqml/Factories/Circuits/ZzEmbedding.py +1 -1
- lazyqml/Factories/Circuits/fCircuits.py +10 -10
- lazyqml/Factories/Dispatchers/Dispatcher.py +264 -85
- lazyqml/Factories/Models/Hybrid.py +460 -0
- lazyqml/Factories/Models/QNNBag.py +6 -6
- lazyqml/Factories/Models/QNNTorch.py +8 -8
- lazyqml/Factories/Models/QSVM.py +3 -3
- lazyqml/Factories/Models/_QNNPennylane.py +4 -4
- lazyqml/Factories/Models/fModels.py +4 -4
- lazyqml/Factories/Preprocessing/Pca.py +2 -2
- lazyqml/Factories/Preprocessing/Sanitizer.py +2 -2
- lazyqml/Factories/Preprocessing/fPreprocessing.py +5 -24
- lazyqml/Global/globalEnums.py +3 -1
- lazyqml/Interfaces/iAnsatz.py +1 -1
- lazyqml/Utils/Utils.py +203 -84
- lazyqml/Utils/Validator.py +4 -7
- lazyqml/__init__.py +1 -1
- lazyqml/lazyqml.py +50 -48
- lazyqml-3.0.1.dist-info/LICENSE +21 -0
- {lazyqml-2.0.5.dist-info → lazyqml-3.0.1.dist-info}/METADATA +48 -35
- lazyqml-3.0.1.dist-info/RECORD +40 -0
- {lazyqml-2.0.5.dist-info → lazyqml-3.0.1.dist-info}/WHEEL +1 -1
- lazyqml/.lazyqmlP.py +0 -293
- lazyqml/.lazyqmlVote.py +0 -303
- lazyqml/Factories/Circuits/_Qkernel.py +0 -16
- lazyqml/Factories/Circuits/_Qnn.py +0 -17
- lazyqml/Factories/Dispatchers/DispatcherCV.py +0 -143
- lazyqml/Factories/Dispatchers/DispatcherNumba.py +0 -226
- lazyqml/Factories/Dispatchers/_Dispatcher.py +0 -188
- lazyqml/Factories/Dispatchers/_DispatcherMultiprocessing.py +0 -201
- lazyqml/Factories/Dispatchers/_QNNBagdispatcher.py +0 -2
- lazyqml/Factories/Dispatchers/_QNNdispatcher.py +0 -2
- lazyqml/Factories/Dispatchers/_QSVMdispatcher.py +0 -112
- lazyqml/Factories/Dispatchers/__Dispatcher.py +0 -193
- lazyqml/Factories/Preprocessing/_PcaAmp.py +0 -22
- lazyqml/Factories/Preprocessing/_PcaTree.py +0 -22
- lazyqml/Factories/Preprocessing/_PcaTreeAmp.py +0 -22
- lazyqml/Lanza copy.sh +0 -32
- lazyqml/Lanza.sh +0 -21
- lazyqml/mem.py +0 -85
- lazyqml-2.0.5.dist-info/RECORD +0 -56
- {lazyqml-2.0.5.dist-info → lazyqml-3.0.1.dist-info}/AUTHORS.rst +0 -0
- /lazyqml-2.0.5.dist-info/LICENSE → /lazyqml-3.0.1.dist-info/LICENSE copy +0 -0
- {lazyqml-2.0.5.dist-info → lazyqml-3.0.1.dist-info}/entry_points.txt +0 -0
- {lazyqml-2.0.5.dist-info → lazyqml-3.0.1.dist-info}/top_level.txt +0 -0
lazyqml/.lazyqmlVote.py
DELETED
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
import pandas as pd
|
|
3
|
-
import sys
|
|
4
|
-
from tabulate import tabulate
|
|
5
|
-
from pydantic import BaseModel, Field, model_validator, field_validator, ValidationError, conset
|
|
6
|
-
from pydantic.config import ConfigDict
|
|
7
|
-
from typing import List, Callable, Optional, Set
|
|
8
|
-
from typing_extensions import Annotated, Set
|
|
9
|
-
from Factories.Preprocessing.fPreprocessing import PreprocessingFactory
|
|
10
|
-
from Global.globalEnums import *
|
|
11
|
-
from Utils.Utils import *
|
|
12
|
-
from Utils.Validator import *
|
|
13
|
-
from Factories.Dispatchers.DispatcherCV import *
|
|
14
|
-
from Factories.Dispatchers.Dispatcher import *
|
|
15
|
-
from sklearn.impute import SimpleImputer
|
|
16
|
-
from ucimlrepo import fetch_ucirepo
|
|
17
|
-
from sklearn.preprocessing import LabelEncoder
|
|
18
|
-
|
|
19
|
-
class QuantumClassifier(BaseModel):
|
|
20
|
-
"""
|
|
21
|
-
This module helps in fitting to all the classification algorithms that are available in Scikit-learn
|
|
22
|
-
Parameters
|
|
23
|
-
----------
|
|
24
|
-
verbose : bool, optional (default=False)
|
|
25
|
-
Verbose True for showing every training message during the fit.
|
|
26
|
-
ignoreWarnings : bool, optional (default=True)
|
|
27
|
-
When set to True, the warning related to algorigms that are not able to run are ignored.
|
|
28
|
-
customMetric : function, optional (default=None)
|
|
29
|
-
When function is provided, models are evaluated based on the custom evaluation metric provided.
|
|
30
|
-
customImputerNum : function, optional (default=None)
|
|
31
|
-
When function is provided, models are imputed based on the custom numeric imputer provided.
|
|
32
|
-
customImputerCat : function, optional (default=None)
|
|
33
|
-
When function is provided, models are imputed based on the custom categorical imputer provided.
|
|
34
|
-
prediction : bool, optional (default=False)
|
|
35
|
-
When set to True, the predictions of all the models models are returned as a pandas dataframe.
|
|
36
|
-
classifiers : list of strings, optional (default=["all"])
|
|
37
|
-
When function is provided, trains the chosen classifier(s) ["all", "qsvm", "qnn", "qnnbag"].
|
|
38
|
-
embeddings : list of strings, optional (default=["all"])
|
|
39
|
-
When function is provided, trains the chosen embeddings(s) ["all", "amplitude_embedding", "ZZ_embedding", "rx_embedding", "rz_embedding", "ry_embedding"].
|
|
40
|
-
ansatzs : list of strings, optional (default=["all"])
|
|
41
|
-
When function is provided, trains the chosen ansatzs(s) ["all", "HPzRx", "tree_tensor", "two_local", "hardware_efficient"].
|
|
42
|
-
randomSate : int, optional (default=1234)
|
|
43
|
-
This integer is used as a seed for the repeatability of the experiments.
|
|
44
|
-
nqubits : int, optional (default=8)
|
|
45
|
-
This integer is used for defining the number of qubits of the quantum circuits that the models will use.
|
|
46
|
-
numLayers : int, optional (default=5)
|
|
47
|
-
The number of layers that the Quantum Neural Network (QNN) models will use, is set to 5 by default.
|
|
48
|
-
numPredictors : int, optional (default=10)
|
|
49
|
-
The number of different predictoras that the Quantum Neural Networks with Bagging (QNN_Bag) will use, is set to 10 by default.
|
|
50
|
-
learningRate : int, optional (default=0.01)
|
|
51
|
-
The parameter that will be used for the optimization process of all the Quantum Neural Networks (QNN) in the gradient descent, is set to 0.01 by default.
|
|
52
|
-
epochs : int, optional (default=100)
|
|
53
|
-
The number of complete passes that will be done over the dataset during the fitting of the models.
|
|
54
|
-
runs : int, optional (default=1)
|
|
55
|
-
The number of training runs that will be done with the Quantum Neural Network (QNN) models.
|
|
56
|
-
maxSamples : float, optiona (default=1.0)
|
|
57
|
-
A floating point number between 0 and 1.0 that indicates the percentage of the dataset that will be used for each Quantum Neural Network with Bagging (QNN_Bag).
|
|
58
|
-
|
|
59
|
-
Examples
|
|
60
|
-
--------
|
|
61
|
-
>>> from lazyqml.supervised import QuantumClassifier
|
|
62
|
-
>>> from sklearn.datasets import load_breast_cancer
|
|
63
|
-
>>> from sklearn.model_selection import train_test_split
|
|
64
|
-
>>> data = load_breast_cancer()
|
|
65
|
-
>>> X = data.data
|
|
66
|
-
>>> y= data.target
|
|
67
|
-
>>> X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=.5,random_state =123)
|
|
68
|
-
>>> clf = QuantumClassifier(verbose=0,ignore_warnings=True, customMetric=None)
|
|
69
|
-
>>> models,predictions = clf.fit(X_train, X_test, y_train, y_test)
|
|
70
|
-
>>> model_dictionary = clf.provide_models(X_train,X_test,y_train,y_test)
|
|
71
|
-
>>> models
|
|
72
|
-
| Model | Embedding | Ansatz | Accuracy | Balanced Accuracy | ROC AUC | F1 Score | Time taken |
|
|
73
|
-
|:------------|:--------------------|:-------------------|-----------:|--------------------:|----------:|-----------:|-------------:|
|
|
74
|
-
| qsvm | amplitude_embedding | ~ | 0.807018 | 0.782339 | 0.782339 | 0.802547 | 43.7487 |
|
|
75
|
-
| qnn | amplitude_embedding | hardware_efficient | 0.77193 | 0.743218 | 0.743218 | 0.765533 | 7.92101 |
|
|
76
|
-
| qnn | ry_embedding | hardware_efficient | 0.71345 | 0.689677 | 0.689677 | 0.709295 | 8.00107 |
|
|
77
|
-
.....................................................................................................................................
|
|
78
|
-
#####################################################################################################################################
|
|
79
|
-
.....................................................................................................................................
|
|
80
|
-
| qnn | ZZ_embedding | two_local | 0.461988 | 0.455954 | 0.455954 | 0.467481 | 2.13294 |
|
|
81
|
-
"""
|
|
82
|
-
model_config = ConfigDict(strict=True)
|
|
83
|
-
|
|
84
|
-
# nqubits: Annotated[int, Field(gt=0)] = 8
|
|
85
|
-
nqubits: Annotated[Set[int], Field(description="Set of qubits, each must be greater than 0")]
|
|
86
|
-
randomstate: int = 1234
|
|
87
|
-
predictions: bool = False
|
|
88
|
-
ignoreWarnings: bool = True
|
|
89
|
-
sequential: bool = False
|
|
90
|
-
numPredictors: Annotated[int, Field(gt=0)] = 10
|
|
91
|
-
numLayers: Annotated[int, Field(gt=0)] = 5
|
|
92
|
-
classifiers: Annotated[Set[Model], Field(min_items=1)] = {Model.ALL}
|
|
93
|
-
ansatzs: Annotated[Set[Ansatzs], Field(min_items=1)] = {Ansatzs.ALL}
|
|
94
|
-
embeddings: Annotated[Set[Embedding], Field(min_items=1)] = {Embedding.ALL}
|
|
95
|
-
backend: Backend = Backend.lightningQubit
|
|
96
|
-
features: Annotated[Set[float], Field(min_items=1)] = {0.3, 0.5, 0.8}
|
|
97
|
-
learningRate: Annotated[float, Field(gt=0)] = 0.01
|
|
98
|
-
epochs: Annotated[int, Field(gt=0)] = 100
|
|
99
|
-
shots: Annotated[int, Field(gt=0)] = 1
|
|
100
|
-
runs: Annotated[int, Field(gt=0)] = 1
|
|
101
|
-
batchSize: Annotated[int, Field(gt=0)] = 8
|
|
102
|
-
threshold: Annotated[int, Field(gt=0)] = 26
|
|
103
|
-
maxSamples: Annotated[float, Field(gt=0, le=1)] = 1.0
|
|
104
|
-
verbose: bool = False
|
|
105
|
-
customMetric: Optional[Callable] = None
|
|
106
|
-
customImputerNum: Optional[Any] = None
|
|
107
|
-
customImputerCat: Optional[Any] = None
|
|
108
|
-
batch: Optional[bool] = True
|
|
109
|
-
cores: Optional[int] = True
|
|
110
|
-
|
|
111
|
-
@field_validator('nqubits', mode='before')
|
|
112
|
-
def check_nqubits_positive(cls, value):
|
|
113
|
-
if not isinstance(value, set):
|
|
114
|
-
raise TypeError('nqubits must be a set of integers')
|
|
115
|
-
|
|
116
|
-
if any(v <= 0 for v in value):
|
|
117
|
-
raise ValueError('Each value in nqubits must be greater than 0')
|
|
118
|
-
|
|
119
|
-
return value
|
|
120
|
-
|
|
121
|
-
@field_validator('features')
|
|
122
|
-
def validate_features(cls, v):
|
|
123
|
-
if not all(0 < x <= 1 for x in v):
|
|
124
|
-
raise ValueError("All features must be greater than 0 and less than or equal to 1")
|
|
125
|
-
return v
|
|
126
|
-
|
|
127
|
-
@field_validator('customMetric')
|
|
128
|
-
def validate_custom_metric_field(cls, metric):
|
|
129
|
-
if metric is None:
|
|
130
|
-
return None # Allow None as a valid value
|
|
131
|
-
|
|
132
|
-
# Check the function signature
|
|
133
|
-
sig = inspect.signature(metric)
|
|
134
|
-
params = list(sig.parameters.values())
|
|
135
|
-
|
|
136
|
-
if len(params) < 2 or params[0].name != 'y_true' or params[1].name != 'y_pred':
|
|
137
|
-
raise ValueError(
|
|
138
|
-
f"Function {metric.__name__} does not have the required signature. "
|
|
139
|
-
f"Expected first two arguments to be 'y_true' and 'y_pred'."
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
# Test the function by passing dummy arguments
|
|
143
|
-
y_true = np.array([0, 1, 1, 0]) # Example ground truth labels
|
|
144
|
-
y_pred = np.array([0, 1, 0, 0]) # Example predicted labels
|
|
145
|
-
|
|
146
|
-
try:
|
|
147
|
-
result = metric(y_true, y_pred)
|
|
148
|
-
except Exception as e:
|
|
149
|
-
raise ValueError(f"Function {metric.__name__} raised an error during execution: {e}")
|
|
150
|
-
|
|
151
|
-
# Ensure the result is a scalar (int or float)
|
|
152
|
-
if not isinstance(result, (int, float)):
|
|
153
|
-
raise ValueError(
|
|
154
|
-
f"Function {metric.__name__} returned {result}, which is not a scalar value."
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
return metric
|
|
158
|
-
|
|
159
|
-
@field_validator('customImputerCat', 'customImputerNum')
|
|
160
|
-
def check_preprocessor_methods(cls, preprocessor):
|
|
161
|
-
# Check if preprocessor is an instance of a class
|
|
162
|
-
if not isinstance(preprocessor, object):
|
|
163
|
-
raise ValueError(
|
|
164
|
-
f"Expected an instance of a class, but got {type(preprocessor).__name__}."
|
|
165
|
-
)
|
|
166
|
-
|
|
167
|
-
# Ensure the object has 'fit' and 'transform' methods
|
|
168
|
-
if not (hasattr(preprocessor, 'fit') and hasattr(preprocessor, 'transform')):
|
|
169
|
-
raise ValueError(
|
|
170
|
-
f"Object {preprocessor.__class__.__name__} does not have required methods 'fit' and 'transform'."
|
|
171
|
-
)
|
|
172
|
-
|
|
173
|
-
# Optionally check if the object has 'fit_transform' method
|
|
174
|
-
if not hasattr(preprocessor, 'fit_transform'):
|
|
175
|
-
raise ValueError(
|
|
176
|
-
f"Object {preprocessor.__class__.__name__} does not have 'fit_transform' method."
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
# Create dummy data for testing the preprocessor methods
|
|
180
|
-
X_dummy = np.array([[1, 2], [3, 4], [5, 6]]) # Example dummy data
|
|
181
|
-
|
|
182
|
-
try:
|
|
183
|
-
# Ensure the object can fit on data
|
|
184
|
-
preprocessor.fit(X_dummy)
|
|
185
|
-
except Exception as e:
|
|
186
|
-
raise ValueError(f"Object {preprocessor.__class__.__name__} failed to fit: {e}")
|
|
187
|
-
|
|
188
|
-
try:
|
|
189
|
-
# Ensure the object can transform data
|
|
190
|
-
transformed = preprocessor.transform(X_dummy)
|
|
191
|
-
except Exception as e:
|
|
192
|
-
raise ValueError(f"Object {preprocessor.__class__.__name__} failed to transform: {e}")
|
|
193
|
-
|
|
194
|
-
# Check the type of the transformed result
|
|
195
|
-
if not isinstance(transformed, (np.ndarray, list)):
|
|
196
|
-
raise ValueError(
|
|
197
|
-
f"Object {preprocessor.__class__.__name__} returned {type(transformed)} from 'transform', expected np.ndarray or list."
|
|
198
|
-
)
|
|
199
|
-
|
|
200
|
-
return preprocessor
|
|
201
|
-
|
|
202
|
-
def fit(self, X_train, y_train, X_test, y_test,showTable=True):
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
printer.set_verbose(verbose=self.verbose)
|
|
206
|
-
# Validation model to ensure input parameters are DataFrames and sizes match
|
|
207
|
-
FitParamsValidator(
|
|
208
|
-
train_x=X_train,
|
|
209
|
-
train_y=y_train,
|
|
210
|
-
test_x=X_test,
|
|
211
|
-
test_y=y_test
|
|
212
|
-
)
|
|
213
|
-
printer.print("Validation successful, fitting the model...")
|
|
214
|
-
|
|
215
|
-
# Fix seed
|
|
216
|
-
fixSeed(self.randomstate)
|
|
217
|
-
d = Dispatcher(sequential=self.sequential,threshold=self.threshold)
|
|
218
|
-
d.dispatch(nqubits=self.nqubits,randomstate=self.randomstate,predictions=self.predictions,numPredictors=self.numPredictors,numLayers=self.numLayers,classifiers=self.classifiers,ansatzs=self.ansatzs,backend=self.backend,embeddings=self.embeddings,features=self.features,learningRate=self.learningRate,epochs=self.epochs,runs=self.runs,maxSamples=self.maxSamples,verbose=self.verbose,customMetric=self.customMetric,customImputerNum=self.customImputerNum,customImputerCat=self.customImputerCat, X_train=X_train,y_train=y_train, X_test=X_test, y_test=y_test,shots=self.shots,showTable=showTable,batch=self.batchSize,auto=self.batch)
|
|
219
|
-
|
|
220
|
-
def repeated_cross_validation(self, X, y, n_splits=10, n_repeats=5, showTable=True):
|
|
221
|
-
printer.set_verbose(verbose=self.verbose)
|
|
222
|
-
# Validation model to ensure input parameters are DataFrames and sizes match
|
|
223
|
-
FitParamsValidatorCV(
|
|
224
|
-
x=X,
|
|
225
|
-
y=y
|
|
226
|
-
)
|
|
227
|
-
printer.print("Validation successful, fitting the model...")
|
|
228
|
-
|
|
229
|
-
# Fix seed
|
|
230
|
-
fixSeed(self.randomstate)
|
|
231
|
-
d = DispatcherCV(sequential=self.sequential,threshold=self.threshold,repeats=n_repeats,folds=n_splits)
|
|
232
|
-
d.dispatch(nqubits=self.nqubits,randomstate=self.randomstate,predictions=self.predictions,numPredictors=self.numPredictors,numLayers=self.numLayers,classifiers=self.classifiers,ansatzs=self.ansatzs,backend=self.backend,embeddings=self.embeddings,features=self.features,learningRate=self.learningRate,epochs=self.epochs,runs=self.runs,maxSamples=self.maxSamples,verbose=self.verbose,customMetric=self.customMetric,customImputerNum=self.customImputerNum,customImputerCat=self.customImputerCat,X_train=X ,X_test=X,y_test=y,y_train=y,shots=self.shots,showTable=showTable,batch=self.batchSize,auto=self.batch,cores=self.cores)
|
|
233
|
-
|
|
234
|
-
def leave_one_out(self, X, y, showTable=True):
|
|
235
|
-
pass
|
|
236
|
-
|
|
237
|
-
if __name__ == '__main__':
|
|
238
|
-
Batch_auto = True
|
|
239
|
-
Sequential = sys.argv[1].lower() == 'true'
|
|
240
|
-
Node = sys.argv[2].lower()
|
|
241
|
-
qubits = int(sys.argv[3])
|
|
242
|
-
cores = int(sys.argv[4])
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
from sklearn.datasets import load_iris
|
|
246
|
-
|
|
247
|
-
dataset="vote"
|
|
248
|
-
|
|
249
|
-
# Fetch dataset
|
|
250
|
-
congressional_voting_records = fetch_ucirepo(id=105)
|
|
251
|
-
|
|
252
|
-
# Data (as pandas dataframes)
|
|
253
|
-
X = congressional_voting_records.data.features
|
|
254
|
-
y = congressional_voting_records.data.targets
|
|
255
|
-
|
|
256
|
-
# Mapping categorical values to numerical values
|
|
257
|
-
X_numerical = X.replace({'y': 1, 'n': 0, '?': float('NaN')})
|
|
258
|
-
|
|
259
|
-
# Option 1: Replace NaNs with a specific value (e.g., -1 or 0)
|
|
260
|
-
X_numerical_filled = X_numerical.fillna(-1)
|
|
261
|
-
|
|
262
|
-
# Or, if you prefer to replace NaN with the column mean, you can use:
|
|
263
|
-
X_numerical_filled_mean = X_numerical.apply(lambda col: col.fillna(col.mean()))
|
|
264
|
-
|
|
265
|
-
print(X_numerical_filled.head())
|
|
266
|
-
print(X_numerical_filled_mean.head())
|
|
267
|
-
|
|
268
|
-
# Handling target variable
|
|
269
|
-
y_numerical = y.replace({'republican': 1, 'democrat': 0})
|
|
270
|
-
|
|
271
|
-
print(y_numerical.head())
|
|
272
|
-
|
|
273
|
-
from sklearn.impute import SimpleImputer
|
|
274
|
-
|
|
275
|
-
# Imputer for replacing missing values with the mean of each column
|
|
276
|
-
imputer = SimpleImputer(strategy='mean')
|
|
277
|
-
X_imputed = pd.DataFrame(imputer.fit_transform(X_numerical), columns=X.columns)
|
|
278
|
-
|
|
279
|
-
print(X_imputed.head())
|
|
280
|
-
X = X_imputed
|
|
281
|
-
y = y_numerical
|
|
282
|
-
|
|
283
|
-
if Node == "slave1":
|
|
284
|
-
repeats = 4
|
|
285
|
-
embeddings = {Embedding.AMP}
|
|
286
|
-
elif Node == "slave2":
|
|
287
|
-
repeats = 4
|
|
288
|
-
embeddings = {Embedding.ZZ}
|
|
289
|
-
elif Node == "slave5":
|
|
290
|
-
repeats = 2
|
|
291
|
-
embeddings = {Embedding.ZZ}
|
|
292
|
-
elif Node == "slave4":
|
|
293
|
-
repeats = 2
|
|
294
|
-
embeddings = {Embedding.ZZ}
|
|
295
|
-
|
|
296
|
-
print(f"PARAMETERS\nEmbeddings: {embeddings}\tBatch Auto: {Batch_auto}\tSequential: {Sequential}\tNode: {Node}\tDataset: {dataset}\tQubits: {qubits}\t Folds\\Repeats: {(8,repeats)}\tCores: {cores}")
|
|
297
|
-
|
|
298
|
-
classifier = QuantumClassifier(nqubits={qubits},classifiers={Model.QSVM},embeddings=embeddings,features={1.0},verbose=True,sequential=Sequential,backend=Backend.lightningQubit,batch=Batch_auto,cores=cores)
|
|
299
|
-
|
|
300
|
-
start = time.time()
|
|
301
|
-
classifier.repeated_cross_validation(X,y,n_repeats=repeats,n_splits=8)
|
|
302
|
-
print(f"TOTAL TIME: {time.time()-start}s\t PARALLEL: {not Sequential}")
|
|
303
|
-
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
from lazyqml.Interfaces.iCircuit import Circuit
|
|
2
|
-
from lazyqml.Factories.Circuits.fCircuits import *
|
|
3
|
-
import pennylane as qml
|
|
4
|
-
|
|
5
|
-
class QkernelCircuit(Circuit):
|
|
6
|
-
def __init__(self, nqubits, embedding) -> None:
|
|
7
|
-
self.nqubits = nqubits
|
|
8
|
-
self.embedding = embedding
|
|
9
|
-
self.CircuitFactory = CircuitFactory()
|
|
10
|
-
|
|
11
|
-
def getCircuit(self):
|
|
12
|
-
def kernel_circ(a, b):
|
|
13
|
-
self.CircuitFactory.GetEmbeddingCircuit(self.embedding)(a, wires = range(self.nqubits))
|
|
14
|
-
qml.adjoint(self.CircuitFactory.GetEmbeddingCircuit(self.embedding))(b, wires = range(self.nqubits)))
|
|
15
|
-
|
|
16
|
-
return kernel_circ
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
from lazyqml.Interfaces.iCircuit import Circuit
|
|
2
|
-
from Circuits.fCircuits import *
|
|
3
|
-
|
|
4
|
-
class QnnCircuit(Circuit):
|
|
5
|
-
def __init__(self, nqubits, nlayers, embedding, ansatz) -> None:
|
|
6
|
-
self.nqubits = nqubits
|
|
7
|
-
self.nlayers = nlayers
|
|
8
|
-
self.embedding = embedding
|
|
9
|
-
self.ansatz = ansatz
|
|
10
|
-
|
|
11
|
-
def getCircuit(self):
|
|
12
|
-
def qnn_circ(a):
|
|
13
|
-
CircuitFactory.GetEmbeddingCircuit(self.embedding)(a, wires = range(self.nqubits))
|
|
14
|
-
CircuitFactory.GetAnsatzCircuit(self.ansatz)(self.nqubits, self.nlayers)
|
|
15
|
-
|
|
16
|
-
return qnn_circ
|
|
17
|
-
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
from lazyqml.Utils.Utils import *
|
|
2
|
-
import numpy as np
|
|
3
|
-
import pandas as pd
|
|
4
|
-
import math
|
|
5
|
-
from lazyqml.Factories.Models.fModels import *
|
|
6
|
-
from lazyqml.Factories.Preprocessing.fPreprocessing import *
|
|
7
|
-
from sklearn.metrics import f1_score, accuracy_score, balanced_accuracy_score
|
|
8
|
-
import time
|
|
9
|
-
from joblib import Parallel, delayed
|
|
10
|
-
from sklearn.model_selection import RepeatedKFold
|
|
11
|
-
|
|
12
|
-
class DispatcherCV:
|
|
13
|
-
def __init__(self, sequential=False, threshold=27, time=True, folds=10, repeats=5):
|
|
14
|
-
self.sequential = sequential
|
|
15
|
-
self.threshold = threshold
|
|
16
|
-
self.timeM = time
|
|
17
|
-
self.fold = folds
|
|
18
|
-
self.repeat = repeats
|
|
19
|
-
|
|
20
|
-
def execute_model(self, model_factory_params, X_train, y_train, X_test, y_test, predictions, customMetric):
|
|
21
|
-
model = ModelFactory().getModel(**model_factory_params)
|
|
22
|
-
preds = []
|
|
23
|
-
accuracy, b_accuracy, f1, custom = 0, 0, 0, 0
|
|
24
|
-
custom = None
|
|
25
|
-
|
|
26
|
-
start = time.time()
|
|
27
|
-
|
|
28
|
-
model.fit(X=X_train, y=y_train)
|
|
29
|
-
y_pred = model.predict(X=X_test)
|
|
30
|
-
|
|
31
|
-
accuracy += accuracy_score(y_test, y_pred, normalize=True)
|
|
32
|
-
b_accuracy += balanced_accuracy_score(y_test, y_pred)
|
|
33
|
-
f1 = f1_score(y_test, y_pred, average="weighted")
|
|
34
|
-
if customMetric is not None:
|
|
35
|
-
custom = customMetric(y_test, y_pred)
|
|
36
|
-
|
|
37
|
-
exeT = time.time() - start
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return model_factory_params['Nqubits'], model_factory_params['model'], model_factory_params['Embedding'], model_factory_params['Ansatz'], model_factory_params['Max_features'], exeT, accuracy, b_accuracy, f1, custom, preds
|
|
41
|
-
|
|
42
|
-
def dispatch(self, nqubits, randomstate, predictions, shots,
|
|
43
|
-
numPredictors, numLayers, classifiers, ansatzs, backend,
|
|
44
|
-
embeddings, features, learningRate, epochs, runs, batch,
|
|
45
|
-
maxSamples, verbose, customMetric, customImputerNum,
|
|
46
|
-
customImputerCat, X_train, y_train, X_test, y_test,
|
|
47
|
-
auto, cores,showTable=True):
|
|
48
|
-
t_pre= time.time()
|
|
49
|
-
combinations = create_combinationsCV(qubits=nqubits,
|
|
50
|
-
classifiers=classifiers,
|
|
51
|
-
embeddings=embeddings,
|
|
52
|
-
features=features,
|
|
53
|
-
ansatzs=ansatzs,
|
|
54
|
-
RepeatID=[i for i in range(self.repeat)],
|
|
55
|
-
FoldID=[i for i in range(self.fold)])
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
X_train = pd.DataFrame(X_train)
|
|
60
|
-
X_test = pd.DataFrame(X_test)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
# Calculate available memory and determine max parallel models
|
|
64
|
-
available_memory = calculate_free_memory()
|
|
65
|
-
quantum_memory = calculate_quantum_memory(num_qubits=max(nqubits))
|
|
66
|
-
max_models_parallel = min(int(available_memory // quantum_memory) if quantum_memory > 0 else float('inf'), psutil.cpu_count(logical=False))
|
|
67
|
-
|
|
68
|
-
for combination in combinations:
|
|
69
|
-
print(combination)
|
|
70
|
-
|
|
71
|
-
# Prepare all model executions
|
|
72
|
-
all_executions = []
|
|
73
|
-
for combination in combinations:
|
|
74
|
-
qubits, name, embedding, ansatz, feature, repeat, fold = combination
|
|
75
|
-
feature = feature if feature is not None else "~"
|
|
76
|
-
|
|
77
|
-
numClasses = len(np.unique(y_train))
|
|
78
|
-
# adjustedQubits = adjustQubits(nqubits=qubits, numClasses=numClasses)
|
|
79
|
-
adjustedQubits = qubits
|
|
80
|
-
# print(f"ADJUSTED QUBITS: {adjustedQubits}")
|
|
81
|
-
prepFactory = PreprocessingFactory(adjustedQubits)
|
|
82
|
-
sanitizer = prepFactory.GetSanitizer(customImputerCat, customImputerNum)
|
|
83
|
-
|
|
84
|
-
X_train = pd.DataFrame(sanitizer.fit_transform(X_train))
|
|
85
|
-
X_test = pd.DataFrame(sanitizer.transform(X_test))
|
|
86
|
-
|
|
87
|
-
model_factory_params = {
|
|
88
|
-
"Nqubits": adjustedQubits,
|
|
89
|
-
"model": name,
|
|
90
|
-
"Embedding": embedding,
|
|
91
|
-
"Ansatz": ansatz,
|
|
92
|
-
"N_class": numClasses,
|
|
93
|
-
"backend": backend,
|
|
94
|
-
"Shots": shots,
|
|
95
|
-
"seed": randomstate*repeat,
|
|
96
|
-
"Layers": numLayers,
|
|
97
|
-
"Max_samples": maxSamples,
|
|
98
|
-
"Max_features": feature,
|
|
99
|
-
"LearningRate": learningRate,
|
|
100
|
-
"BatchSize": batch,
|
|
101
|
-
"Epoch": epochs,
|
|
102
|
-
"numPredictors": numPredictors
|
|
103
|
-
}
|
|
104
|
-
# print(f"XTEST SHAPE: {X_test.shape}")
|
|
105
|
-
# print(f"YTEST SHAPE: {y_test.shape}")
|
|
106
|
-
# print(f"XTrain SHAPE: {X_train.shape}")
|
|
107
|
-
# print(f"YTrain SHAPE: {y_train.shape}")
|
|
108
|
-
preprocessing = prepFactory.GetPreprocessing(ansatz=ansatz, embedding=embedding)
|
|
109
|
-
X_train_processed = np.array(preprocessing.fit_transform(X_train, y=y_train))
|
|
110
|
-
X_test_processed = np.array(preprocessing.transform(X_test))
|
|
111
|
-
y_test = np.array(y_test)
|
|
112
|
-
y_train = np.array(y_train)
|
|
113
|
-
# print(f"XTEST PROCESSED SHAPE: {X_test_processed.shape}")
|
|
114
|
-
# print(f"XTrain PROCESSED SHAPE: {X_train_processed.shape}")
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
all_executions.append((model_factory_params, X_train_processed, y_train, X_test_processed, y_test, predictions, customMetric))
|
|
118
|
-
if self.timeM:
|
|
119
|
-
print(f"PREPROCESSING TIME: {time.time()-t_pre}")
|
|
120
|
-
# Execute all models in parallel
|
|
121
|
-
t_exe = time.time()
|
|
122
|
-
if self.sequential:
|
|
123
|
-
results = [self.execute_model(*execution_params) for execution_params in all_executions]
|
|
124
|
-
else:
|
|
125
|
-
if auto:
|
|
126
|
-
results = Parallel(n_jobs=cores, prefer='processes',batch_size='auto',verbose=10)(
|
|
127
|
-
delayed(self.execute_model)(*execution_params) for execution_params in all_executions
|
|
128
|
-
)
|
|
129
|
-
else:
|
|
130
|
-
results = Parallel(n_jobs=cores, prefer='processes',batch_size=1,verbose=10)(
|
|
131
|
-
delayed(self.execute_model)(*execution_params) for execution_params in all_executions
|
|
132
|
-
)
|
|
133
|
-
if self.timeM:
|
|
134
|
-
print(f"EXECUTING TIME: {time.time()-t_exe}")
|
|
135
|
-
# Process results
|
|
136
|
-
t_res = time.time()
|
|
137
|
-
scores = pd.DataFrame(results, columns=["Qubits","Model", "Embedding", "Ansatz", "Features", "Time taken", "Accuracy", "Balanced Accuracy", "F1 Score", "Custom Metric", "Predictions"])
|
|
138
|
-
if showTable:
|
|
139
|
-
print(scores.to_markdown())
|
|
140
|
-
|
|
141
|
-
if self.timeM:
|
|
142
|
-
print(f"RESULTS TIME: {time.time()-t_res}")
|
|
143
|
-
return scores
|