news 2026/10/19 7:38:33

DNN、LSTM与CNN实现时间序列预测的实战指南与调参经验

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DNN、LSTM与CNN实现时间序列预测的实战指南与调参经验

做时间序列预测这几年,我踩过不少坑。从最初只会拿ARIMA硬怼,到后来把DNN、LSTM、CNN这套深度学习组合拳打熟,中间经历了不少试错。今天这篇就把我实际用DNN、LSTM、CNN做时间序列预测的完整思路、代码实现、调参经验和踩坑记录整理出来,给正在入门或者已经上手但总感觉差点意思的朋友一份能直接“抄作业”的参考。

先说结论:深度学习模型做时间序列预测,不是玄学,但有门槛。门槛不在于模型本身有多复杂,而在于你对数据理解得够不够透、对模型选择是否合理、对训练细节是否敏感。这篇文档我会从一个完整的实战项目切入,把从数据预处理到模型训练、评估、调优的全流程讲清楚。

1. 项目整体设计与模型选型思路

1.1 为什么用深度学习做时间序列预测

传统的时序预测方法,比如ARIMA、指数平滑这些经典统计模型,在平稳序列或者有明显趋势、季节性规律的序列上表现不错。但一旦数据量大了、特征维度多了、非线性关系复杂了,传统方法就开始力不从心。举个例子,你预测一个商场未来一周的客流量,影响因素可能包含促销活动、天气状况、节假日、周边交通等等,这些因素和客流量的关系往往是非线性的、耦合的,用统计模型很难建模。

深度学习模型的优势就在这。DNN可以用多隐藏层学习特征之间的高维非线性组合;LSTM天然适合处理具有时间依赖性的数据,能学习序列中的长短期模式;CNN则擅长提取局部特征,对周期性、趋势性变化有很好的敏感度。在实际项目中,我通常不是单一使用某一个模型,而是根据数据特征和业务需求,选择最合适的那个,或者做模型集成。

1.2 三种模型的核心差异与适用场景

模型核心优势适用场景典型不足
DNN结构简单、训练快、适合纯回归映射多变量预测、特征与目标无强时序依赖完全忽略时序顺序,容易丢失上下文信息
LSTM记忆单元结构设计精巧,擅长长序列依赖建模股票价格、气象数据、流量预测等强时序数据训练慢、参数量大、容易过拟合,对数据量要求高
CNN(1D)卷积核能自动提取局部模式,训练并行度高传感器信号、周期性明显的序列数据对序列位置不敏感,需要配合合适的卷积核尺寸

说实话,这三者的选择不是“谁取代谁”的关系。我见过不少新手一上来就上LSTM,觉得“既然LSTM是最强时序模型,那用它就对了”,结果数据量不够,模型收敛得稀烂,效果还不如一个简单的Gradient Boosting模型。所以我一直强调:模型选型先看数据,再看任务。

1.3 从业务问题到建模方案的拆解方法

拿到一个时间序列预测任务,我建议先按这四步走:

  1. 明确预测目标:是预测下一时刻的值,还是未来N天?单步预测还是多步预测?这决定了你的标签怎么构建。
  2. 考察数据质量:有没有缺失值?有没有异常尖峰?采样间隔是否均匀?这些都是后续处理的先决条件。
  3. 检查时序依赖性:把历史数据画出来,看看自相关图(ACF/PACF),初步判断序列是平稳的还是带趋势的、带季节性的。
  4. 确定评估方式:不能用随机划分训练集和测试集,必须按时间顺序切分。这一点太多人栽跟头了,后面我会单独说。

2. 数据准备与预处理实操

2.1 数据采集与清洗规范

无论是做实验还是做业务落地,数据的质量直接决定模型的上限。我自己过了一遍完整流程,发现最容易出错的反而不是模型代码,而是数据预处理这几步。

缺失值处理:对时间序列数据,不建议用均值填充。因为时序数据往往有自相关性,用前向填充(ffill)或者插值法更合理。比如传感器某时刻数据丢失,用前一秒的值填充,比用全天平均值填充要靠谱得多。

