Skip to content

用 Python 中的量子机器学习预测股票价格

作者:老余捞鱼

原创不易,转载请标明出处及原作者。

写在前面的话:今天,我们将深入量子计算与机器学习的交叉领域,探索量子机器学习。我们的主要目标是比较量子神经网络与简单的单层 MLP 在预测股票价格时间序列方面的性能

为了促进这个项目,我们将利用 Financial Modeling Prep (FMP) 提供的 Historical API 端点来获取可靠、准确的数据,这一点非常重要。

一、导入数据

首先,让我们导入分析所需的库。这些库将为我们提供探索和实施项目所需的基本工具。

import numpy as np
import pandas as pd
import requests
import json
import tensorflow as tf
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from sklearn.metrics import mean_squared_error
from qiskit import QuantumCircuit
from qiskit.circuit.library import PauliFeatureMap
from qiskit.algorithms.optimizers import ADAM
from qiskit.circuit import Parameter
from qiskit.primitives import Sampler

我们已经安装了用于量子计算网络的 Qiskit 库和其他重要库,从而建立了我们的环境。为了提取数据,我们将使用 Financial Modeling Prep 提供的历史数据 API

FMP 的历史数据应用程序接口(API)提供了一个方便访问的端点,提供了丰富多样的历史股票数据,这在我们项目的每一个步骤中都证明是非常宝贵的。这一资源使我们能够访问广泛的金融信息,从而提高我们分析的深度和准确性。其友好的用户界面和全面的数据集大大提高了我们研究和实施的成功率和效率。现在,我们将提取历史数据如下:

api_url = "https://financialmodelingprep.com/api/v3/historical-price-full/AAPL?apikey=YOUR API KEY"

# Make a GET request to the API
response = requests.get(api_url)

# Check if the request was successful (status code 200)
if response.status_code == 200:
    # Parse the response JSON
    data = response.json()
else:
    print(f"Error: Unable to fetch data. Status code: {response.status_code}")

data

将您的 API 密钥替换为您的秘密 API 密钥,您可以通过创建 FMP 帐户获得该密钥。输出是一个 JSON 响应,如下所示:


二、量子计算简介

在普通计算机中,我们有被称为 “与或门 “的微小开关。这些开关控制着信息的移动。它们与称为 “比特 “的基本数据单位协同工作,比特可以是 0 或 1。这些门帮助计算机进行计算和处理数据。现在,在量子计算机中,我们使用一种叫做 “量子比特 “的东西来代替比特。量子比特很特别,因为它们可以同时为 0 和 1。这就好比一枚硬币在旋转时会同时显示正面和反面,直到你抓住它,它才会选择其中一面。

当我们说 “波函数坍缩 “时,这只是一种花哨的说法,即当我们检查时,量子比特决定是 0 或 1。我们用不同的东西来制造这些量子比特,比如光粒子(光子)、构成东西的微小粒子(原子),甚至是小电路(约瑟夫森结)。这些就像是我们特殊量子比特的构件。这些量子系统(粒子或电路)会做一些有趣的事情。它们可以同时处于不同的状态(叠加),以一种特殊的方式连接在一起(纠缠),甚至穿过它们不应该穿过的障碍(隧穿)。最酷的是,量子计算机凭借其量子比特和特殊行为,利用某些算法比普通计算机更快地解决某些问题。这就像拥有了一种新工具,它可能会帮助我们在未来更高效地解决棘手的难题。


2.1 量子计算中的算子

在传统计算中,我们使用 AND、NOT 和 OR 等基本逻辑门进行运算。这些逻辑门使用 0 和 1 进行运算,其规则基于一个简单的数学系统,称为

它主要处理 2 的模数计算。现在,想象一下量子计算机–它也有门,但这些门就像增压版。量子门处理的不是简单的比特,而是量子比特或量子位。这些量子门背后的数学涉及复数和矩阵运算。

以量子 NOT 门为例:

将它应用于初始状态为∣0⟩的量子比特,算子就会把它翻转到∣1⟩,如果再次应用,它又会回到∣0⟩。这有点像掷硬币。

还有一种哈达玛门(H),它能做一些非常酷的事情。将它应用于最初处于∣0⟩状态的量子比特,会让它同时处于 0 和 1 的特殊混合状态,从而在数学上显示出 H 对|0⟩的操作,并将其转换为标准的基态叠加:

