LSTM+KNN的金融时间序列预测

薛定谔了么
2025-11-18 01:16:00
人工智能
算法解析

 今天的案例是:STM-KNN融合模型在金融时间序列预测中的应用。


当你在预测股票价格的变化。你可以用两种思路去分析:


一种是LSTM:它就像一个善于记忆的“未来小预测家”,能记住之前价格的走势规律(比如三天前大涨,今天可能还涨),适合处理时间序列的数据。


另一种是KNN:它就像一个“查相似案例的老专家”,看到今天的情况后,会去历史中找“过去哪个时间点跟现在最像”,然后用那些时候的走势来做预测。


LSTM-KNN融合模型就是把这两个方法结合起来:



一个能记住长期趋势(LSTM),一个能查找相似历史情况(KNN)


两者一起上阵,让预测更靠谱。



  核心原理


1. LSTM


LSTM 是一种改进的循环神经网络(RNN),解决了普通RNN难以记住长期信息的问题。它能有效捕捉金融时间序列中的长期依赖性


LSTM 的核心结构包括 3 个门控机制:


输入门(Input Gate):决定当前输入有多少信息传进来。


遗忘门(Forget Gate):决定过去记忆有多少信息要丢弃。


输出门(Output Gate):决定最终输出什么内容。


LSTM 关键公式:


设:


 · xt:当前输入(如某一天的价格)


 · ht-1:上一时刻的隐藏状态


 · Ct-1:上一时刻的记忆单元


 · W,b:权重和偏置


则 LSTM 计算过程如下:


1.遗忘门:



2.输入门:



3.更新记忆单元:



4.输出门:




LSTM 会输出一个预测值(比如明天的价格走势),我们可以把它作为第一阶段的预测。



2. KNN(K-最近邻)


KNN 是一种基于“相似性”的非参数监督学习算法,核心思想是:



找到当前数据与历史数据中最相似的 K 个样本,看看它们的走势是涨还是跌,进行投票或加权平均。



KNN 实现步骤:


1.构造特征向量(如过去5天的涨跌)


2.定义距离度量方式(如欧式距离):



3.找到距离最近的 K 个样本


4.根据这 K 个样本的目标值(如涨跌情况)做平均或投票,得到预测值


3. LSTM-KNN 融合模型


这个融合模型可以有多种融合方式,常见的两种:


方法一:后融合(Late Fusion)


 · LSTM预测值KNN预测值 分别计算


 · 然后做加权平均:



其中α∈[0,1]是融合权重


方法二:级联融合(Stacking)


 · 先让 LSTM 和 KNN 各自输出结果


 · 再用另一个模型(如线性回归或小型神经网络)学习如何组合这两个结果


  完整案例


将LSTM(长短期记忆神经网络)和KNN(K近邻算法)相结合,用于预测金融时间序列(如股票价格)。融合的目的是同时捕捉趋势性(LSTM)和模式相似性(KNN),提升模型在波动金融数据上的预测准确性。


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
from sklearn.preprocessing import MinMaxScaler
from sklearn.neighbors import KNeighborsRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error
from torch.utils.data import DataLoader, TensorDataset

# 1. 设定随机种子
np.random.seed(42)
torch.manual_seed(42)

# 2. 构造虚拟金融时间序列数据
days = 500
price = 100 + np.cumsum(np.random.normal(0, 1, size=days))
sma_short = pd.Series(price).rolling(5).mean()
sma_long = pd.Series(price).rolling(20).mean()
volatility = pd.Series(price).rolling(5).std()

data = pd.DataFrame({
    "price": price,
    "sma_short": sma_short,
    "sma_long": sma_long,
    "volatility": volatility
}).dropna().reset_index(drop=True)

# 3. 特征缩放与滑动窗口生成序列数据
features = ['price', 'sma_short', 'sma_long', 'volatility']
scaler = MinMaxScaler()
data_scaled = scaler.fit_transform(data[features])

