Skip to main content
IBM Quantum Platform

Classificação híbrida de conjuntos aprimorada por quantum (fluxo de trabalho de estabilidade da rede)

Estimativa de uso: 20 minutos em tempo de QPU para cada trabalho em um processador Eagle r3. (OBSERVAÇÃO: essa é apenas uma estimativa. Seu tempo de execução pode variar)


Segundo plano

Este tutorial demonstra um fluxo de trabalho híbrido quântico-clássico que aprimora um conjunto clássico por meio de uma etapa de otimização quântica. Utilizando o “ Machine Learning o de Singularidade – Classificação” da Multiverse Computing (uma função do Qiskit), treinamos um conjunto de modelos de aprendizado convencionais (por exemplo, árvores de decisão, k-NN, regressão logística) e, em seguida, refinamos esse conjunto com uma camada quântica para melhorar a diversidade e a generalização. O objetivo é prático: em uma tarefa real de previsão de estabilidade da rede, comparamos uma linha de base clássica robusta com uma alternativa otimizada quântica, utilizando as mesmas divisões de dados, para que você possa ver em que aspectos a abordagem quântica ajuda e quais são os custos envolvidos.

Por que isso é importante: selecionar um bom subconjunto de muitos alunos fracos é um problema combinatório que cresce rapidamente com o tamanho do conjunto. As heurísticas clássicas, como boosting, bagging e stacking, têm bom desempenho em escalas moderadas, mas podem ter dificuldades para explorar com eficiência bibliotecas grandes e redundantes de modelos. A função integra algoritmos quânticos - especificamente QAOA (e opcionalmente VQE em outras configurações) - para pesquisar esse espaço com mais eficiência depois que os alunos clássicos são treinados, aumentando a chance de encontrar um subconjunto compacto e diversificado que generalize melhor.

Crucialmente, a escala de dados não é limitada por qubits. O trabalho pesado com os dados - pré-processamento, treinamento do pool de alunos e avaliação - continua sendo clássico e pode lidar com milhões de exemplos. Os Qubits determinam apenas o tamanho do conjunto usado na etapa de seleção quântica. Esse desacoplamento é o que torna a abordagem viável no hardware atual: você mantém os fluxos de trabalho familiares do scikit-learn para treinamento de dados e modelos e chama a etapa quântica por meio de uma interface de ação limpa em Qiskit Functions.

Na prática, embora diferentes tipos de alunos possam ser fornecidos ao conjunto (por exemplo, árvores de decisão, regressão logística ou k-NN), as árvores de decisão tendem a ter o melhor desempenho. O otimizador favorece consistentemente os membros mais fortes do conjunto - quando são fornecidos alunos heterogêneos, os modelos mais fracos, como os regressores lineares, geralmente são eliminados em favor dos mais expressivos, como as árvores de decisão.

O que você fará aqui: preparar e equilibrar o conjunto de dados de estabilidade de grade; estabelecer uma linha de base clássica AdaBoost; executar várias configurações quânticas que variam a largura e a regularização do conjunto; executar em simuladores IBM® ou QPUs via Qiskit Serverless; e comparar a exatidão, a precisão, a recuperação e F1 em todas as execuções. Ao longo do caminho, você usará o padrão de ação da função (create, fit, predict, fit_predict, create_fit_predict) e os controles de tecla:

  • Tipos de regularização: onsite (λ) para esparsidade direta e alpha para uma compensação baseada em proporção entre termos de interação e no local
  • Auto-regularização: defina regularization="auto" com uma taxa de seleção de destino para adaptar a esparsidade automaticamente
  • Opções do otimizador: simulador versus QPU, repetições, otimizador clássico e suas opções, profundidade de transpilagem e configurações do Sampler ou do Estimator d Qiskit Runtime

As referências na documentação mostram que a precisão melhora à medida que o número de alunos (qubits) aumenta em problemas desafiadores, com o classificador quântico igualando ou superando um conjunto clássico comparável. Neste tutorial, você reproduzirá o fluxo de trabalho de ponta a ponta e examinará quando o aumento da largura do conjunto ou a mudança para a regularização adaptável produz melhor F1 com uso razoável de recursos. O resultado é uma visão fundamentada de como uma etapa de otimização quântica pode complementar, em vez de substituir, o aprendizado de conjunto clássico em aplicativos reais.