这就好比一枚硬币在空中旋转,在落地之前既显示正面也显示反面。

现在,让我们来谈谈受控-非(CNOT)门。它作用于两个量子位。如果第一个量子比特为∣1⟩,它就会将第二个量子比特从∣0⟩翻转到∣1⟩,反之亦然。这就像一个量子开关,取决于第一个量子比特的状态。

在量子世界里,事情变得更加有趣。如果有两个处于特殊状态的量子比特,CNOT 门会唯一地重新排列它们的组合,产生我们所说的纠缠。这种纠缠就像是量子比特之间的一种特殊联系,使它们的行为协调一致。

因此,简而言之,普通计算机使用的是 0 和 1 的基本规则,而量子计算机拥有这些迷人的门,可以玩弄概率、混合状态,并在量子比特之间建立联系,为更高效地解决复杂问题开辟了一个充满可能性的世界。

在我们的项目中,我们特别强调一类被称为参数化门的门。这些门的行为取决于特定的输入参数,用符号 θ 表示:

如下图所示,每个矩阵都有一个单元矩阵:

让我们深入研究一下这些旋转门:

设想它是一个类似旋转门的量子门,可以将量子比特旋转一个特定的角度 θ。

门的功能类似,都是围绕不同的轴进行旋转。

这些门的意义在于其参数化的特性。通过调整输入参数θ,我们在量子算法中引入了一个可定制的元素。这些门是构建我们项目中不可或缺的量子神经网络的基础组件。

从本质上讲,θ 就像一个类似旋钮的调节参数,使我们能够在量子神经网络框架内对量子算法的行为进行微调和定制。在针对特定任务优化和定制量子算法性能时,这种灵活性变得至关重要。

2.2 量子电路

量子算法可以看作是对量子态执行的一系列操作,用类似的表达式来表示:

如下图所示,这些算法被转化为量子电路。在这幅图中,算法从初始状态 |q_0 q_1⟩ = |00⟩ 开始,以测量结果|00⟩ 或 |11⟩(概率相等,均为 0.5)结束,并记录为经典比特(c 线)。

在量子电路中,每条横线对应一个量子比特,门依次应用,直到测量为止。值得注意的是,量子程序中不允许循环。变分量子电路(VQC)是量子电路的一种特殊类型。值得注意的是,VQC 包含参数化门,如前面提到的 R_x(θ)、R_y(θ)、R_z(θ)。

简单地说,量子算法就像是量子计算机的逐步指令,而量子电路则直观地表示这些步骤。变分量子电路通过参数化门引入了一种特殊的灵活性,允许根据特定值(用 θ 表示)进行定制。

2.3 量子机器学习

QML 的主要目标是设计和部署能够在量子计算机上运行的方法,以解决经典机器学习中遇到的传统监督、无监督和强化学习任务。

QML 的与众不同之处在于它利用量子计算(QC)固有的叠加、隧道、纠缠和量子并行等独特功能,进行量子操作。在我们的研究中,我们特别关注量子神经网络(QNN)的设计。量子神经网络是经典神经网络的量子对应物。

细分起来,QNN 的每一层都是一个变量量子电路 (VQC),由参数化的门组成。这些参数相当于经典神经网络中的权重。此外,量子神经网络还包含一种在现有量子位之间交换信息的机制,类似于经典网络中不同层神经元之间的连接。通常,这种信息交换是通过纠缠实现的,采用的算子包括 CNOT 门。

创建量子机器学习(QML)模型通常需要几个步骤,如上图所示。首先,我们在经典 CPU 上加载并预处理数据集。接下来,我们使用量子嵌入技术,在量子处理单元(QPU)或量子硬件上将经典数据编码为量子态。一旦经典数据以量子态表示,就会执行在解析中实现的核心模型,并使用经典比特测量结果。最后,如果需要,我们会在 CPU 上对这些结果进行后处理,以获得预期的模型输出。在我们的研究中,我们按照这个整体流程来研究量子神经网络在时间序列预测中的应用。

2.4 量子神经网络

量子神经网络 (QNN) 通常由三个主要层组成:

1.输入层:该层将经典输入数据转换为量子态。它使用带有旋转和受控旋转门的参数化变分电路,为给定输入准备所需的量子态。这一步被称为量子嵌入,采用了基编码、振幅编码、哈密顿编码或张量乘积编码等技术。