def create_sequences(data, target_index=0, seq_len=20):
    X, y = [], []
    for i in range(len(data) - seq_len):
        X.append(data[i:i+seq_len])
        y.append(data[i+seq_len][target_index])
    return np.array(X), np.array(y)

X_seq, y_seq = create_sequences(data_scaled, seq_len=20)
split = int(len(X_seq) * 0.8)
X_train, y_train = X_seq[:split], y_seq[:split]
X_test, y_test = X_seq[split:], y_seq[split:]

# 4. 定义 LSTM 模型结构
class LSTMModel(nn.Module):
    def __init__(self, input_size, hidden_size=64, num_layers=2):
        super(LSTMModel, self).__init__()
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, 1)

    def forward(self, x):
        out, _ = self.lstm(x)
        return self.fc(out[:, -1, :])

# 5. 模型训练
model = LSTMModel(input_size=4)
loss_fn = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

X_train_t = torch.tensor(X_train, dtype=torch.float32)
y_train_t = torch.tensor(y_train, dtype=torch.float32).view(-1, 1)
X_test_t = torch.tensor(X_test, dtype=torch.float32)

train_dl = DataLoader(TensorDataset(X_train_t, y_train_t), batch_size=32, shuffle=True)

train_losses = []
for epoch in range(50):
    model.train()
    batch_losses = []
    for xb, yb in train_dl:
        optimizer.zero_grad()
        pred = model(xb)
        loss = loss_fn(pred, yb)
        loss.backward()
        optimizer.step()
        batch_losses.append(loss.item())
    train_losses.append(np.mean(batch_losses))

# 6. 构建 KNN 模型并预测
X_train_knn = X_train.reshape(X_train.shape[0], -1)
X_test_knn = X_test.reshape(X_test.shape[0], -1)
knn = KNeighborsRegressor(n_neighbors=5)
knn.fit(X_train_knn, y_train)
y_knn_pred = knn.predict(X_test_knn)

# 7. LSTM + KNN 融合预测
model.eval()
with torch.no_grad():
    y_lstm_pred = model(X_test_t).numpy().flatten()

alpha = 0.6  # 融合比例
y_fused = alpha * y_lstm_pred + (1 - alpha) * y_knn_pred

# 8. 可视化分析

# 图1:价格与均线
plt.figure(figsize=(12, 5))
plt.plot(data['price'], label='Price', color='blue')
plt.plot(data['sma_short'], label='SMA 5', color='orange')
plt.plot(data['sma_long'], label='SMA 20', color='green')
plt.title('Price with Moving Averages')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

# 图2:训练损失曲线
plt.figure(figsize=(10, 4))
plt.plot(train_losses, color='crimson')
plt.title('Training Loss Curve (MSE)')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.grid(True)
plt.tight_layout()
plt.show()

# 图3:预测对比图
plt.figure(figsize=(14, 6))
plt.plot(y_test, label='True', color='black')
plt.plot(y_lstm_pred, label='LSTM', color='blue', linestyle='--')
plt.plot(y_knn_pred, label='KNN', color='green', linestyle=':')
plt.plot(y_fused, label='Fused', color='red')
plt.title('Prediction: True vs LSTM vs KNN vs Fused')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

# 图4:残差图
residuals = y_test - y_fused
plt.figure(figsize=(12, 4))
plt.bar(range(len(residuals)), residuals, color='orange')
plt.title('Prediction Residuals (True - Fused)')
plt.tight_layout()
plt.show()

# 9. 模型性能评估
mse = mean_squared_error(y_test, y_fused)
mae = mean_absolute_error(y_test, y_fused)

print(f"Fused Prediction MSE: {mse:.6f}")
print(f"Fused Prediction MAE: {mae:.6f}")

第一步:数据构建与预处理


· 使用 numpy 构造 500 天的“虚拟股票价格”,模拟市场波动;


· 衍生出几个基础技术指标(短期、长期均线和波动率);


· 使用 MinMaxScaler 将数据归一化到 [0, 1] 区间。


第二步:构造时间序列数据(滑动窗口)