Requisitos

Antes de iniciar este tutorial, verifique se você tem os seguintes pacotes instalados em seu ambiente Python :

  • qiskit[visualization]~=2.1.0
  • qiskit-serverless~=0.24.0
  • qiskit-ibm-runtime v0.40.1
  • qiskit-ibm-catalog~=0.8.0
  • scikit-learn==1.5.2
  • pandas>=2.0.0,<3.0.0
  • imbalanced-learn~=0.12.3

Instalação

Nesta seção, inicializamos o cliente Qiskit Serverless e carregamos a função Singularity Machine Learning - Classification fornecida pela Multiverse Computing. Com o Qiskit Serverless, você pode executar fluxos de trabalho híbridos quânticos-clássicos na infraestrutura de nuvem gerenciada pelo IBM sem se preocupar com o gerenciamento de recursos. Você precisará de uma chave de API IBM Quantum Platform e do seu nome de recurso na nuvem (CRN) para se autenticar e acessar Qiskit Functions.

Baixe o conjunto de dados

Para executar este tutorial, usamos um conjunto de dados de classificação de estabilidade de grade pré-processado que contém leituras rotuladas de sensores do sistema de energia. A célula a seguir cria automaticamente a estrutura de pastas necessária e faz o download dos arquivos de treinamento e teste diretamente em seu ambiente usando wget. Se você já tiver esses arquivos localmente, esta etapa os substituirá com segurança para garantir a consistência da versão.

## 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
base_url = (
    "https://raw.githubusercontent.com/Qiskit/documentation/"
    "main/datasets/tutorials/grid_stability"
)
!wget -q --show-progress -O data_tutorial/grid_stability/train.csv {base_url}/train.csv

!wget -q --show-progress -O data_tutorial/grid_stability/test.csv {base_url}/test.csv