异常值检测:别一上来就用Z-score那种硬阈值方法。我通常先用滑动窗口计算局部均值和标准差,如果某个点偏离窗口均值超过3倍标准方差,再结合业务场景判断是真实波动还是噪声。比如在流量预测中,双十一当天的流量可能是平时的10倍,这必须是真实数据,不能当异常去掉。

重采样与对齐:多源数据融合时,不同数据源的采样间隔可能不同,需要统一重采样到同一频率。建议先用低频对齐高频,避免数据信息丢失。

2.2 滑窗法构建训练样本

这里要重点讲一下滑窗法。深度时序预测的基本训练方式是:用过去lookback步的数据预测未来horizon步的值。这个概念看起来简单,但窗口长度的选择很有讲究。

拿我做过的一个电力负荷预测项目举例。原始数据是每15分钟一个采样点的电力负荷,一天就是96个点。我要预测未来24小时(即96个点)的负荷曲线。如果直接把lookback设成96,那模型只能看到前一天的96个点,很可能学不到“上周同一天”这种周期性特征。后来我把lookback设为672(一周的96×7),模型预测精度明显提升。

这里有个经验公式供参考:

lookback = (预测周期数 + 需要考虑的历史周期数) × 单周期点数

比如,数据有日周期性,你想预测未来24小时,同时需要考虑过去7天的同期数据,那lookback建议设为(1 + 7) × 96 = 768。

窗口构建的Python代码可以这样写:

import numpy as np def create_sequences(data, lookback=96, horizon=96): X, y = [], [] for i in range(lookback, len(data) - horizon + 1): X.append(data[i - lookback:i]) y.append(data[i:i + horizon]) return np.array(X), np.array(y)

提示:这里X的形状是(样本数, lookback, 特征数),y的形状是(样本数, horizon)。LSTM要求输入为这种三维格式,DNN则可以把X展平成一维。

2.3 归一化与数据泄漏的坑

数据归一化用Min-Max还是StandardScaler?我的建议是:如果数据分布比较稳定,Min-Max就够用;如果存在较大离群点,用StandardScaler会更稳。

但最关键的坑在于:归一化参数只能用训练集的统计量,不能用全量数据拟合。我见过有人图省事,直接把整条序列拿去做归一化,得到的模型在测试集上表现虚高,一上线就崩。这就叫数据泄漏。

正确做法:

from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler(feature_range=(0, 1)) train_values = scaler.fit_transform(train_data.reshape(-1, 1)) test_values = scaler.transform(test_data.reshape(-1, 1))

注意fit_transform只对训练集执行,测试集只调用transform。推理阶段的新数据也一律用训练好的scaler,不能重新fit。

3. 三种模型的架构设计与代码实现

3.1 DNN模型搭建与全连接层设计

DNN实现时间序列预测的核心思想是:把滑窗内的序列数据作为特征,用全连接层做非线性映射,直接输出预测值。DNN的优势在于结构简单、训练速度快,适合做基线模型。

一个标准的DNN时序预测模型可以这么写:

import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Dropout, Flatten def build_dnn(lookback=96, n_features=1, horizon=96): model = Sequential([ Flatten(input_shape=(lookback, n_features)), Dense(256, activation='relu'), Dropout(0.3), Dense(128, activation='relu'), Dropout(0.2), Dense(horizon) ]) model.compile(optimizer='adam', loss='mse', metrics=['mae']) return model

DNN模型虽然结构简单,但有几点需要注意:

  • Flatten层:将(lookback, n_features)的输入展平成(lookback × n_features,)的向量。这一步是必须的,因为Dense层只接受二维输入。
  • Dropout层的设计:Dropout比例不能太大,0.2~0.3比较合适。太大可能导致模型欠拟合,尤其是数据量本身不大的时候。
  • 输出层:horizon是多少,输出层神经元就是多少。如果做单步预测,输出层神经元就是1。

DNN模型我通常拿来当baseline。有了baseline之后,你才能评估LSTM/CNN是否真的带来了收益。如果LSTM的表现还不如DNN,你先别急着调参,大概率是数据处理环节出了问题。

3.2 LSTM模型搭建与记忆单元机制