· 用过去20 天的数据序列预测第 21 天的价格;


· 避免时间信息“穿越未来”导致数据泄露;


· 得到训练集和测试集。


第三步:定义并训练 LSTM 模型


· PyTorch 实现一个两层 LSTM 网络,捕捉时间序列的趋势;


· 损失函数为 MSE,优化器使用 Adam;


· 每轮迭代记录损失,便于绘图观察模型是否收敛。


第四步:构建 KNN 模型(基于历史相似性)


· 把序列扁平化为向量,使用KNeighborsRegressor寻找最相似的历史片段;


· 模拟“图形识别型交易系统”的逻辑。


第五步:LSTM-KNN 融合预测


· 融合策略为加权平均



· 权重 alpha=0.6,表示更侧重 LSTM 趋势判断。


数据分析图


图1:价格与均线趋势图



展示模拟市场价格随时间的波动情况,显示技术指标对趋势的平滑作用,LSTM 主要就是要学这种趋势结构。


图2:训练误差下降曲线



显示 LSTM 训练过程中损失逐渐减小,判断是否过拟合或欠拟合,趋势平稳下降表示模型收敛良好。


图3:真实值 vs LSTM vs KNN vs 融合预测



直观对比四条曲线的重合程度,融合预测(红色线)更贴近真实走势(黑线),融合能补偿 LSTM 在拐点滞后的问题,KNN则在局部震荡中表现更稳定。


图4:残差条形图(真实 - 融合预测)



可视化每一个时间点预测误差,较小和平均分布的残差说明模型表现稳定,某些高波动时期误差增大,也反映模型挑战点。


 




文章改编转载自微信公众号:机器学习实战ML


原文链接:https://mp.weixin.qq.com/s/ifTlZqJKmDkuQC_2sStlpQ?scene=1

24
0
0
1
关于作者
相关文章
  • 量子计算,离我们普通人还有多远?
    量子计算,正经历一场攸关存亡的“实用主义”转向。全球知名前沿科技咨询机构ICV在《2 ...
    了解详情 
  • 突破长短期记忆网络——LSTM与ARIMA结合的时间序列预测原理 ...
    时间序列数据具有时间依赖性与趋势性,因此需要结合不同的建模方法来捕捉其特性。传统的时间序列 ...
    了解详情 
  • 突破存储瓶颈——人工神经网络如何革新分子模拟数据的压缩与共享 ...
    随着计算能力的显著提升以及分子动力学模拟软件的不断进步,如何高效地存储和共享庞大的生物分子 ...
    了解详情 
  • 基于相干光量子计算机(CIM)的空时编码超表面量子启发优化算法复 ...
    本文是论文《 Quantum Annealing-Inspired Optimization for Space-TimeCoding Metasurface 》的 ...
    了解详情 
联系我们
二维码
在本版发帖返回顶部
快速回复 返回顶部 返回列表
玻色有奖小调研
填写问卷,将免费赠送您5个100bit真机配额
(单选) 您是从哪个渠道得知我们的?*
您是从哪个社交媒体得知我们的?*
您是通过哪个学校的校园宣讲得知我们的呢?
取消

提交成功

真机配额已发放到您的账户,可前往【云平台】查看

量子AI开发者认证

考核目标

开发者能够成功搭建Kaiwu-PyTorch-Plugin项目基础环境,并成功运行QBM-VAE示例代码,根据系统提供的随机seed值,求出正确的FID值。

通过奖励

10个一年效期的550量子比特真机配额

专属「量子AI开发者」社区认证标识

开发者权益

每月固定权益:5个550量子比特真机配额
前往考核

第一步

按照README提示成功安装Kaiwu-PyTorch-Plugin库环境依赖
前往GitHub

第二步

替换seed值

您的seed值为

第三步

输入您计算的FID值

*

提交答案

开发者权益

每月固定权益:5个550量子比特的真机配额

恭喜您完成考核

您将获得量子AI开发者认证标识及考核奖励

550bit*10

配额