# Check the files have been downloaded
!echo "Dataset files downloaded:"
!ls -lh data_tutorial/grid_stability/*.csv

Output:

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

Importar pacotes necessários

Nesta seção, importamos todos os pacotes do Python e os módulos do Qiskit usados em todo o tutorial. Isso inclui as principais bibliotecas científicas para manipulação de dados e avaliação de modelos, como NumPy, pandas e scikit-learn , além de ferramentas de visualização e componentes Qiskit para executar o modelo quântico aprimorado. Também importamos o QiskitRuntimeService e o QiskitFunctionsCatalog para nos conectarmos aos serviços do IBM Quantum® e acessarmos a função Singularity Machine Learning.

from pprint import pprint
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 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")

Definir variáveis constantes

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"

Conecte-se a IBM Quantum e carregue a função Singularity

Em seguida, fazemos a autenticação com os serviços IBM Quantum e carregamos a função Singularity Machine Learning - Classification do site Qiskit Functions Catalog. O QiskitRuntimeService estabelece uma conexão segura com o IBM Quantum Platform usando seu token de API e o CRN da instância, permitindo o acesso a back-ends quânticos. O endereço QiskitFunctionsCatalog é então usado para recuperar a função Singularity pelo nome ("multiverse/singularity"), o que nos permite chamá-la posteriormente para a computação quântica-clássica híbrida. Se a configuração for bem-sucedida, você verá uma mensagem de confirmação indicando que a função foi carregada corretamente.

catalog = QiskitFunctionsCatalog(
    token=IBM_TOKEN,
    instance=IBM_INSTANCE_TEST,
    channel="ibm_quantum_platform",
)
backend = catalog.least_busy()

singularity = catalog.load(FUNCTION_NAME)
print(
    "Successfully connected to IBM Qiskit Serverless and "
    "loaded the Singularity function."
)
print("Catalog:", catalog)
print("Singularity function:", singularity)

Output:

Successfully connected to IBM Qiskit Serverless and loaded the Singularity function.
Catalog: <QiskitFunctionsCatalog>
Singularity function: QiskitFunction(multiverse/singularity)

Defina funções auxiliares

Antes de executar os principais experimentos, definimos algumas pequenas funções utilitárias que simplificam o carregamento de dados e a avaliação de modelos.

  • load_data() lê os arquivos CSV de entrada em matrizes NumPy, dividindo recursos e rótulos para compatibilidade com fluxos de trabalho scikit-learn e quantum.
  • evaluate_predictions() calcula as principais métricas de desempenho - exatidão, precisão, recall e F1-score - e, opcionalmente, informa o tempo de execução se forem fornecidas informações de tempo.

Essas funções auxiliares simplificam as operações repetidas posteriormente no notebook e garantem relatórios de métricas consistentes nos classificadores clássicos e quânticos.

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

Passo 1: Mapear entradas clássicas para um problema quântico

Começamos preparando o conjunto de dados para a experimentação híbrida quântica-clássica. O objetivo dessa etapa é converter os dados brutos de estabilidade da grade em divisões equilibradas de treinamento, validação e teste que possam ser usadas de forma consistente pelos fluxos de trabalho clássico e quântico. A manutenção de divisões idênticas garante que as comparações de desempenho posteriores sejam justas e reproduzíveis.

Carregamento e pré-processamento de dados

Primeiro, carregamos os arquivos CSV de treinamento e teste, criamos uma divisão de validação e equilibramos o conjunto de dados usando uma superamostragem aleatória. O balanceamento evita a tendência para a classe majoritária e fornece um sinal de aprendizado mais estável para os modelos de conjunto clássico e quântico.

# 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)

Output:

Shapes:
  X_train_bal: (5104, 12)
  y_train_bal: (5104,)
  X_val: (850, 12)
  y_val: (850,)
  X_test: (750, 12)
  y_test: (750,)

Linha de base clássica: referência AdaBoost

Antes de executar qualquer otimização quântica, treinamos uma linha de base clássica forte - um classificador AdaBoost padrão - nos mesmos dados balanceados. Isso fornece um ponto de referência reproduzível para comparação posterior, ajudando a quantificar se a otimização quântica melhora a generalização ou a eficiência além de um conjunto clássico bem ajustado.

# ----- 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)

Output:

Classical AdaBoost baseline:
Accuracy: 0.7893333333333333
Precision: 1.0
Recall: 0.7893333333333333
F1: 0.8822652757078987

Etapa 2: Otimizar o problema para execução em hardware quântico

A tarefa de seleção de conjuntos é formulada como um problema de otimização combinatória, no qual cada aprendizado fraco é uma variável de decisão binária, e o objetivo equilibra a precisão com a esparsidade por meio de um termo de regularização. O resolve QuantumEnhancedEnsembleClassifier isso com QAOA em hardware d IBM, sem deixar de permitir a exploração por meio de simuladores. O controle optimizer_options do loop híbrido: simulator=False direciona os circuitos para a QPU selecionada, num_solutions aumenta a amplitude da busca e ( classical_optimizer_options para o otimizador clássico interno) controla a convergência; valores em torno de 60 iterações representam um bom equilíbrio entre qualidade e tempo de execução. As opções de tempo de execução — como profundidade moderada do circuito (reps) e um esforço padrão de transpilagem — ajudam a garantir um desempenho robusto em todos os dispositivos. A configuração abaixo é o perfil “melhores resultados” que usaremos para execuções em hardware; você também pode criar uma variante puramente simulada ativando a opção simulator=True para executar o fluxo de trabalho em modo de simulação, sem consumir tempo da QPU.

# 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}")

Output:

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

Passo 3: Execute usando Qiskit primitives

Agora, executamos o fluxo de trabalho completo usando a ação create_fit_predict da função Singularity para treinar, otimizar e avaliar o QuantumEnhancedEnsembleClassifier de ponta a ponta na infraestrutura IBM. A função cria o conjunto, aplica a otimização quântica por meio do site Qiskit primitives e retorna as previsões e os metadados do trabalho (inclusive o tempo de execução e o uso de recursos). A divisão de dados clássicos da Etapa 1 é reutilizada para fins de reprodutibilidade, com dados de validação passados pelo site fit_params para que a otimização possa ajustar os hiperparâmetros internamente, mantendo o conjunto de testes retido intacto.

Nesta etapa, exploramos várias configurações do conjunto quântico para entender como os principais parâmetros - especificamente num_learners e regularization - afetam a qualidade dos resultados e o uso da QPU.

  • num_learners determina a largura do conjunto (e, implicitamente, o número de qubits), influenciando a capacidade e o custo computacional do modelo.
  • regularization controla a esparsidade e o ajuste excessivo, definindo quantos alunos permanecem ativos após a otimização.

Ao variar esses parâmetros, podemos ver como a largura e a regularização do conjunto interagem: o aumento da largura normalmente melhora o F1, mas custa mais tempo de QPU, enquanto a regularização mais forte ou adaptável pode melhorar a generalização com praticamente o mesmo espaço ocupado pelo hardware. As próximas subseções apresentam três configurações representativas para ilustrar esses efeitos.

Linha de base

Essa configuração usa num_learners = 10 e regularization = 7.

  • num_learners controla a largura do conjunto - efetivamente o número de aprendizes fracos combinados e, no hardware quântico, o número de qubits necessários. Um valor maior expande o espaço de pesquisa combinatória e pode melhorar a precisão e a recuperação, mas também aumenta a largura do circuito, o tempo de compilação e o uso geral da QPU.
  • regularization define a força da penalidade para incluir alunos adicionais. Com a regularização padrão "no local", os valores mais altos impõem uma esparsidade mais forte (menos alunos mantidos), enquanto os valores mais baixos permitem conjuntos mais complexos.

Essa configuração fornece uma linha de base de baixo custo, mostrando como um conjunto pequeno se comporta antes de dimensionar a largura ou ajustar a esparsidade.

# Problem scale and regularization
NUM_LEARNERS = 10
REGULARIZATION = 7
# ----- Quantum-enhanced ensemble on IBM hardware -----
print("\n-- Submitting quantum-enhanced ensemble job --")
job_1 = singularity.run(
    action="create_fit_predict",
    name="grid_stability_qeec",
    quantum_classifier="QuantumEnhancedEnsembleClassifier",
    num_learners=NUM_LEARNERS,
    regularization=REGULARIZATION,
    optimizer_options=optimizer_options,  # from Step 2
    backend_name=backend,  # least-busy compatible backend
    instance=IBM_INSTANCE_QUANTUM,
    random_state=RANDOM_STATE,
    X_train=X_train_bal,
    y_train=y_train_bal,
    X_test=X_test,
    fit_params={"validation_data": (X_val, y_val)},
    options={"save": False},
)
result_1 = job_1.result()
print("Action status:", result_1.get("status"))
print("Action message:", result_1.get("message"))
print("Metadata:")
pprint(result_1.get("metadata"))
qeec_pred_job_1 = np.array(result_1["data"]["predictions"])
_ = evaluate_predictions(qeec_pred_job_1, y_test)

Output:


-- Submitting quantum-enhanced ensemble job --
Action status: ok
Action message: Classifier created, fitted, and predicted.
Metadata:
{'resource_usage': {'RUNNING: EXECUTING_QPU': {'QPU_TIME': 1550.1889700889587},
                    'RUNNING: MAPPING': {'CPU_TIME': 267.05158376693726},
                    'RUNNING: POST_PROCESSING': {'CPU_TIME': 152.4274561405182},
                    'RUNNING: WAITING_QPU': {'CPU_TIME': 3336.8785166740417}}}
Accuracy: 0.868
Precision: 1.0
Recall: 0.868
F1: 0.9293361884368309
status_1 = job_1.status()
print("\nQuantum job status:", status_1)

Output:


Quantum job status: DONE

Aumentar o número de alunos

Aqui, aumentamos o num_learners de 10 → 30, mantendo o regularization = 7.

  • Um número maior de alunos expande o espaço de hipóteses, permitindo que o modelo capture padrões mais sutis, o que pode elevar modestamente F1.
  • Na maioria dos casos, a diferença de tempo de execução entre 10 e 30 alunos não é substancial, o que indica que a largura adicional do circuito não aumenta significativamente o custo de execução.
  • O aprimoramento da qualidade ainda segue uma curva de retorno decrescente : os primeiros ganhos aparecem à medida que o conjunto cresce, mas eles se estabilizam quando os alunos adicionais contribuem com menos informações novas.

Esse experimento destaca a compensação entre qualidade e eficiência - o aumento da largura do conjunto pode oferecer pequenos ganhos de precisão sem uma grande penalidade no tempo de execução, dependendo das condições de backend e transpilação.

# Problem scale and regularization
NUM_LEARNERS = 30
REGULARIZATION = 7
# ----- Quantum-enhanced ensemble on IBM hardware -----
print("\n-- Submitting quantum-enhanced ensemble job --")
job_2 = singularity.run(
    action="create_fit_predict",
    name="grid_stability_qeec",
    quantum_classifier="QuantumEnhancedEnsembleClassifier",
    num_learners=NUM_LEARNERS,
    regularization=REGULARIZATION,
    optimizer_options=optimizer_options,  # from Step 2
    backend_name=backend,  # least-busy compatible backend
    instance=IBM_INSTANCE_QUANTUM,
    random_state=RANDOM_STATE,
    X_train=X_train_bal,
    y_train=y_train_bal,
    X_test=X_test,
    fit_params={"validation_data": (X_val, y_val)},
    options={"save": False},
)
result_2 = job_2.result()
print("Action status:", result_2.get("status"))
print("Action message:", result_2.get("message"))
print("QPU Time:")
pprint(result_2.get("metadata"))
qeec_pred_job_2 = np.array(result_2["data"]["predictions"])
_ = evaluate_predictions(qeec_pred_job_2, y_test)

Output:


-- Submitting quantum-enhanced ensemble job --
Action status: ok
Action message: Classifier created, fitted, and predicted.
QPU Time:
{'resource_usage': {'RUNNING: EXECUTING_QPU': {'QPU_TIME': 1095.822762966156},
                    'RUNNING: MAPPING': {'CPU_TIME': 680.2116754055023},
                    'RUNNING: POST_PROCESSING': {'CPU_TIME': 154.4466371536255},
                    'RUNNING: WAITING_QPU': {'CPU_TIME': 80.80395102500916}}}
Accuracy: 0.8946666666666667
Precision: 1.0
Recall: 0.8946666666666667
F1: 0.944405348346235
status_2 = job_2.status()
print("\nQuantum job status:", status_2)

Output:


Quantum job status: DONE

Regularização

Nessa configuração, aumentamos para num_learners = 60 e introduzimos a regularização adaptativa para gerenciar a esparsidade de forma mais intuitiva.

  • Com regularization = "auto", o otimizador encontra automaticamente uma força de regularização adequada que seleciona aproximadamente regularization_ratio * num_learners alunos fracos para o conjunto final, em vez de fixar a penalidade manualmente. Isso oferece uma interface mais conveniente para gerenciar o equilíbrio entre a esparsidade e o tamanho do conjunto.
  • regularization_type = "alpha" define como a penalidade é aplicada. Ao contrário do onsite, que não tem limites [0, ∞], o alpha tem limites entre [0, 1], o que facilita o ajuste e a interpretação. O parâmetro controla a compensação entre penalidades individuais e em pares, oferecendo uma faixa de configuração mais suave.
  • regularization_desired_ratio ≈ 0.82 especifica a proporção-alvo de alunos a serem mantidos ativos após a regularização - aqui, cerca de 82% dos alunos são retidos, cortando automaticamente os 18% mais fracos.

Embora a regularização adaptativa simplifique a configuração e ajude a manter um conjunto equilibrado, ela não garante necessariamente um desempenho melhor ou mais estável. A qualidade real depende da seleção de um parâmetro de regularização adequado, e o ajuste fino por meio de validação cruzada pode ser caro do ponto de vista computacional. A principal vantagem está no aprimoramento da usabilidade e da interpretabilidade, em vez de ganhos diretos de precisão.

# Problem scale and regularization
NUM_LEARNERS = 60
REGULARIZATION = "auto"
REGULARIZATION_TYPE = "alpha"
REGULARIZATION_RATIO = 0.82
# ----- Quantum-enhanced ensemble on IBM hardware -----
print("\n-- Submitting quantum-enhanced ensemble job --")
job_3 = singularity.run(
    action="create_fit_predict",
    name="grid_stability_qeec",
    quantum_classifier="QuantumEnhancedEnsembleClassifier",
    num_learners=NUM_LEARNERS,
    regularization=REGULARIZATION,
    regularization_type=REGULARIZATION_TYPE,
    regularization_desired_ratio=REGULARIZATION_RATIO,
    optimizer_options=optimizer_options,  # from Step 2
    backend_name=backend,  # least-busy compatible backend
    instance=IBM_INSTANCE_QUANTUM,
    random_state=RANDOM_STATE,
    X_train=X_train_bal,
    y_train=y_train_bal,
    X_test=X_test,
    fit_params={"validation_data": (X_val, y_val)},
    options={"save": False},
)
result_3 = job_3.result()
print("Action status:", result_3.get("status"))
print("Action message:", result_3.get("message"))
print("Metadata:")
pprint(result_3.get("metadata"))
qeec_pred_job_3 = np.array(result_3["data"]["predictions"])
_ = evaluate_predictions(qeec_pred_job_3, y_test)

Output:


-- Submitting quantum-enhanced ensemble job --
Action status: ok
Action message: Classifier created, fitted, and predicted.
Metadata:
{'resource_usage': {'RUNNING: EXECUTING_QPU': {'QPU_TIME': 1146.5584812164307},
                    'RUNNING: MAPPING': {'CPU_TIME': 1387.7451872825623},
                    'RUNNING: POST_PROCESSING': {'CPU_TIME': 171.78878355026245},
                    'RUNNING: WAITING_QPU': {'CPU_TIME': 95.41597843170166}}}
Accuracy: 0.908
Precision: 1.0
Recall: 0.908
F1: 0.9517819706498952
status_3 = job_3.status()
print("\nQuantum job status:", status_3)

Output:


Quantum job status: DONE

Etapa 4: Pós-processamento e retorno do resultado no formato clássico desejado

Agora, pós-processamos os resultados das execuções clássica e quântica, convertendo-os em um formato consistente para avaliação posterior. Essa etapa compara a qualidade da previsão usando métricas padrão - exatidão, precisão, recuperação e F1 - e analisa como a largura do conjunto (num_learners) e o controle de esparsidade (regularization) influenciam o desempenho e o comportamento computacional.

A linha de base clássica do AdaBoost oferece uma referência compacta e estável para o aprendizado em pequena escala. Ele tem bom desempenho com conjuntos limitados e sobrecarga de computação insignificante, refletindo a força do reforço tradicional quando o espaço de hipóteses ainda é tratável. As configurações quânticas (qeec_pred_job_1, qeec_pred_job_2 e qeec_pred_job_3) ampliam essa linha de base incorporando o processo de seleção de conjuntos em um loop de otimização quântica variacional. Isso permite que o sistema explore subconjuntos exponencialmente grandes de alunos simultaneamente em sobreposição, abordando a natureza combinatória da seleção de conjuntos de forma mais eficiente à medida que a escala aumenta.

Os resultados mostram que o aumento de num_learners de 10 para 30 melhora a recuperação e F1, confirmando que um conjunto mais amplo captura interações mais ricas entre os alunos fracos. O ganho é sublinear no hardware atual - cada aprendiz adicional produz incrementos de precisão menores - mas o comportamento de escala subjacente permanece favorável porque o otimizador quântico pode pesquisar espaços de configuração mais amplos sem o aumento exponencial típico da seleção clássica de subconjuntos. A regularização introduz nuances adicionais: um λ=7 fixo impõe uma esparsidade consistente e estabiliza a convergência, enquanto a regularização α adaptativa ajusta automaticamente a esparsidade com base nas correlações entre os alunos. Esse corte dinâmico geralmente alcança um F1 ligeiramente maior para a mesma largura de qubit, equilibrando a complexidade e a generalização do modelo.

Quando comparada diretamente com a linha de base AdaBoost, a menor configuração quântica ( L=10 ) reproduz precisão semelhante, validando a correção do pipeline híbrido. Em larguras maiores, as variantes quânticas - especialmente com a autorregularização - começam a superar modestamente a linha de base clássica, mostrando melhor recuperação e F1 sem crescimento linear no custo computacional. Esses aprimoramentos não indicam uma "vantagem quântica" imediata, mas sim uma eficiência de escalonamento : o otimizador quântico mantém um desempenho viável à medida que o conjunto se expande, enquanto uma abordagem clássica enfrentaria um crescimento exponencial na complexidade da seleção de subconjuntos.

Na prática:

  • Use a linha de base clássica para validação rápida e benchmarking em pequenos conjuntos de dados.
  • Aplique conjuntos quânticos quando a largura do modelo ou a complexidade dos recursos aumentar - a pesquisa baseada em QAOA se adapta melhor a esses regimes.
  • Empregar a α-regularização adaptativa para manter a esparsidade e a generalização sem aumentar a largura do circuito.
  • Monitore o tempo e a profundidade da QPU para equilibrar os ganhos de qualidade com as restrições de hardware de curto prazo.

Juntos, esses experimentos mostram que os conjuntos otimizados por quantum complementam os métodos clássicos: eles reproduzem a precisão da linha de base em pequenas escalas e, ao mesmo tempo, oferecem um caminho para o dimensionamento eficiente em problemas de aprendizado combinatório maiores. Com o aprimoramento do hardware, espera-se que essas vantagens de escalonamento se agravem, ampliando o tamanho e a profundidade viáveis dos modelos baseados em conjuntos para além do que é classicamente prático.

Avalie as métricas para cada configuração

Agora, avaliamos todas as configurações - a linha de base clássica AdaBoost e os três conjuntos quânticos - usando o auxiliar evaluate_predictions para calcular a exatidão, a precisão, a recuperação e F1 no mesmo conjunto de testes. Essa comparação esclarece como a otimização quântica é dimensionada em relação à abordagem clássica: em larguras pequenas, ambas têm desempenho semelhante; à medida que os conjuntos crescem, o método quântico pode explorar espaços de hipóteses maiores com mais eficiência. A tabela resultante captura essas tendências de forma consistente e quantitativa.

results = []

# Classical baseline
acc_b, prec_b, rec_b, f1_b = evaluate_predictions(baseline_pred, y_test)
results.append(
    {
        "Config": "AdaBoost (Classical)",
        "Accuracy": acc_b,
        "Precision": prec_b,
        "Recall": rec_b,
        "F1": f1_b,
    }
)

# Quantum runs
for label, preds in [
    ("QEEC L=10, reg=7", qeec_pred_job_1),
    ("QEEC L=30, reg=7", qeec_pred_job_2),
    (f"QEEC L=60, reg=auto (α={REGULARIZATION_RATIO})", qeec_pred_job_3),
]:
    acc, prec, rec, f1 = evaluate_predictions(preds, y_test)
    results.append(
        {
            "Config": label,
            "Accuracy": acc,
            "Precision": prec,
            "Recall": rec,
            "F1": f1,
        }
    )


df_results = pd.DataFrame(results)
df_results

Output:

Accuracy: 0.7893333333333333
Precision: 1.0
Recall: 0.7893333333333333
F1: 0.8822652757078987
Accuracy: 0.868
Precision: 1.0
Recall: 0.868
F1: 0.9293361884368309
Accuracy: 0.8946666666666667
Precision: 1.0
Recall: 0.8946666666666667
F1: 0.944405348346235
Accuracy: 0.908
Precision: 1.0
Recall: 0.908
F1: 0.9517819706498952
, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,0AdaBoost (Classical)0.7893331.00.7893330.8822651QEEC L=10, reg=70.8680001.00.8680000.9293362QEEC L=30, reg=70.8946671.00.8946670.9444053QEEC L=60, reg=auto (α=0.82)0.9080001.00.9080000.951782 ,

Visualize as tendências de qualidade em todas as configurações

O gráfico de barras agrupado abaixo compara a Precisão e a F1 entre a linha de base clássica e os conjuntos quânticos (L=10, L=30 e L=60 auto-α). Ele ilustra como a precisão se estabiliza enquanto o F1 melhora gradualmente à medida que a largura do conjunto quântico aumenta, demonstrando que o método híbrido sustenta o escalonamento do desempenho sem o crescimento exponencial de custos típico da seleção clássica de subconjuntos.

x = np.arange(len(df_results))
width = 0.35
plt.figure(figsize=(7.6, 4.6))
plt.bar(x - width / 2, df_results["Accuracy"], width=width, label="Accuracy")
plt.bar(x + width / 2, df_results["F1"], width=width, label="F1")
plt.xticks(x, df_results["Config"], rotation=10)
plt.ylabel("Score")
plt.title("Classical vs Quantum ensemble performance")
plt.legend()
plt.ylim(0, 1.0)
plt.tight_layout()
plt.show()

Output:

Output of the previous code cell

Interpretação

O gráfico confirma o padrão de escala esperado. O AdaBoost clássico tem um bom desempenho para conjuntos menores, mas torna-se cada vez mais caro para ser dimensionado à medida que o número de alunos fracos aumenta, porque seu problema de seleção de subconjunto se expande de forma combinatória. Os modelos com aprimoramento quântico replicam a precisão clássica em larguras baixas e começam a superá-la à medida que o tamanho do conjunto aumenta, especialmente sob a regularização α adaptativa. Isso reflete a capacidade do otimizador quântico de amostrar e avaliar muitos subconjuntos candidatos em paralelo por meio de superposição, mantendo a pesquisa tratável mesmo em larguras maiores. Embora a sobrecarga de hardware atual compense alguns dos ganhos teóricos, a tendência ilustra a vantagem da eficiência de dimensionamento da formulação quântica. Em termos práticos, o método clássico continua sendo preferível para benchmarks leves, enquanto os conjuntos aprimorados por quantum tornam-se vantajosos à medida que a dimensionalidade do modelo e o tamanho do conjunto aumentam, oferecendo melhores compensações entre precisão, generalização e crescimento computacional.


Apêndice: Benefícios e melhorias de escalabilidade

A vantagem de escalabilidade do site QuantumEnhancedEnsembleClassifier decorre do modo como o processo de seleção de conjuntos é mapeado para a otimização quântica. Os métodos clássicos de aprendizagem de conjuntos, como AdaBoost ou florestas aleatórias, tornam-se computacionalmente caros à medida que o número de alunos fracos aumenta, pois a seleção do subconjunto ideal é um problema combinatório que se expande exponencialmente.

Em contrapartida, a formulação quântica - implementada aqui por meio do Algoritmo de Otimização Aproximada Quântica (QAOA) - pode explorar esses espaços de pesquisa exponencialmente grandes com mais eficiência, avaliando várias configurações em superposição. Como resultado, o tempo de treinamento não aumenta significativamente com o número de alunos, permitindo que o modelo permaneça eficiente mesmo com o aumento da largura do conjunto.

Embora o hardware atual apresente algumas limitações de ruído e profundidade, esse fluxo de trabalho demonstra uma abordagem híbrida de curto prazo em que os componentes clássicos e quânticos cooperam: o otimizador quântico fornece um cenário de inicialização melhor para o loop clássico, melhorando a convergência e a qualidade do modelo final. À medida que os processadores quânticos evoluem, espera-se que esses benefícios de escalabilidade se estendam a conjuntos de dados maiores, conjuntos mais amplos e profundidades de circuito mais profundas.


Referências

  1. Introdução ao Qiskit Functions
  2. Singularidade da computação do multiverso Machine Learning

Pesquisa tutorial

Reserve um minuto para fazer comentários sobre este tutorial. Suas percepções nos ajudarão a melhorar nossas ofertas de conteúdo e a experiência do usuário.

Link para a pesquisa

Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.