LSTM能在时序预测中表现优异,核心在于它的记忆单元结构。简单来说,LSTM有三个门:遗忘门、输入门、输出门。遗忘门决定保留多少历史信息,输入门决定新信息如何写入,输出门决定当前状态如何输出。这套机制使得LSTM能够在长序列中有效避免梯度消失问题。

一个标准的LSTM时序预测模型可以这么写:

from tensorflow.keras.layers import LSTM def build_lstm(lookback=96, n_features=1, horizon=96): model = Sequential([ LSTM(64, input_shape=(lookback, n_features), return_sequences=False), Dropout(0.2), Dense(32, activation='relu'), Dense(horizon) ]) model.compile(optimizer='adam', loss='mse', metrics=['mae']) return model

如果你想要堆叠多层LSTM,需要把前面层的return_sequences设为True,最后一层LSTM设为False:

def build_stacked_lstm(lookback=96, n_features=1, horizon=96): model = Sequential([ LSTM(64, input_shape=(lookback, n_features), return_sequences=True), Dropout(0.2), LSTM(32, return_sequences=False), Dropout(0.2), Dense(horizon) ]) return model

LSTM实战中,我最常被问到的问题有三个:

第一,LSTM单元数怎么定?我的经验是:第一层LSTM单元数从32或64开始,如果数据量大、序列长,可以考虑128。单元数加倍时,参数量会呈平方增长,训练速度下降很快,效果未必线性提升。

第二,为什么LSTM的训练很慢?LSTM需要逐步处理序列的每个时间步,这是其结构决定的。如果训练速度成为瓶颈,可以考虑改用GRU。GRU参数量更少,效果通常相差不大。

第三,LSTM在数据量少的时候容易过拟合怎么办?回调函数中设置EarlyStopping是必须的,另外可以增大Dropout比例到0.3~0.4。还有一个小技巧:对LSTM的输入加一些高斯噪声(GaussianNoise(0.01)),在训练时有正则化效果,实测有效。

3.3 CNN模型搭建与一维卷积核设计

不少人以为CNN只能处理图像,其实一维卷积(Conv1D)在时序预测中非常实用。CNN的思想是通过滑动卷积核提取序列中的局部模式,比如连续几小时的流量变化、连续几天的趋势等。这些局部特征被卷积核捕捉后,再由全连接层映射成预测值。

一个标准的一维CNN时序预测模型可以这么写:

from tensorflow.keras.layers import Conv1D, MaxPooling1D, GlobalAveragePooling1D def build_cnn(lookback=96, n_features=1, horizon=96): model = Sequential([ Conv1D(filters=64, kernel_size=6, activation='relu', input_shape=(lookback, n_features)), MaxPooling1D(pool_size=2), Conv1D(filters=32, kernel_size=3, activation='relu'), GlobalAveragePooling1D(), Dense(horizon) ]) model.compile(optimizer='adam', loss='mse', metrics=['mae']) return model

这里有几个关键的参数值得琢磨:

  • kernel_size(卷积核大小):决定了每次卷积覆盖的时间步数。如果数据是日级别的,kernel_size=3就能覆盖3天;如果是小时级别的,kernel_size=6覆盖6小时。核大小的选择应该和数据粒度匹配,不要用固定的6去套所有数据。
  • filters(卷积核数量):相当于特征提取器的个数。通常是64起步,层数加深时可以适当减少。
  • MaxPooling1D:在卷积之后对局部特征做下采样,降维的同时保持主要特征。池化窗口为2时,序列长度减半。
  • GlobalAveragePooling1D:这一步很关键,它把卷积输出的特征图压缩成一个向量,避免了直接把特征图展平导致参数量过大的问题。

CNN在时序预测中一个常见的误区:把Conv1D当成了“银弹”,以为只要卷积核堆得足够多,模型就一定能提取到好的特征。实际上一维卷积的视野范围受限于kernel_size,它擅长捕捉局部模式,但对长距离依赖关系并不敏感。如果你发现预测结果对长时间跨度的周期性变化不敏感,可以适当增大kernel_size,或者堆叠多层卷积扩大感受野,也可以考虑把LSTM和CNN组合起来。