2.解析层:该层是 QNN 的核心,包含一个变量量子电路,重复 L 次即可经典地模拟 L 个网络层。它负责处理和操作量子信息。

3.输出层:这一层对比特进行测量,提供最终的预期结果。

对于输入层,我们采用张量乘积编码技术。这涉及为每个量子比特设置一个简单的 X 旋转门,门参数通过将经典数据缩放至 [-π, π] 范围来设置。虽然这是一种快速、直接的编码方法(O(1) 运算),但它也有局限性。所需的量子比特数与输入的经典数据成线性比例。为了解决这个问题,我们在输入数据中引入了可学习的缩放和偏差参数,增强了量子嵌入的灵活性。在图 3 中,您可以看到一个有 3 个量子比特的网络的输入层示例,其中经典数据具有以下特征:

输入比例参数:

和偏置参数:

就会发挥作用。

关于公式,值得注意的是,与经典神经网络不同,文献中常见的量子层结构(如全连接层或递归层)并不是固定不变的。量子比特之间可能存在的量子信息传输门是非常广泛的,而如何优化这些门的组织以实现有效的数据传输是一个尚未被深入探索的领域。

在我们的项目中,我们采用了 “真实振幅”(Real Amplitudes ansatz),这一选择的灵感来自于它在量子强化学习和分类的策略估计等多个领域的成功应用。该方案首先采用全旋转 X/Y/Z 参数化门,类似于量子版的连接权重。然后是一系列以环形结构排列的 CNOT 门,以促进量子比特信息的传输。图 4 直观地展示了这一构想是如何实现的,相当于 3 量子比特网络的量子网络层。

细分而言,我们工作中的量子网络层涉及一组参数,参数总数是量子比特数的 3 倍(3*n),其中 “n “代表量子网络中的量子比特数。

现在,让我们来谈谈输出层,它是我们量子模型的关键部分。在量子计算中,当我们想从量子态中提取信息时,通常会使用选定的可观测量进行测量。计算基础上的σ_z算子就是这样一种常用的观测指标。要理解这一点,可以将其视为从量子态中提取信息的一种方法。

网络输出是通过计算量子态的期望值来确定的。这表示为⟨ψ|σ_z|ψ⟩,其中⟨ψ|表示|ψ⟩的复共轭。结果在 [-1, 1] 范围内。

不用再为那些复杂的数学公式而紧张–我们值得信赖的库 Qiskit 已经帮我们解决了这个问题!Qiskit 可以无缝处理所有复杂的量子计算,让我们更容易理解量子计算过程。因此,你可以专注于探索量子世界,而不必被繁琐的数学问题所困扰

现在,为了使我们的网络输出对数据集固有的偏差和规模不那么敏感,我们引入了最终规模参数和需要学习的偏差。这一步骤为我们的模型增加了一层适应性,使其能够根据数据的具体特征对输出进行微调和调整。整个模型架构如下图所示。

我们提出的量子神经网络(QNN)的训练是在普通 CPU 上使用亚当优化器等经典算法进行的。中央处理器通过传统的传播规则处理梯度计算,而在量子处理单元(QPU)上,我们使用参数移动规则计算梯度。这有点像双系统,中央处理器管理主要的训练,而 QPU 则在特定的量子计算中发挥作用。

图 6 展示了训练过程流水线,其中 θ¹ 代表输入层的标度/偏置参数,θ² 对应包含等式的各层参数,θ³ 是网络输出的标度/偏置参数。这种协调确保了利用经典和量子计算资源的内聚训练方法。

由于量子神经网络(QNN)是一种前馈模型,我们首先要定义一个时间跨度,用 T 表示。在这里,目标是时间 t 时的时间序列值,记为 x(t),而输入则包括 x(t-1)、x(t-2)、……、x(t-T)。这种结构调整有助于模型理解数据中的时间关系,使其能够根据过去的值进行预测。


三、用 Qiskit 创建 QNN


3.1 提取数据和数据预处理

首先,我们使用 Financial Modeling Prep 提供的历史数据 API 端点获取数据,如下所示:

api_url = "https://financialmodelingprep.com/api/v3/historical-price-full/AAPL?apikey=YOUR API KEY"

