lazyqml 2.0.4__py2.py3-none-any.whl → 3.0.0__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.
Files changed (53) hide show
  1. lazyqml/Factories/Circuits/AmplitudeEmbedding.py +1 -1
  2. lazyqml/Factories/Circuits/HCzRx.py +1 -1
  3. lazyqml/Factories/Circuits/HardwareEfficient.py +1 -1
  4. lazyqml/Factories/Circuits/RxEmbedding.py +1 -1
  5. lazyqml/Factories/Circuits/RyEmbedding.py +1 -1
  6. lazyqml/Factories/Circuits/RzEmbedding.py +1 -1
  7. lazyqml/Factories/Circuits/TreeTensor.py +1 -1
  8. lazyqml/Factories/Circuits/TwoLocal.py +1 -1
  9. lazyqml/Factories/Circuits/ZzEmbedding.py +1 -1
  10. lazyqml/Factories/Circuits/fCircuits.py +10 -10
  11. lazyqml/Factories/Dispatchers/Dispatcher.py +264 -85
  12. lazyqml/Factories/Models/Hybrid.py +460 -0
  13. lazyqml/Factories/Models/QNNBag.py +6 -6
  14. lazyqml/Factories/Models/QNNTorch.py +8 -8
  15. lazyqml/Factories/Models/QSVM.py +3 -3
  16. lazyqml/Factories/Models/_QNNPennylane.py +4 -4
  17. lazyqml/Factories/Models/fModels.py +4 -4
  18. lazyqml/Factories/Preprocessing/Pca.py +2 -2
  19. lazyqml/Factories/Preprocessing/Sanitizer.py +2 -2
  20. lazyqml/Factories/Preprocessing/fPreprocessing.py +5 -24
  21. lazyqml/Global/globalEnums.py +3 -1
  22. lazyqml/Interfaces/iAnsatz.py +1 -1
  23. lazyqml/Utils/Utils.py +203 -84
  24. lazyqml/Utils/Validator.py +4 -7
  25. lazyqml/__init__.py +1 -1
  26. lazyqml/lazyqml.py +54 -49
  27. lazyqml-3.0.0.dist-info/LICENSE +21 -0
  28. {lazyqml-2.0.4.dist-info → lazyqml-3.0.0.dist-info}/METADATA +48 -35
  29. lazyqml-3.0.0.dist-info/RECORD +40 -0
  30. {lazyqml-2.0.4.dist-info → lazyqml-3.0.0.dist-info}/WHEEL +1 -1
  31. lazyqml/.lazyqmlP.py +0 -293
  32. lazyqml/.lazyqmlVote.py +0 -303
  33. lazyqml/Factories/Circuits/_Qkernel.py +0 -16
  34. lazyqml/Factories/Circuits/_Qnn.py +0 -17
  35. lazyqml/Factories/Dispatchers/DispatcherCV.py +0 -143
  36. lazyqml/Factories/Dispatchers/DispatcherNumba.py +0 -226
  37. lazyqml/Factories/Dispatchers/_Dispatcher.py +0 -188
  38. lazyqml/Factories/Dispatchers/_DispatcherMultiprocessing.py +0 -201
  39. lazyqml/Factories/Dispatchers/_QNNBagdispatcher.py +0 -2
  40. lazyqml/Factories/Dispatchers/_QNNdispatcher.py +0 -2
  41. lazyqml/Factories/Dispatchers/_QSVMdispatcher.py +0 -112
  42. lazyqml/Factories/Dispatchers/__Dispatcher.py +0 -193
  43. lazyqml/Factories/Preprocessing/_PcaAmp.py +0 -22
  44. lazyqml/Factories/Preprocessing/_PcaTree.py +0 -22
  45. lazyqml/Factories/Preprocessing/_PcaTreeAmp.py +0 -22
  46. lazyqml/Lanza copy.sh +0 -32
  47. lazyqml/Lanza.sh +0 -21
  48. lazyqml/mem.py +0 -85
  49. lazyqml-2.0.4.dist-info/RECORD +0 -56
  50. {lazyqml-2.0.4.dist-info → lazyqml-3.0.0.dist-info}/AUTHORS.rst +0 -0
  51. /lazyqml-2.0.4.dist-info/LICENSE → /lazyqml-3.0.0.dist-info/LICENSE copy +0 -0
  52. {lazyqml-2.0.4.dist-info → lazyqml-3.0.0.dist-info}/entry_points.txt +0 -0
  53. {lazyqml-2.0.4.dist-info → lazyqml-3.0.0.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