4. 训练策略与参数调优

4.1 数据划分与评估指标的选择

时序预测中,训练集、验证集、测试集的划分必须严格按时间顺序进行,并且不能打乱。我自己习惯的划分方式如下:

  • 训练集:前70%~80%的数据,模型在这部分数据上学习模式。
  • 验证集:训练集之后的10%~15%数据,用于调参和早停。
  • 测试集:最后10%~15%数据,用于最终评估模型泛化能力。

划分代码可以这样写:

train_end = int(len(data) * 0.7) val_end = int(len(data) * 0.85) train_data = data[:train_end] val_data = data[train_end:val_end] test_data = data[val_end:]

关于评估指标,做回归预测一般看MAE(平均绝对误差)和RMSE(均方根误差)。RMSE对大误差的惩罚更重,适合需要避免严重偏差的场景;MAE更贴近真实业务意义的平均偏差。

我做过一个能耗预测项目,业务方最关心的其实是“今天预测的能耗和实际能耗差多少度”,这种情况用MAE就比RMSE更好解释。但在某些金融风控场景,大误差的代价极其昂贵,用RMSE会更合理。

4.2 损失函数与优化器的选择

时序回归任务中,默认的损失函数通常是mse(均方误差)。但在某些业务场景,可以考虑更贴合业务目标的损失函数:

  • 如果数据中存在大量离群点,mae作为损失函数更鲁棒,但训练时梯度变化相对平缓,收敛可能更慢。
  • 如果预测值和真实值的量级跨度大,先对数据做对数变换再进行MSE回归,效果往往比直接回归更好。

优化器方面,我个人最常用Adam,初始学习率1e-3。如果你发现训练前期损失下降很快,但到后期震荡明显,可以试试把学习率降到5e-4或1e-4,或者用ReduceLROnPlateau回调:验证集损失连续若干轮不下降时,学习率自动乘以0.5。

from tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping callbacks = [ EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True), ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, min_lr=1e-6) ]

4.3 Batch Size与Epoch的实践经验

关于batch_size,我见过有人用16、32、64、128都试过,最后发现64通常是个不错的默认值。小batch可以让模型训练更稳定,但速度慢;大batch可以加速训练,但可能陷入尖锐极小值,泛化能力略差。

我自己实验的经验:LSTM对batch_size比较敏感,偏大的batch_size可能导致LSTM“记不住”长序列信息。CNN则相对没那么敏感。

epoch数不能固定,务必配合EarlyStopping。耐心值(patience)设10到15比较合适,太小的耐心容易在损失还在下降时提前停止。

5. 项目实操全流程演示

5.1 完整代码流程:从数据到预测

为了让你能直接跑起来,我整理一个完整的流程示例。假设我这里有一份按小时采样的一维序列数据,放在data.csv里,内容是单列数值。

import numpy as np import pandas as pd from sklearn.preprocessing import MinMaxScaler from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Dropout, LSTM, Conv1D, MaxPooling1D, Flatten from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau # 1. 读取数据 df = pd.read_csv('data.csv', parse_dates=['ds'], index_col='ds') values = df['y'].values.reshape(-1, 1) # 2. 按时间顺序划分 train_end = int(len(values) * 0.7) val_end = int(len(values) * 0.85) train_values = values[:train_end] val_values = values[train_end:val_end] test_values = values[val_end:] # 3. 归一化 scaler = MinMaxScaler() scaler.fit(train_values) train_scaled = scaler.transform(train_values) val_scaled = scaler.transform(val_values) test_scaled = scaler.transform(test_values) # 4. 构建滑窗数据 def create_sequences(data, lookback, horizon): X, y = [], [] for i in range(lookback, len(data) - horizon + 1): X.append(data[i - lookback:i]) y.append(data[i:i + horizon]) return np.array(X), np.array(y) lookback, horizon = 168, 24 X_train, y_train = create_sequences(train_scaled, lookback, horizon) X_val, y_val = create_sequences(val_scaled, lookback, horizon) X_test, y_test = create_sequences(test_scaled, lookback, horizon) # 5. 构建模型 model = Sequential([ LSTM(64, input_shape=(lookback, 1), return_sequences=True), Dropout(0.2), LSTM(32, return_sequences=False), Dropout(0.2), Dense(24) ]) model.compile(optimizer='adam', loss='mse', metrics=['mae']) # 6. 训练 history = model.fit( X_train, y_train, validation_data=(X_val, y_val), epochs=100, batch_size=64, callbacks=[early_stopping, reduce_lr], verbose=1 ) # 7. 预测与反归一化 y_pred = model.predict(X_test) y_pred_inverse = scaler.inverse_transform(y_pred.reshape(-1, 1)).reshape(y_pred.shape) y_test_inverse = scaler.inverse_transform(y_test.reshape(-1, 1)).reshape(y_test.shape) # 8. 评估 from sklearn.metrics import mean_absolute_error, mean_squared_error mae = mean_absolute_error(y_test_inverse.flatten(), y_pred_inverse.flatten()) rmse = np.sqrt(mean_squared_error(y_test_inverse.flatten(), y_pred_inverse.flatten())) print(f'MAE: {mae:.4f}, RMSE: {rmse:.4f}')