# Make a GET request to the API
response = requests.get(api_url)

# Check if the request was successful (status code 200)
if response.status_code == 200:
    # Parse the response JSON
    data = response.json()
else:
    print(f"Error: Unable to fetch data. Status code: {response.status_code}")

df = pd.json_normalize(data, 'historical', ['symbol']) #convert into a datframe
df.tail()

输出结果是一个 Pandas 数据框架,看起来像这样(在此之前,请确保用您的秘密 API 密钥替换您的 API 密钥):

从这些大量数据中,我们将使用开盘价作为时间变量,我们将使用 500 个数据点,每个数据点代表每日开盘价,我们的预测窗口大小为 2。

final_data = df[['open', 'date']][0:500] #forming filtered dataframe
input_sequences = []
labels = []

#Creating input and output data for time series forecasting
for i in range(len(final_data['open'])):
    if i > 1:
        labels.append(final_data['open'][i])
        input_sequences.append(final_data['open'][i-2:i+1].tolist())
        
#creating train test split
x_train = np.array(input_sequences[0:400])
x_test = np.array(input_sequences[400:])
y_train = np.array(labels[0:400])
y_test = np.array(labels[400:])

现在,让我们绘制获得的数据。

import matplotlib.pyplot as plt
plt.style.use('ggplot')

# Convert the 'date' column to datetime format
df['date'] = pd.to_datetime(df['date'])

# Plotting the time series data
plt.figure(figsize=(10, 6))
plt.plot(df['date'][0:500], df['open'][0:500], marker='o', linestyle='-')

# Adding labels and title
plt.xlabel('date')
plt.ylabel('open')
plt.title('Time Series Data')

# Display the plot
plt.grid(True)
plt.show()

以下是输出结果:


3.2 量子神经网络

Pauli Feature Map:

num_features =  2
feature_map = PauliFeatureMap(feature_dimension = num_features, reps = 2)
optimizer = ADAM(maxiter = 100)

在我们的方法中,我们利用保利特征图将数据编码成量子比特,特别是利用 2 个特征。编码电路的结构如下:

此外,为了优化我们的模型,我们使用了 ADAM 优化器。这一选择有助于微调量子神经网络的参数,从而提高其整体性能。

量子电路:

def ans(n, depth):
    qc = QuantumCircuit(n)
    for j in range(depth):
        for i in range(n):
            param_name = f'theta_{j}_{i}'
            theta_param = Parameter(param_name)
            qc.rx(theta_param, i)
            qc.ry(theta_param, i)
            qc.rz(theta_param, i)
    for i in range(n):
        if i == n-1:
            qc.cnot(i, 0)
        else:
            qc.cnot(i, i+1)
    return qc

该函数初始化量子电路,量子比特数等于特征数。在第一个循环中,它将旋转门添加到电路中,每个旋转门都有参数化的旋转角度。第二个循环将 CNOT 门添加到电路中。每次迭代时,都会添加一个 CNOT 门,将当前的量子比特作为控制比特(第 0 个量子比特),目标量子比特由循环索引决定。此外,还会添加另一个 CNOT 门,将当前的量子位作为控制位,将下一个量子位作为目标位。

这个过程为我们的量子电路构建了反演,本质上就是创建了我们之前定义的量子神经网络结构。该电路的示意图已在前面介绍过,以供参考。

启动 Anstaz 电路:

ansatz = ans(num_features, 5) #anstaz(num_qubits=num_features, reps=5)

#creating train test split
x_train = np.array(input_sequences[0:400])
x_test = np.array(input_sequences[400:])
y_train = np.array(labels[0:400])
y_test = np.array(labels[400:])

现在,我们继续创建一个变分量子电路(VQC),它可以作为神经网络运行。在这个电路中,我们既包含了定义量子神经网络结构的ansatz,也包含了我们的特征编码。为此,我们从 qiskit_machine_learning.classifiers 中导入了 VQC 模块。VQC 封装了我们神经网络的量子处理方面,它与 Qiskit 的集成简化了量子机器学习算法的实现。

VQC:

vqr = VQR(
    feature_map = feature_map,
    ansatz = ansatz,
    optimizer = optimizer,
)

vqr.fit(x_train,y_train)
vqr_mse = mean_squared_error(y_test, vqr.predict(x_test))

