简介:面向机器学习期末大作业、金融量化入门及课程设计的一款基于长短期记忆网络的股票/基金预测模型项目,完整覆盖数据准备、模型训练与预测结果展示环节。资源共11个文件,包含5个Excel数据文件、3个Python脚本、1份Markdown说明、1张预测效果图与1个缓存文件,压缩包整体仅155KB,轻量易部署。已有224人学习下载。数据文件提供基金训练集、测试集、一年期收益排行以及预测结果对比等素材,Python脚本包含LSTM模型定义、视图逻辑与基金净值数据获取功能,配合说明文档与可视化结果,可清晰理解各模块的调用关系与预测流程。读者可在此基础上替换成自己的股票或基金行情数据,调节批大小、时间步长等参数,完成可复现的预测实验,适合课程设计、毕业设计或项目复现参考。资源虽小但结构完整,适合快速上手验证长短期记忆网络在金融场景中的预测效果。
1. 用 LSTM 预测股价之前,先弄清这个“高分项目”到底在预测什么
拿到一个名为“基于机器学习 LSTM 的股票/基金预测模型(高分项目)”的压缩包,很多人的第一反应是解压、跑通、看曲线,然后幻想明天该买哪只。这个思路恰恰是错的。这类项目的核心价值不是给你一个“稳赚不赔的选股器”,而是让你完整走一遍“机器学习应用流程”:从原始行情数据到特征工程,从 LSTM 神经网络搭建到时序预测模型评估,最后在回测中理解预测模型的边界。适合谁?适合正在做课程设计、毕设,或者想入门时间序列预测的开发者。它帮你把“机器学习能做什么”和“股票数据长什么样”两件事串起来。但如果你指望它直接指导实盘交易,我建议趁早打消这个念头——作为工程师,我会把这类项目定位成“练手的高分模板”,而不是“印钞机”。
2. 数据是预测模型的黑匣子:从原始行情到 LSTM 输入张量的完整处理流程
2.1 用机器学习处理行情数据的第一步:先决定预测目标,而不是先找数据
大多数从网上下载的 LSTM 股票预测项目,代码里都会有这么一行:df['close'],然后直接构造滑窗。但我在实际做预测模型时,第一步永远是反问自己:你到底要预测什么?是预测明天收盘价的具体数值,还是预测未来 5 天的涨跌方向?这两种目标对应的数据标签构造方式完全不同,模型架构和评估指标也不一样。
常见做法是预测“下一个交易日的收盘价”,这是一个回归问题。标签就是t+1时刻的 close 价格,特征是t时刻之前一段窗口内的所有可用维度——通常是开盘价、最高价、最低价、收盘价、成交量,再可选地加上技术指标如 MA5、RSI 等。如果你要预测涨跌方向,那就把连续标签变成二分类:1表示明天收盘价比今天高,0表示低。这个选择直接决定损失函数是MSELoss还是CrossEntropyLoss,也决定输出层是Linear(隐藏层, 1)还是Linear(隐藏层, 2)。
我强烈建议新手先从“预测收盘价数值”入手,因为回归任务更容易收敛,也更容易画出“预测值 vs 真实值”的曲线,可视化效果好,答辩的时候也更好讲故事。但要注意,数值预测的评估门槛很低——你随便拿昨天的价格当预测值,RMSE 都没那么难看,所以后面一定要补方向准确率这类指标。
2.2 特征工程与滑窗构造:把时间序列切成 LSTM 能吃的样本
LSTM 神经网络处理的是序列数据,输入形状是(batch, seq_len, feature_dim)。原始行情是一张长表,需要切成一个个固定长度的窗口。比如我们用过去 60 个交易日的特征预测第 61 天的收盘价,那 seq_len 就是 60,feature_dim 就是特征列数。
下面是我常用的滑窗构造代码,用纯 Python 实现,避免引入复杂依赖:
import numpy as np def create_sequences(features, target, seq_len=60): """ 把特征矩阵和标签切成滑动窗口样本 features: shape (n_samples, n_features) target: shape (n_samples,) seq_len: 过去多少个时间步 返回 X: (n_samples-seq_len, seq_len, n_features) y: (n_samples-seq_len,) """ X, y = [], [] for i in range(seq_len, len(features)): X.append(features[i-seq_len:i, :]) # 取前 seq_len 行所有特征 y.append(target[i]) # 当前时刻的真实标签 return np.array(X), np.array(y) # 假设 raw_feature 是已经归一化后的特征矩阵, raw_target 是价格序列 X, y = create_sequences(raw_feature, raw_target, seq_len=60) print("X shape:", X.shape) # 例如 (941, 60, 8) print("y shape:", y.shape) # 例如 (941,)这段代码的逻辑非常直接:从第seq_len个位置开始,不断往后滑一个单位,每次都取前seq_len行作为模型输入,当前行作为标签。注意这里y[i]是target[i],也就是说我们用 0~59 天的数据预测第 60 天的值。如果你想预测未来第 2 天、第 5 天,就把索引改成target[i+delta],并相应地调整返回的样本总数。
参数说明:seq_len是最敏感的超参数之一。设为 60 意味着模型依赖过去约 3 个月的交易日(A 股大概 20 个交易日一个月)。时间序列预测模型里,窗口太短学不到趋势,窗口太长容易引入旧数据噪声。实际调参时我一般从 20、30、60、90 几档里选,结合训练集大小来定,后面避坑章会专门讲。
2.3 归一化与训练集/验证集/测试集划分:最容易翻车的时序切分
数据处理里最隐蔽的坑,是直接用全量数据的均值和标准差做归一化。这在普通机器学习任务里很常见,但用在时间序列预测模型上就是数据泄漏——因为测试集的信息在训练之前就被模型“看到”了。
正确的做法是:先把数据按时间顺序分成三段——训练集(比如前 70%)、验证集(15%)、测试集(最后 15%),然后只用训练集的统计量去归一化所有数据。看代码:
from sklearn.preprocessing import MinMaxScaler # 按时间顺序切分,绝不随机打乱 train_size = int(len(features) * 0.7) val_size = int(len(features) * 0.15) train_data = features[:train_size] val_data = features[train_size:train_size+val_size] test_data = features[train_size+val_size:] # 只拟合训练集 scaler = MinMaxScaler(feature_range=(0, 1)) scaler.fit(train_data) train_scaled = scaler.transform(train_data) val_scaled = scaler.transform(val_data) test_scaled = scaler.transform(test_data)注意scaler.fit(train_data)这一步。fit 只会计算训练集的 min/max,然后用同一套参数去 transform 验证集和测试集。这样测试集的信息不会污染训练过程。如果偷懒写成scaler.fit(features)再全量 transform,模型在训练时就已经“见过”测试集的数值分布,测试集就失去了检验泛化能力的作用。
另外,绝对不要用train_test_split(random_state=42)这类函数做随机切分,因为时间序列一旦乱序,模型学到的就是“未来预测过去”的伪规律,训练损失可能很漂亮,实际效果一塌糊涂。这个踩坑点我在下面避坑章会再强调一次。
3. 搭建 LSTM 股票预测模型:PyTorch 实现与关键参数调优
3.1 LSTM 神经网络的核心结构:为什么它比全连接更适合时序预测模型
很多机器学习入门资料里,LSTM 被描述成一个很神秘的“记忆结构”,其实拆开看并不复杂。相比全连接网络,LSTM 引入了“细胞状态”和“门控机制”:遗忘门决定过去哪些信息要丢弃,输入门决定新信息如何写入,输出门决定当前时刻要输出什么。这让网络在长序列上拥有选择性记忆,能捕捉价格数据的趋势和周期性。当然,股票价格噪声极大,LSTM 不会创造信息,它只是从特征中拟合一个非线性映射。
我用 PyTorch 实现过一个最小可运行的 LSTM 预测模型,结构如下:输入经过一个 LSTM 层,所有时间步的输出取最后一个时间步的隐状态,再接一个全连接层输出预测值。下面给出完整代码,可以直接跑通。
3.2 最小可运行模型代码:从单层 LSTM 到多层堆叠
import torch import torch.nn as nn class LSTMPredictor(nn.Module): def __init__(self, input_size=8, hidden_size=64, num_layers=2, output_size=1, dropout=0.2): """ input_size: 特征维度,比如 8 列特征 hidden_size: 隐藏层神经元数 num_layers: LSTM 层数 output_size: 预测目标维度,回归任务设置为 1 dropout: 多层 LSTM 时,层间随机失活比例 """ super(LSTMPredictor, self).__init__() self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True, dropout=dropout) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x): # x: (batch, seq_len, input_size) out, (h_n, c_n) = self.lstm(x) # out 包含所有时间步输出 # 取最后一个时间步的输出 last_out = out[:, -1, :] # (batch, hidden_size) pred = self.fc(last_out) # (batch, output_size) return pred # 实例化模型 model = LSTMPredictor(input_size=8, hidden_size=64, num_layers=2) # 随机造一批数据: 4 个样本,每个样本 60 个时间步,8 个特征 dummy_x = torch.randn(4, 60, 8) print("output shape:", model(dummy_x).shape) # (4, 1)这段代码里,batch_first=True表示输入张量的第一维是 batch,这样更符合 PyTorch 习惯。out[:, -1, :]是取最后一个时间步的隐藏层输出,这是回归任务最常见的做法。为什么不取所有时间步的平均或拼接?因为最后一个时间步的隐状态已经包含了前面所有信息的压缩表达,如果取平均会稀释近期信息。当然,你可以在上面加注意力机制,但基础模型先用最简单的结构。
num_layers=2是经验值。单层 LSTM 表达能力有限,难以拟合复杂趋势;三层以上在股票这种高噪声数据上很容易过拟合,而且训练时间明显变长。我建议新手固定为 2,等模型收敛后再试 1 或 3。hidden_size=64也是一个起步值,数据量小的时候 32 也够用,数据量大可以上 128。
3.3 必调的三个参数:序列长度、隐藏层大小、学习率
第一个必调参数是序列长度seq_len,前面提过。它决定模型“回头看多远”。有量化研究说股票价格短期动量效应大约在 5~20 个交易日,中期在 60 天左右。你可以做一个小实验:把 seq_len 从 10 逐步调到 120,每个值跑一遍训练,比较验证集 RMSE。你会发现 seq_len 从 20 到 60 时性能提升明显,超过 90 后往往开始变差——因为太久远的市场环境对当前价格影响已经很小,反而把模型参数往噪声里带。
第二个是hidden_size。隐藏单元数决定了 LSTM 的记忆容量。太小,模型记不住必要的模式;太大,参数量暴增,训练集不大时很快就出现过拟合。我习惯用“数据量除以参数量的经验法则”:训练样本 1000 条以内,hidden_size 不超过 32;5000 条左右可以到 64;超过一万条再考虑 128。当然这个法则不是严格公式,但能避免一上来就把模型堆到 256 导致训练半天不收敛。
第三个是学习率。PyTorch 里我常用Adam优化器,它的默认学习率是1e-3,但这个默认值在 LSTM 上并不总是好用。股票价格范围如果被归一化到 0~1,1e-3通常可以接受;如果数据没归一化或者分布偏斜,损失很容易 NaN。我在实践中会先用1e-3跑 10 个 epoch,如果损失震荡不降,就降到3e-4或1e-4。也可以加学习率调度器:
import torch.optim as optim optimizer = optim.Adam(model.parameters(), lr=1e-3) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=5) for epoch in range(50): train_loss = train_one_epoch(model, optimizer, train_loader) val_loss = evaluate(model, val_loader) scheduler.step(val_loss) # 验证损失不降则自动减半学习率注意scheduler.step要传入验证损失,因为ReduceLROnPlateau监控的是验证集指标而非训练集。这是很多人容易忽略的细节:调度器如果踩在训练损失上,基本没意义,因为训练损失总是降的。学习率衰减的 patience 设 5,意味着连续 5 个 epoch 验证损失没刷新最低记录,就把学习率乘以 0.5,给模型一个“精细调整”的机会。
4. 训练与评估:别被回测曲线骗了,高分项目的高分从哪来
4.1 损失函数与优化器选择:回归预测不是分类
股票价格预测通常是回归任务,最常用的是均方误差(MSE),公式是预测值和真实值差的平方的平均。MSE 对大误差有很强的惩罚,这既是优点也是缺点——LSTM 训练时如果某一天价格突然暴涨暴跌,个别大误差会让损失剧烈波动。因此也有人用平均绝对误差(MAE)或者 Huber Loss,后者结合了两者特性。PyTorch 里可以直接用nn.MSELoss或nn.HuberLoss。
优化器我基本只用 Adam,因为它在梯度稀疏和噪声大的场景下表现稳定。需要注意的是 weight decay(L2 正则)不要设太高,常见做法的1e-4到1e-3之间。股票数据本身噪声大,不加正则化很容易把训练集背得滚瓜烂熟,加多了模型又会变得过于平滑,连趋势都拟合不出来。我一般固定weight_decay=1e-4。
训练代码要写好批量迭代和梯度清零,这是 PyTorch 初学者的高频翻车点:
def train_one_epoch(model, optimizer, data_loader, loss_fn): model.train() total_loss = 0 for X_batch, y_batch in data_loader: optimizer.zero_grad() # 清空上一步梯度 y_pred = model(X_batch) # 前向传播 loss = loss_fn(y_pred, y_batch) # 计算损失, y_batch 需要 reshape 成和 y_pred 一致 loss.backward() # 反向传播 optimizer.step() # 更新参数 total_loss += loss.item() return total_loss / len(data_loader)特别注意y_batch的形状。nn.Linear输出形状是(batch, 1),而标签形状可能是(batch,),直接算 MSE 时 PyTorch 会广播,但容易出错。最好在构造数据集时就把标签 reshape 成(batch, 1),或者用y_batch.view(-1, 1)。
4.2 评估指标:用 RMSE、MAE 和方向准确率判断模型好坏
很多课程设计项目只画一条“预测值 vs 真实值”的折线图,看起来贴合得不错,然后宣称“准确率达到 95%”。这其实是自欺欺人,因为价格预测的误差只要不超过几个点,肉眼看起来就高度重合。我评估时序预测模型时必看三个指标:
- RMSE:均方根误差,单位和价格一致。比如 RMSE 为 2.5 元,代表平均预测偏差 2.5 元。
- MAE:平均绝对误差,更接近人直觉,和 RMSE 的差距能反映误差分布是否有极端值。
- 方向准确率:预测涨跌方向(今天预测明天涨,明天实际是否涨)的正确比例。这个指标才是对交易最有意义的,但往往被忽略。
方向准确率的计算很有讲究。即使模型预测的数值偏差很大,只要方向对,就能赚钱;反过来,数值贴得很紧但方向错了,实盘照样亏。一个能用的方向准确率应该在 52%~55% 以上(对 A 股这种接近随机的市场,51% 已经不算差),如果只有 48%~50%,说明模型基本没学到方向信息,只能当预测均值用。
下面是一个简单评估函数:
def evaluate_model(model, data_loader): model.eval() preds, trues = [], [] with torch.no_grad(): for X_batch, y_batch in data_loader: y_pred = model(X_batch) preds.append(y_pred.numpy().flatten()) trues.append(y_batch.numpy().flatten()) preds = np.concatenate(preds) trues = np.concatenate(trues) rmse = np.sqrt(np.mean((preds - trues) ** 2)) mae = np.mean(np.abs(preds - trues)) # 方向准确率:忽略相等的情况 direction_pred = np.sign(np.diff(preds)) direction_true = np.sign(np.diff(trues)) direction_acc = np.mean(direction_pred == direction_true) return rmse, mae, direction_acc注意np.diff是相邻两个预测值的差,如果差为 0 则 sign 为 0,股票预测模型很少出现完全相同的连续预测,但最好过滤掉这些样本,否则会虚高。这个方向准确率的计算前提是预测序列和真实序列按时间对齐,并且是连续预测值,而不是单步预测后拼接的离散点。
4.3 训练过程监控:早停法与模型保存的后悔药
训练 LSTM 就像煮一碗面,火候过了就糊了。神经元网络的深度学习训练中,常见现象是训练损失持续下降,验证损失先降后升,这就是过拟合的开始。我没有耐心每次手动盯着曲线,最有效的做法是早停:如果验证损失连续 N 个 epoch 没有创新低,就停止训练,并恢复到最后一次验证损失最低的模型权重。
这需要写一个“模型保存 + 恢复”的流程,也是项目里经常缺的一块。没有早停,最终保存的往往是最后一个 epoch 的模型,而不是验证集上表现最好的那个。这就像考试成绩最后关头没发挥好,却拿期末成绩当最终分数。代码如下:
best_val_loss = float('inf') patience = 15 wait = 0 for epoch in range(100): train_loss = train_one_epoch(...) val_loss = evaluate(...) if val_loss < best_val_loss: best_val_loss = val_loss torch.save(model.state_dict(), 'best_model.pt') # 保存最优权重 wait = 0 else: wait += 1 if wait >= patience: print(f"Early stop at epoch {epoch}") break # 训练结束后加载最优模型 model.load_state_dict(torch.load('best_model.pt'))这是一个典型的“后悔药”设计:每次验证损失刷新最低值就保存一份快照,后续哪怕模型继续训练过拟合了,还能回滚到最优状态。patience=15意味着最多允许 15 个 epoch 不进步。这个值在股票预测任务里比较合理,因为验证损失本来就有随机波动,太小像 5 可能把进行一次正常波动误判为停滞,太大会浪费训练时间。
这里还有个细节:保存模型时只保存state_dict,不要保存整个model对象,因为重建模型结构后加载权重更灵活,而且文件更小,也不容易因为 PyTorch 版本不同而报错。
5. LSTM 预测模型的常见坑与排查:从数据泄漏到预测值平移
5.1 数据泄漏:归一化时用全量统计量是最隐蔽的坑
现象:测试集上的 RMSE 比训练集还低,模型“完美”预测未来行情,实盘却完全失效。
原因:数据归一化时对整个数据集调用了scaler.fit(features)。MinMaxScaler 在计算最大值最小值时,已经包含了测试集的价格范围,相当于把测试集的最高价、最低价信息偷偷告诉了模型。训练时模型看到的输入分布里混入了未来信息,所以它学到的“规律”里包含了对未来数据的记忆。
解决:按时间顺序先切训练、验证、测试,然后只对训练集做fit,再用同样的 scaler 转换验证集和测试集。代码在第 2.3 节已经给出,这是最简单的修复。另外要检查是否误用了shuffle=True在时间序列上下文中。DataLoader 里千万别开shuffle=True,否则训练集和验证集的数据会被打乱,时间顺序完全破坏。
5.2 预测值滞后:为什么模型输出的曲线总是比真实值“慢半拍”
现象:预测曲线和真实曲线形状非常相似,但明显向右平移,即真实值涨到高点后,预测值才跟着往上涨;真实值跌了,预测值还维持原样。这样的模型看起来“贴合度极高”,其实只是把昨天的价格搬到了今天。
原因:这是纯回归模型在随机数据上的必然现象。因为股票价格接近随机游走,最好的回归预测(最小化 MSE)就是预测条件均值,而条件均值在无明确趋势时最接近上一个观测值。LSTM 学到的最优策略就是“复制上一个时刻的价格”。因此预测值等于前一日收盘价加上一个小修正,曲线自然滞后一天。
解决:不要再用 RMSE 作为唯一指标,加入方向准确率。如果方向准确率只有 50% 左右,说明模型本质是“昨天价格预测法”。可以尝试改变预测目标——不直接预测价格,而是预测价格差分(即涨跌幅),这样模型不能依赖“复制上一个价格”,被迫学习涨跌模式。代码上只需要把标签从close[t]改成close[t] - close[t-1],预测后再加回基准价格。这个简单变更通常能让方向准确率有明显提升。
5.3 过拟合与欠拟合:训练损失降了,测试却一塌糊涂
现象:训练损失很低,验证和测试损失高得离谱,或者训练损失一直不降。
原因:过拟合是因为模型容量太大、训练数据太少,或者循环训练了太多 epoch。欠拟合则相反——隐藏层太小、序列长度太短、模型没有学到足够模式。还有一类特殊情况是梯度爆炸或梯度消失,LSTM 虽然比普通 RNN 好些,但多层堆叠后深层梯度仍可能异常。
解决:先看训练曲线。如果训练损失和验证损失都在下降但差距大,是过拟合,对策依次为:减小 hidden_size、减少 num_layers、增大 dropout、增加 weight_decay、加早停。如果训练损失本身就不降,是欠拟合或学习率问题,先调低学习率试几个 epoch;如果仍然不降,增大 hidden_size 和 seq_len。还有一个我常用的快速排查:先拿一小段训练数据(比如 100 个样本)跑通一轮,看模型能不能把这一批数据过拟合到损失基本为 0。如果不能,说明代码有 bug——比如梯度没清零、标签形状不对、归一化有 NaN。
5.4 股票涨跌随机性:当模型告诉你明天涨,你该怎么办
现象:模型在测试集上方向准确率 53%,看似比随机好一点,但一实盘就亏,手续费和滑点吃掉了收益。
原因:股票市场接近弱式有效。LSTM 模型能捕捉到的“规律”往往非常微弱,而且会在不同时间段失效。课程设计项目里的回测是静态的——用过去的数据测试模型,测完就结束。但真实市场是动态的,模型训练时的规律可能在下个月就不存在了。
解决:调低预期。在做这类预测模型时,我会把目标设定为“比随机略好”而不是“必赚”。你可以用滚动回测来验证稳定性:训练集每次向前滚动 20 个交易日,重新训练模型,再预测下 20 个交易日,重复多次,看方向准确率是否稳定。如果只在某一段特定行情里有效,那基本说明模型只是在拟合历史记忆。另外,严格把交易成本计入模拟——每次预测涨了就买入,跌了就空仓,假设每次买卖手续费 0.1%,滑点 0.05%,看看最终收益是否仍为正。大部分课程项目做到这里就会现原形。
6. 把模型用在基金预测上:迁移要点与一个可落地的验证技巧
6.1 从股票到基金:数据频率、复权与净值处理的差异
很多高分项目会同时演示股票和基金预测,但直接从股票迁移到基金会踩数据坑。基金净值不像股票有分钟级或日级高频数据,普通开放式基金一天只有一个单位净值,样本量小。而且基金净值已经经过平滑处理,涨跌波动更小,LSTM 模型会学得更“懒”——直接预测净值持平,损失也能控制在很小的范围。我一般会改用周频数据,扩大时间跨度,或引入指数对比基准作为额外特征。还要注意分红和拆分:股票用前复权价格,基金净值要用累计净值或者把分红再投资处理,否则会出现净值断崖式下跌,模型误以为学到了暴跌规律。
6.2 验证技巧:用滚动回测替代一次性划分,看稳定性
前面提过滚动回测是评估时序预测模型的更好方式。这里给出一个具体实现思路:把完整数据集分为若干段,每次用前 80% 的数据训练,后 20% 预测,然后整体向后滑动 20 个交易日,重复 5 次。记录每次的 RMSE、方向准确率和模拟收益。如果多次结果的标准差很小,说明模型稳定;如果第一次效果很好、之后效果变差,说明模型只是过拟合了某段行情。
def rolling_backtest(features, target, model_fn, seq_len=60, step=20, n_folds=5): results = [] total_len = len(features) start = 0 for i in range(n_folds): train_end = start + int(total_len * 0.6) # 每次只取固定比例作为训练 test_end = train_end + step train_data = features[start:train_end] test_data = features[train_end:test_end] # ... 这里执行归一化、滑窗、训练、预测 ... # 记录 rmse, direction_acc results.append((rmse, direction_acc)) start += step if test_end >= total_len: break return np.array(results)这个函数的参数一概按需求调整。要点是每次只在训练段上做归一化,绝不能把 test 段的信息混进 scaler。如果滚动 5 次的结果差异太大,我会回头检查特征,比如某种技术指标在不同行情下是否失效。
6.3 进阶:多因子输入与注意力机制,是否值得加
如果你已经完成了基础 LSTM 预测模型,想让它更像一个“高分项目”,可以往两个方向加东西。一是多因子输入:不止用 OHLCV,还可以加入技术指标如 MACD、RSI、布林带,甚至加入其他股票或指数的走势特征,让input_size从 8 变成十几。这会增加模型表达能力,但也要注意特征之间的量纲差异,归一化必须分别处理。
二是注意力机制:在 LSTM 的输出上叠加一个 Attention 层,让模型对序列中更重要的时间步赋予更高权重。比如“放量突破”那天,注意力权重会集中在突破时段。PyTorch 实现注意力不算难,但在股票预测上,注意力带来的提升往往有限,因为有效规律本身就弱。我的建议是:先把基础模型做扎实,如果提升方向准确率遇到瓶颈,再考虑注意力,这样项目更有层次感,也不会因为过度复杂而难以答辩。
我自己的习惯是每轮实验都先把随机种子固定住,再把数据划分文件存成 CSV,这样不同模型之间对比才公平。很多项目翻车,不是因为模型不好,而是因为每次跑数据切分都不一样,把随机性当成了模型能力。这个教训让我在做任何时序预测模型时都先把数据流固定,再谈调参。希望帮到你。
本文还有配套的精品资源,点击获取