这个代码在单变量序列上可以直接运行。如果你的场景是多变量,把(lookback, 1)改成(lookback, n_features)即可,数据拼接时注意多个特征列的堆叠顺序即可。

5.2 训练过程的观察要点

训练过程中的loss曲线非常关键。凭我个人的经验,要注意以下三类现象:

  • 训练loss和验证loss都在缓慢下降,但差距不大:正常,让训练继续。
  • 训练loss下降正常,验证loss早早就开始反弹:过拟合了,调大Dropout、减小模型容量或者提前停止。
  • 训练loss几乎不动:可能学习率太低或者模型架构有问题。先检查数据有没有归一化、梯度有没有正常传播。

我每次训练都会画loss曲线来观察这些现象,这比单纯看最终的评估指标要有用得多。因为你至少能判断模型有没有在学、在朝哪个方向学。

5.3 两种合理的多步预测策略

上面代码用的是直接多步预测,即模型一次性输出未来24个时间步的值。这种方式实现简单、训练效率高,但预测误差会沿时间步累积。

另一种方法是递归多步预测。先训练一个单步预测模型,预测出下一时刻后,把预测值拼接到输入序列末端,再预测下下个时刻。这种方式的优势在于不依赖固定的horizon,但误差会随时间步长累积,越往后越不准。

我的建议是:如果horizon比较短(比如12~24步之内),用直接多步预测;如果预测周期很长,可以考虑用seq2seq架构或者生成式的方法,比如用Teacher Forcing策略训练,效果会更好。

6. 常见问题与排查技巧实录

6.1 模型预测结果“平移”失真问题

很多人,包括我自己,都遇到过这么一个现象:预测曲线和真实曲线形状几乎一样,但整体滞后了一段。也就是说,预测曲线看起来像是真实曲线的“右移版本”。

这个问题的根源通常是序列的自相关性太强,模型学到了一个最简单的解法:“把上一个时间步的值当作当前时间步的预测”。尤其在序列变化缓慢、噪声较小的场景下,这种现象尤其明显。

排查思路:

  • 检查预测值和真实值的Correlation是否极高,且MAE相对序列本身的幅度很小。如果是,基本可以判定模型在“抄近路”。
  • 尝试增加lookback,让模型看到更长的上下文。
  • 对序列做差分处理,把原始序列转换成“增量序列”再进行预测。比如预测明天的值先预测明天相对今天的增量,最后再把增量加回去。

差分处理代码示例:

diff_values = np.diff(values.flatten())

模型对差分序列进行训练和预测,得到预测增量后,用np.cumsum还原成原始尺度的预测值。

注意:差分会放大噪声对预测结果的干扰。数据本身噪声较大时,建议先做平滑(比如简单移动平均),再做差分。

6.2 LSTM训练过程中Loss出现NaN