# Calculate root mean squared error
vqr_rmse = np.sqrt(vqr_mse)

在最后一步,我们将变异量子回路(VQC)与我们的特征进行拟合。这包括在我们的数据集上训练量子神经网络。拟合完成后,我们通过计算均值误差和均值根误差来评估其性能。这一评估步骤有助于我们衡量变异量子回路在处理给定特征和预测结果方面的准确性和有效性。


3.3 经典神经网络

现在,让我们构建一个简单的经典神经网络,作为与量子神经网络进行比较的基准。我们选择的架构将是一个简单的多层感知器(MLP),它只有一个隐藏层,配备 64 个节点。这个经典神经网络将为我们提供一个参考点,我们可以根据它来评估量子神经网络的性能。

古典 ANN:

model = Sequential()
model.add(Dense(64,activation = 'relu', input_shape = (4,)))
model.add(Dense(1))

model.compile(optimizer = 'adam', loss = 'mean_squared_error')

model.fit(x_train, y_train, epochs = 20, batch_size = 32, validation_data = (x_test,y_test))

loss = model.evaluate(x_test, y_test)
prediction = model.predict(x_test)

ann_mse = mean_squared_error(y_test, prediction.flatten())
ann_rmse = np.sqrt(ann_mse)


四、结果与比较

结果如下: 1)QNN:< 3.5 rmse 2)ann: > 3.6 rmse

在这次评估中,量子神经网络(QNN)的表现明显优于人工神经网络(ANN),显示了其前景。不过,必须承认的是,获得的均方根误差(RMSE)值可能达不到预期的满意度。本实验的主要目的是突出量子计算的潜力,展示其生成卓越结果和构建适用于商业用途的模型的能力。

本研究预计,随着量子计算机不断进步,在有效训练这些模型方面达到更高的鲁棒性水平,在不久的将来,该技术在现实世界的应用将逐步变得更加实用。


在这些发现的基础上,量子神经网络(QNN)显然有望得到进一步发展和实际应用。虽然目前的时间序列预测基准可能优于 QNN,但仍有很大的改进潜力。解决当前的局限性是可以预见的,特别是随着量子计算的不断进步。成功开发出强大的量子计算机,将为在时间序列预测领域取得更卓越的成果打开一扇大门。

注:我展示了量子神经网络 (QNN) 和经典神经网络 (CNN) 的基本演示,以说明它们的构造并突出结果的差异。值得注意的是,量子神经网络可能会出现差异,因此请随意调整所提供的示例,以更好地适应您的具体使用情况。请对代码和参数进行相应调整,以优化性能,并解决在为您的特定应用实施量子神经网络时可能出现的任何难题。


五、结论

总之,本项目探索了量子计算和神经网络的创建,突出了其未来的发展潜力。随着技术的进步,我们有机会利用量子计算机开发更复杂的量子机器学习算法。这些系统可以大大缩短训练时间,受益于量子比特的效率,并能在电路形成中使用更多的量子比特。这一进展为增强计算能力和解决问题的能力打开了大门,为量子计算在机器学习应用领域的未来指明了一条充满希望的道路。

  1. 量子计算机利用量子位的叠加和纠缠特性,能够在处理和计算方面提供比经典计算机更高的效率。
  2. 量子神经网络通过参数化门和量子电路实现,能够在量子计算机上执行,有潜力在机器学习任务中提供优于经典神经网络的性能。
  3. 在处理时间序列数据时,量子神经网络能够捕捉数据中的复杂模式,并在预测股票价格等任务中表现出优异的潜力。
  4. 尽管量子机器学习目前仍然处于发展初期,但随着量子计算技术的进步,它有望在未来成为解决复杂问题的强有力工具。
  5. 本文的研究表明,量子机器学习算法在处理时间序列预测问题时,与经典机器学习算法相比,具有相似或更好的性能。
  6. 随着量子计算机的发展和量子算法的改进,量子机器学习将在未来提供更多的应用可能性,尤其是在金融市场分析等领域。

希望你今天能学到一些有用的新知识。此外,请在评论中告诉我您对量子机器学习及其对股市行业的影响的看法。感谢您的宝贵时间。


本文内容仅仅是技术探讨和学习,并不构成任何投资建议。

转发请注明原作者和出处。

Published inAI&Invest专栏

Be First to Comment

    发表回复