This repository was archived by the owner on Mar 25, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathQCM_v2.py
More file actions
158 lines (125 loc) · 5.14 KB
/
Copy pathQCM_v2.py
File metadata and controls
158 lines (125 loc) · 5.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# Quantum Committee Machine (QCM) for Lottery Prediction
# Lottery prediction generated using an ensemble of diverse quantum circuit architectures
# Quantum Regression Model with Qiskit
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from qiskit import QuantumCircuit
from qiskit.circuit import ParameterVector
from qiskit.quantum_info import Statevector, SparsePauliOp
from scipy.optimize import minimize
from qiskit_machine_learning.utils import algorithm_globals
import random
# ================= SEED PARAMETERS =================
SEED = 39
random.seed(SEED)
np.random.seed(SEED)
algorithm_globals.random_seed = SEED
# ==================================================
# Use the existing dataframe
df_raw = pd.read_csv('/data/loto7hh_4586_k24.csv')
# 4568 historical draws of Lotto 7/39 (Serbia)
# v2: granice kao u sortiranoj kombinaciji (pozicija i -> min i+1, max 33+i)
_MIN_POS = np.array([1, 2, 3, 4, 5, 6, 7], dtype=int)
_MAX_POS = np.array([33, 34, 35, 36, 37, 38, 39], dtype=int)
def quantum_committee_predict(df):
df = df.copy()
cols = ['Num1', 'Num2', 'Num3', 'Num4', 'Num5', 'Num6', 'Num7']
predictions = {}
# Model Hyperparameters
num_qubits = 1
train_window = 20
num_members = 3 # Ensemble size (The Committee)
# Helper to train and predict for a single committee member
def get_member_prediction(m_id, X_train, y_train, X_next):
x_p = ParameterVector('x', 1)
t_p = ParameterVector('theta', 2)
qc = QuantumCircuit(num_qubits)
# Diversity: Each member has a different encoding/ansatz structure
if m_id == 0:
qc.ry(x_p[0], 0)
qc.rz(t_p[0], 0)
qc.ry(t_p[1], 0)
elif m_id == 1:
qc.rx(x_p[0], 0)
qc.ry(t_p[0], 0)
qc.rz(t_p[1], 0)
else:
qc.rz(x_p[0], 0)
qc.rx(t_p[0], 0)
qc.ry(t_p[1], 0)
observable = SparsePauliOp('Z')
def cost_fn(params):
mse = 0
for i in range(len(X_train)):
# Bind parameters to the circuit
bound_qc = qc.assign_parameters({x_p[0]: X_train[i][0], t_p[0]: params[0], t_p[1]: params[1]})
sv = Statevector.from_instruction(bound_qc)
# Calculate expectation value classically using the statevector
exp_val = sv.expectation_value(observable).real
mse += (exp_val - y_train[i]) ** 2
return mse / len(X_train)
# v2: više iteracija + najbolji od nekoliko slučajnih startova
best_x = None
best_cost = float("inf")
for _ in range(4):
x0 = np.random.uniform(0, 2 * np.pi, 2)
res = minimize(
cost_fn,
x0,
method='COBYLA',
options={'maxiter': 180, 'rhobeg': 0.3},
)
c = float(res.fun)
if c < best_cost:
best_cost = c
best_x = res.x
# Final prediction for the next step
bound_qc_final = qc.assign_parameters({x_p[0]: X_next[0][0], t_p[0]: best_x[0], t_p[1]: best_x[1]})
sv_final = Statevector.from_instruction(bound_qc_final)
return sv_final.expectation_value(observable).real
for idx, col in enumerate(cols):
# 1. Feature Engineering: 1 Lag
df[f'{col}_lag'] = df[col].shift(1)
df_model = df.dropna().tail(train_window + 1)
X = df_model[[f'{col}_lag']].values
y = df_model[col].values
# 2. Scaling
scaler_x = MinMaxScaler(feature_range=(0, np.pi))
scaler_y = MinMaxScaler(feature_range=(-1, 1))
X_scaled = scaler_x.fit_transform(X)
y_scaled = scaler_y.fit_transform(y.reshape(-1, 1)).flatten()
X_train, y_train = X_scaled[:-1], y_scaled[:-1]
X_next = X_scaled[-1:]
# 3. Collect votes from the Committee
member_results = []
for m_id in range(num_members):
member_results.append(get_member_prediction(m_id, X_train, y_train, X_next))
# 4. Aggregate: Simple Average of the Committee's predictions
# v2: medijana (robusnije od proseka na šumu)
avg_pred_scaled = float(np.median(member_results))
# Inverse scale back to lottery number range
pred_final = scaler_y.inverse_transform(np.array([[avg_pred_scaled]]))
lo, hi = int(_MIN_POS[idx]), int(_MAX_POS[idx])
predictions[col] = int(round(np.clip(pred_final[0][0], lo, hi)))
return predictions
print("Computing predictions using Quantum Committee Machine (QCM) ...")
q_qcm_results = quantum_committee_predict(df_raw)
# Format for display
q_qcm_df = pd.DataFrame([q_qcm_results])
# q_qcm_df.index = ['Quantum Committee Machine (QCM) Prediction']
print()
print("Lottery prediction generated using an ensemble of diverse quantum circuit architectures.")
print()
print()
print("Quantum Committee Machine (QCM) Results:")
print(q_qcm_df.to_string(index=True))
print()
"""
Quantum Committee Machine (QCM) Results:
Num1 Num2 Num3 Num4 Num5 Num6 Num7
0 11 x 19 y 25 z 36
"""
"""
(v2: agregacija glasova je medijana umesto proseka.)
"""