NaN问题在LSTM训练中出现得不少。常见原因有这几个:

  • 学习率过大。Adam默认1e-3一般不导致NaN,但如果你手滑设成了0.1,梯度爆炸在所难免。降低学习率到1e-4再试。
  • 数据中有NaN或Inf。检查滑窗后X_train和y_train中是否存在非有限值。
  • 梯度爆炸。给模型加梯度裁剪可以兜底。Keras里可以用optimizer=tf.keras.optimizers.Adam(clipvalue=1.0)来限制梯度值范围。

我的习惯是在model.compile之前先做一个快速检查:

assert np.isfinite(X_train).all() assert np.isfinite(y_train).all()

这个小动作能帮你排除掉一半的NaN问题。

6.3 CNN模型对数据顺序敏感性的处理

CNN在时序预测中的一个天然弱点是:卷积核在特征提取时对“顺序”不敏感。你看看卷积核的工作方式,它是在局部窗口内加权求和,更关注的是窗口内模式的出现,而不是模式出现的精确位置。这对于某些任务来说是好事(比如平移不变性),但对严格依赖时间顺序的任务可能不合适。

如果你发现CNN模型的结果和LSTM差距很大,可以考虑两个方向:

  1. 调整kernel_size:让卷积核覆盖更符合业务周期的时间跨度。比如预测星期级的周期,kernel_size=7比kernel_size=3更合适。
  2. CNN + LSTM的混合模型:先用CNN提取局部特征,再把特征序列输入LSTM建模长依赖。这种结构在不少文献里被称为“卷积LSTM”的变种,在长序列预测中常常稳压单个模型。

混合模型的构建逻辑如下:

model = Sequential([ Conv1D(filters=64, kernel_size=7, activation='relu', input_shape=(lookback, n_features)), MaxPooling1D(pool_size=2), LSTM(32, return_sequences=False), Dropout(0.2), Dense(horizon) ])

6.4 训练集和测试集误差差异巨大的排查

如果训练集上表现很好,测试集上一塌糊涂,除了典型的过拟合之外,还有一种常见情况:验证集和测试集分布发生了偏移。比如你用历史训练好的模型去预测未来,但业务的真实环境已经变了(比如疫情前后客流量模式完全不同)。这种情况下,再强大的模型也无法凭空预测出从未见过的新模式。

要缓解分布偏移问题,有几个办法:

  • 定期重新训练模型,用最近的数据做增量训练。
  • 在训练集中保留一定比例的“近期数据”作为验证集,而不是用最早的近期数据。
  • 如果是业务环境突变,建议先人工研判,而不是盲目相信模型输出。

6.5 关于超参数调优的小结

深度时序预测的超参数,说来说去就那么几个:lookback、horizon、层数、单元数、dropout、学习率、batch_size。但真正决定效果的往往不是单点超参的最优值,而是数据预处理和特征工程。

我试过用keras-tuner做网格搜索,在 300 组参数里选了最好的一组,结果只比手动调的默认参数提升了不到 3%。而把lookback从96改成672、加上差分特征之后,误差直接下降了20%。这个对比说明:先把数据层面的问题解决好,再谈模型调参才有意义。

7. 其他值得尝试的优化思路

7.1 多变量特征融合

如果你的历史数据不止一个序列,比如预测电力负荷时有温度、湿度、星期几、节假日标记等维度,建议作为一个整体输入模型。这种多变量输入对预测精度提升非常明显。

它其实是在模拟真实世界的复杂性:预测结果不仅取决于目标序列的历史值,还取决于相关的外部变量。落入滑窗时,每个特征列都对应滑窗内的一个通道,模型在卷积或LSTM处理时,会自动学习不同特征之间的交叉关系。

7.2 嵌入业务特征

星期几、是否为节假日这类特征,建议用嵌入(Embedding)层处理,而不要直接作为数值输入。否则“周日=7”“周一=1”这种数值排序会给模型带来误导性信息。我通常把这类特征转换成one-hot编码,再拼接到特征序列中。

7.3 模型集成

如果你的资源允许,最后可以做一个简单的加权集成。比如LSTM和CNN单独训练,验证集上LSTM的MAE为2.3,CNN的MAE为2.6,那么可以按0.6和0.4的权重进行加权组合。集成后的误差通常不会比最好的单模型差,甚至在多数情况下会更好。

