تصنيف هجين معزَّز كميًّا بالتعلم التجميعي (سير عمل استقرار الشبكة الكهربائية)
تقدير الاستخدام: 20 دقيقة من وقت وحدة المعالجة الكمية لكل مهمة على معالج Eagle r3. (ملاحظة: هذا تقدير فحسب. قد يختلف وقت التشغيل الفعلي.)
الخلفية النظرية
يوضح هذا البرنامج التعليمي سير عملًا هجينًا كميًّا-كلاسيكيًّا يُعزِّز تجميعًا كلاسيكيًّا بخطوة تحسين كمية. باستخدام وظيفة "Singularity Machine Learning – Classification" من Multiverse Computing (وهي دالة Qiskit)، نُدرِّب مجموعة من المتعلمين التقليديين (على سبيل المثال، أشجار القرار، وخوارزمية k-NN، والانحدار اللوجستي)، ثم نُنقِّح هذه المجموعة بطبقة كمية لتحسين التنوع والتعميم. الهدف عملي: في مهمة تنبؤ حقيقية باستقرار الشبكة الكهربائية، نقارن خطًّا أساسيًّا كلاسيكيًّا قويًّا مع بديل مُحسَّن كميًّا وفق تقسيمات البيانات ذاتها، حتى تتمكن من رؤية الحالات التي تُسهم فيها الخطوة الكمية إيجابًا وتكلفتها.
سبب أهمية ذلك: اختيار مجموعة فرعية جيدة من كثير من المتعلمين الضعفاء هو مسألة تحسين تركيبية تنمو بسرعة مع حجم التجميع. تؤدي الأساليب الاستدلالية الكلاسيكية كالتعزيز والتجميع والتكديس أداءً جيدًا عند المقاييس المتوسطة، لكنها قد تُعاني في استكشاف مكتبات ضخمة ومتكررة من النماذج باستكفاء. تدمج الدالة الخوارزميات الكمية - تحديدًا QAOA (واختياريًّا VQE في تكوينات أخرى) - للبحث في ذلك الفضاء بصورة أكثر فاعلية بعد تدريب المتعلمين الكلاسيكيين، مما يزيد من احتمالية إيجاد مجموعة فرعية مدمجة ومتنوعة تُعمِّم بشكل أفضل.
من الناحية الجوهرية، لا يتقيد حجم البيانات بعدد القيوت. يظل الجزء الثقيل المتعلق بالبيانات - المعالجة المسبقة وتدريب مجموعة المتعلمين والتقييم - كلاسيكيًّا وقادرًا على معالجة الملايين من الأمثلة. تحدد القيوت فقط حجم التجميع المستخدم في خطوة الاختيار الكمية. هذا الفصل هو ما يجعل النهج قابلًا للتطبيق على الأجهزة الحالية: تحتفظ بسير عمل scikit-learn المعتادة للبيانات وتدريب النماذج بينما تستدعي الخطوة الكمية عبر واجهة action نظيفة في Qiskit Functions.
في التطبيق العملي، بينما يمكن تزويد التجميع بأنواع مختلفة من المتعلمين (مثل أشجار القرار، والانحدار اللوجستي، أو k-NN)، تميل أشجار القرار إلى الأداء الأفضل. يُفضِّل المحسِّن باستمرار أعضاء التجميع الأقوى - فعند تزويده بمتعلمين غير متجانسين، تُقلَّم النماذج الأضعف كالمنحدرات الخطية لصالح النماذج الأكثر تعبيرًا مثل أشجار القرار.
ما ستفعله هنا: تجهيز مجموعة بيانات استقرار الشبكة الكهربائية وموازنتها؛ وضع خط أساسي كلاسيكي باستخدام AdaBoost؛ تشغيل عدة تكوينات كمية تتباين في عرض التجميع والتنظيم؛ التنفيذ على المحاكيات أو وحدات المعالجة الكمية من IBM® عبر Qiskit Serverless؛ ومقارنة الدقة والضبط والاستدعاء و F1 عبر جميع التشغيلات. على طول الطريق، ستستخدم نمط action الخاص بالدالة (create وfit وpredict وfit_predict وcreate_fit_predict) والضوابط الرئيسية:
- أنواع التنظيم:
onsite(λ) للتشتيت المباشر وalphaللمقايضة النسبية بين حدَّي التفاعل والموقع - التنظيم التلقائي: اضبط
regularization="auto"مع نسبة اختيار مستهدفة لضبط التشتيت تلقائيًّا - خيارات المحسِّن: المحاكي مقابل وحدة المعالجة الكمية، والتكرارات، والمحسِّن الكلاسيكي وخياراته، وعمق النقل، وإعدادات sampler/estimator لبيئة التشغيل
تُظهر المعايير المرجعية في الوثائق أن الدقة تتحسن مع زيادة عدد المتعلمين (القيوت) في المسائل الصعبة، إذ يُضاهي المصنِّف الكمي أو يتجاوز التجميع الكلاسيكي المقارن. في هذا البرنامج التعليمي، ستُعيد إنتاج سير العمل من البداية إلى النهاية وتفحص متى يُعطي زيادة عرض التجميع أو التبديل إلى التنظيم التكيفي قيمة F1 أفضل مع استخدام معقول للموارد. والنتيجة هي رؤية راسخة لكيفية تكامل خطوة التحسين الكمية مع التعلم التجميعي الكلاسيكي في التطبيقات الحقيقية بدلًا من إحلالها محله.
المتطلبات
قبل البدء بهذا البرنامج التعليمي، تأكد من تثبيت الحزم التالية في بيئة Python الخاصة بك:
qiskit[visualization]~=2.1.0qiskit-serverless~=0.24.0qiskit-ibm-runtime v0.40.1qiskit-ibm-catalog~=0.8.0scikit-learn==1.5.2pandas>=2.0.0,<3.0.0imbalanced-learn~=0.12.3
الإعداد
في هذا القسم، نُهيِّئ عميل Qiskit Serverless ونُحمِّل دالة Singularity Machine Learning – Classification المقدَّمة من Multiverse Computing. مع Qiskit Serverless، يمكنك تشغيل سير عمل هجينة كمية-كلاسيكية على البنية التحتية السحابية المُدارة من IBM دون القلق بشأن إدارة الموارد. ستحتاج إلى مفتاح API لمنصة IBM Quantum واسم موردك السحابي (CRN) للمصادقة والوصول إلى Qiskit Functions.
تنزيل مجموعة البيانات
لتشغيل هذا البرنامج التعليمي، نستخدم مجموعة بيانات تصنيف استقرار الشبكة الكهربائية المُعالَجة مسبقًا والتي تحتوي على قراءات مستشعرات نظام الطاقة الموسومة.
تُنشئ الخلية التالية تلقائيًّا بنية المجلدات المطلوبة وتُنزِّل ملفَّي التدريب والاختبار مباشرةً في بيئتك باستخدام wget.
إذا كانت هذه الملفات متاحة لديك محليًّا، فستقوم هذه الخطوة بالكتابة فوقها بأمان لضمان اتساق الإصدارات.
# Added by doQumentation — installs packages not in the Binder environment
%pip install -q imbalanced-learn scikit-learn
## Download dataset for Grid Stability Classification
# Create data directory if it doesn't exist
!mkdir -p data_tutorial/grid_stability
# Download the training and test sets from the official Qiskit documentation repo
!wget -q --show-progress -O data_tutorial/grid_stability/train.csv \
https://raw.githubusercontent.com/Qiskit/documentation/main/datasets/tutorials/grid_stability/train.csv
!wget -q --show-progress -O data_tutorial/grid_stability/test.csv \
https://raw.githubusercontent.com/Qiskit/documentation/main/datasets/tutorials/grid_stability/test.csv
# Check the files have been downloaded
!echo "Dataset files downloaded:"
!ls -lh data_tutorial/grid_stability/*.csv
data_tutorial/grid_ 100%[===================>] 612.94K --.-KB/s in 0.01s
data_tutorial/grid_ 100%[===================>] 108.19K --.-KB/s in 0.006s
Dataset files downloaded:
-rw-r--r-- 1 coder coder 109K Nov 8 18:50 data_tutorial/grid_stability/test.csv
-rw-r--r-- 1 coder coder 613K Nov 8 18:50 data_tutorial/grid_stability/train.csv
استيراد الحزم المطلوبة
في هذا القسم، نستورد جميع حزم Python ووحدات Qiskit المستخدمة طوال البرنامج التعليمي.
تشمل هذه الحزم المكتبات العلمية الأساسية لمعالجة البيانات وتقييم النماذج - مثل NumPy وpandas وscikit-learn - إل ى جانب أدوات التصوير ومكونات Qiskit لتشغيل النموذج المعزَّز كميًّا.
نستورد أيضًا QiskitRuntimeService وQiskitFunctionsCatalog للاتصال بخدمات IBM Quantum® والوصول إلى دالة Singularity Machine Learning.
from typing import Tuple
import warnings
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from imblearn.over_sampling import RandomOverSampler
from qiskit_ibm_catalog import QiskitFunctionsCatalog
from qiskit_ibm_runtime import QiskitRuntimeService
from sklearn.ensemble import AdaBoostClassifier
from sklearn.metrics import (
accuracy_score,
f1_score,
precision_score,
recall_score,
)
from sklearn.model_selection import train_test_split
warnings.filterwarnings("ignore")
تعيين المتغيرات الثابتة
IBM_TOKEN = ""
IBM_INSTANCE_TEST = ""
IBM_INSTANCE_QUANTUM = ""
FUNCTION_NAME = "multiverse/singularity"
RANDOM_STATE: int = 123
TRAIN_PATH = "data_tutorial/grid_stability/train.csv"
TEST_PATH = "data_tutorial/grid_stability/test.csv"
الاتصال بـ IBM Quantum وتحميل دالة Singularity
بعد ذلك، نُجري المصادقة مع خدمات IBM Quantum ونُحمِّل دالة Singularity Machine Learning – Classification من Qiskit Functions Catalog.
تُنشئ QiskitRuntimeService اتصالًا آمنًا بمنصة IBM Quantum باستخدام رمز API الخاص بك ومعرِّف CRN، مما يتيح الوصول إلى الواجهات الخلفية الكمية.
يُستخدَم QiskitFunctionsCatalog بعد ذلك لاسترداد دالة Singularity بالاسم ("multiverse/singularity")، مما يُمكِّننا من استدعائها لاحقًا للحوسبة الهجينة الكمية-الكلاسيكية.
إذا نجح الإعداد، ستظهر رسالة تأكيد تُشير إلى تحميل الدالة بصورة صحيحة.
service = QiskitRuntimeService(
token=IBM_TOKEN,
channel="ibm_quantum_platform",
instance=IBM_INSTANCE_QUANTUM,
)
backend = service.least_busy()
catalog = QiskitFunctionsCatalog(
token=IBM_TOKEN,
instance=IBM_INSTANCE_TEST,
channel="ibm_quantum_platform",
)
singularity = catalog.load(FUNCTION_NAME)
print(
"Successfully connected to IBM Qiskit Serverless and loaded the Singularity function."
)
print("Catalog:", catalog)
print("Singularity function:", singularity)
Successfully connected to IBM Qiskit Serverless and loaded the Singularity function.
Catalog: <QiskitFunctionsCatalog>
Singularity function: QiskitFunction(multiverse/singularity)
تعريف الدوال المساعدة
قبل تشغيل التجارب الرئيسية، نُعرِّف عددًا قليلًا من الدوال المساعدة الصغيرة التي تُبسِّط تحميل البيانات وتقييم النماذج.
- تقرأ
load_data()ملفات CSV المدخلة إلى مصفوفات NumPy، مُفصِلةً بين السمات والتسميات لتوافقها معscikit-learnوسير العمل الكمية. - تحسب
evaluate_predictions()مقاييس الأداء الرئيسية - الدقة الكلية والضبط والاستدعاء ودرجة F1 - وتُبلِّغ اختياريًّا عن وقت التشغيل إذا توفرت معلومات التوقيت.
تُبسِّط هذه الدوال المساعدة العمليات المتكررة لاحقًا في كراسة الملاحظات وتضمن تقارير متسقة للمقاييس عبر المصنِّفات الكلاسيكية والكمية على حدٍّ سواء.
def load_data(data_path: str) -> Tuple[np.ndarray, np.ndarray]:
"""Load data from the given path to X and y arrays."""
df: pd.DataFrame = pd.read_csv(data_path)
return df.iloc[:, :-1].values, df.iloc[:, -1].values
def evaluate_predictions(predictions, y_true):
"""Compute and print accuracy, precision, recall, and F1 score."""
accuracy = accuracy_score(y_true, predictions)
precision = precision_score(y_true, predictions)
recall = recall_score(y_true, predictions)
f1 = f1_score(y_true, predictions)
print("Accuracy:", accuracy)
print("Precision:", precision)
print("Recall:", recall)
print("F1:", f1)
return accuracy, precision, recall, f1
الخطوة 1: تعيين المدخلات الكلاسيكية إلى مسألة كمية
نبدأ بتجهيز مجموعة البيانات للتجريب الهجين الكمي-الكلاسيكي. يهدف هذا القسم إلى تحويل بيانات استقرار الشبكة الكهربائية الخام إلى تقسيمات متوازنة للتدريب والتحقق والاختبار يمكن استخدامها باتساق في سير العمل الكلاسيكية والكمية. يضمن الحفاظ على تقسيمات متطابقة أن مقارنات الأداء اللاحقة عادلة وقابلة للاستنساخ.
تحميل البيانات والمعالجة المسبقة
نُحمِّل أولًا ملفات CSV للتدريب والاختبار، وننشئ تقسيم تحقق، ونُوازن مجموعة البيانات باستخدام أخذ عينات زائدة عشوائية. تمنع الموازنة التحيز نحو الفئة الأغلب وتوفر إشارة تعلُّم أكثر استقرارًا لكلٍّ من النماذج التجميعية الكلاسيكية والكمية.
# Load and upload the data
X_train, y_train = load_data(TRAIN_PATH)
X_test, y_test = load_data(TEST_PATH)
X_train, X_val, y_train, y_val = train_test_split(
X_train, y_train, test_size=0.2, random_state=RANDOM_STATE
)
# Balance the dataset through over-sampling of the positive class
ros = RandomOverSampler(random_state=RANDOM_STATE)
X_train_bal, y_train_bal = ros.fit_resample(X_train, y_train)
print("Shapes:")
print(" X_train_bal:", X_train_bal.shape)
print(" y_train_bal:", y_train_bal.shape)
print(" X_val:", X_val.shape)
print(" y_val:", y_val.shape)
print(" X_test:", X_test.shape)
print(" y_test:", y_test.shape)
Shapes:
X_train_bal: (5104, 12)
y_train_bal: (5104,)
X_val: (850, 12)
y_val: (850,)
X_test: (750, 12)
y_test: (750,)
الخط الأساسي الكلاسيكي: مرجع AdaBoost
قبل تشغيل أي تحسين كمي، ندرِّب خطًّا أساسيًّا كلاسيكيًّا قويًّا - مصنِّف AdaBoost قياسي - على البيانات المتوازنة ذاتها. يوفر ذلك نقطة مرجعية قابلة للاستنساخ للمقارنة لاحقًا، مما يساعد على قياس ما إذا كان التحسين الكمي يُحسِّن التعميم أو الكفاءة بما يتجاوز التجميع الكلاسيكي المضبوط جيدًا.
# ----- Classical baseline: AdaBoost -----
baseline = AdaBoostClassifier(n_estimators=60, random_state=RANDOM_STATE)
baseline.fit(X_train_bal, y_train_bal)
baseline_pred = baseline.predict(X_test)
print("Classical AdaBoost baseline:")
_ = evaluate_predictions(baseline_pred, y_test)
Classical AdaBoost baseline:
Accuracy: 0.7893333333333333
Precision: 1.0
Recall: 0.7893333333333333
F1: 0.8822652757078987
الخطوة 2: تحسين المسألة لتنفيذها على الأجهزة الكمية
تُصاغ مهمة اختيار التجميع كمسألة تحسين تركيبية حيث يُمثِّل كل متعلِّم ضعيف مت غيرًا ثنائيًّا للقرار، ويُوازن الهدف بين الدقة والتشتيت من خلال حد تنظيمي. يحلّ QuantumEnhancedEnsembleClassifier هذه المسألة باستخدام QAOA على أجهزة IBM، مع السماح أيضًا باستكشاف قائم على المحاكي. تتحكم optimizer_options في الحلقة الهجينة: يُوجِّه simulator=False الدوائر إلى وحدة المعالجة الكمية المختارة، بينما يُوسِّع num_solutions نطاق البحث، وتتحكم classical_optimizer_options (للمحسِّن الكلاسيكي الداخلي) في التقارب؛ تُعدُّ القيم حول 60 تكرارًا توازنًا جيدًا بين الجودة ووقت التشغيل. تُساعد خيارات بيئة التشغيل - كعمق دائرة معتدل (reps) وجهد نقل قياسي - على ضمان أداء قوي عبر الأجهزة المختلفة. التكوين أدناه هو ملف تعريف "أفضل النتائج" الذي سنستخدمه في تشغيلات الأجهزة؛ يمكنك أيضًا إنشاء نسخة محاكاة بحتة عن طريق تبديل simulator=True للتشغيل الجاف للسير دون استهلاك وقت وحدة المعالجة الكمية.
# QAOA / runtime configuration for best results on hardware
optimizer_options = {
"simulator": False, # set True to test locally without QPU
"num_solutions": 100_000, # broaden search over candidate ensembles
"reps": 3, # QAOA depth (circuit layers)
"optimization_level": 3, # transpilation effort
"num_transpiler_runs": 30, # explore multiple layouts
"classical_optimizer": "COBYLA", # robust default for this landscape
"classical_optimizer_options": {
"maxiter": 60 # practical convergence budget
},
# You can pass backend-specific options; leaving None uses least-busy routing
"estimator_options": None,
"sampler_options": None,
}
print("Configured hardware optimization profile:")
for key, value in optimizer_options.items():
print(f" {key}: {value}")
Configured hardware optimization profile:
simulator: False
num_solutions: 100000
reps: 3
optimization_level: 3
num_transpiler_runs: 30
classical_optimizer: COBYLA
classical_optimizer_options: {'maxiter': 60}
estimator_options: None
sampler_options: None