8. 我在实际项目中的几点体会

回到最初的问题:用DNN、LSTM、CNN做时间序列预测,到底怎么选?我个人现在的判断标准非常简单——先跑DNN拿baseline,然后根据数据的时序依赖强度决定是否换LSTM或CNN。如果序列有强周期性且你只需要依赖局部模式,一维CNN往往速度最快、效果最稳。如果序列长且存在长期趋势依赖,LSTM值得一试。深度学习模型之间从来不是互相排斥的,组合起来的效果常常更好。

另外,代码本身占整个项目成功的比例真的不高。数据预处理的质量、训练验证的划分逻辑、模型输出的可视化检查,这些环节才真正决定了预测系统能不能落地。预测曲线一定要画出来看,不要只看数字指标。一个看似不错的MAE,画出来可能是一条“滞后版的真实曲线”,这种模型上线之后业务方是不会满意的。

最后想分享一个小技巧:模型训练完成后,不要只保存模型权重,最好连同预处理参数、训练配置一并保存。这样下次预测的时候,可以完全复现训练时的数据变换过程,不会因为归一化参数丢失导致预测结果对不上。用pickle把scaler和模型一起归档即可。

如果你想在时序预测这条路上走得更深,建议从单变量逐步扩展到多变量,从单步预测逐步走向多步预测,从单一模型走向混合模型。每一步都会有新的坑在等你,但这正是这个领域的乐趣所在。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 7:38:03

基于Django和Leaflet的地质野外记录与地图展示系统

简介:geolog-app 是一套基于 Python 与 Django 框架开发的地质类 Web 应用源码包,面向希望掌握 Django 项目结构、地质数据管理与可视化展示的开发者。压缩包共 22 个文件,包含 14 个 Python 脚本、2 个文本说明、1 个 HTML 模板、1 个 CSS 样…

作者头像 李华
网站建设 2026/10/19 7:35:20

2026年项目经理评职称必看:软考/建造师等证书对应层级一次说清

前不久在后台看到一条留言:非全日制本科、八年项目经验,手里只有PMP证书,想报中级职称,材料递上去被退回来了,原因是“证书不在目录内”。这条留言我印象很深,因为它代表了一大批项目经理的真实困境。很多做…

作者头像 李华
网站建设 2026/10/19 7:34:58

Linux网络配置:nmcli命令与ifcfg-*文件关联及避坑指南

搞 Linux 运维这些年,网络配置大概是新手最容易翻车、老手也偶尔头疼的一块。最常见的两个操作方式,一个是敲 nmcli 命令让 NetworkManager 干活,另一个是直接编辑 /etc/sysconfig/network-scripts/ 下面的 ifcfg-* 网卡配置文件。两条路都能…

作者头像 李华
网站建设 2026/10/19 7:34:00

Python深度学习入门实战:从环境搭建到图像分类全流程

“Python深度学习”这几个字放在一起的时候,不少人的第一反应是:又要学Python、又要补数学、还要看懂模型结构,门槛是不是太高了?我在这个方向折腾了几年,从照着教程跑MNIST都跑不明白,到后来独立负责一套图…

作者头像 李华
网站建设 2026/10/19 7:33:24

医疗影像分割中SAM如何把病灶边界做得更精细

去年有个项目要做肺结节风险分级前的病灶分割,某医院给了一批边界极不规则的亚实性结节影像。UNet系列、DeepLab系列我前后试过一圈,医生反馈永远是“肿瘤是圈出来了,但边界就像用蜡笔画的,很多细小的分叶和毛刺都抹平了”。后来我…

作者头像 李华
网站建设 2026/10/19 7:32:42

VirtualWife:本地化Live2D+LLM虚拟人直播框架

简介:VirtualWife是一个开源的虚拟数字人项目,面向AI开发者、直播技术实践者及AIGC应用探索者,旨在降低B站虚拟直播的技术门槛,提供可快速部署、可定制的本地化数字人交互方案。资源包共246个文件,涵盖97个Python核心逻…

作者头像 李华