开头可以先抛出场景问题:传感器时序数据缺失、脏数据对后续分析的影响,然后引出这套组合清洗模型,说明它能做什么、适合谁。
1. 这套清洗模型要解决什么问题
做过工业设备监测、电力负荷预测或环境传感数据分析的朋友,应该都有过这样的体验:辛辛苦苦从现场采集回来的时序数据,打开一看,缺一大块,有的地方数值跳变得离谱。直接丢进LSTM或Transformer里训练,模型性能一塌糊涂;用简单的线性插值补一下,短缺口看着还行,长缺口或者数据本身波动剧烈时,补出来的形态完全是“假的”——均值对得上,但变化规律对不上。
我在这套代码里做的事情,简单说就是:针对含有缺失值、异常跳变和局部噪声的时序数据,设计了一个多阶段数据清洗与填补流程。核心结构是“K均值聚类 + KNN-LSTM-RF 三重填补器”:先用K均值聚类把整个时间序列按运行状态划分成不同片段,再对每个片段分别调用KNN(局部相似匹配)、LSTM(时序长期依赖学习)和RF(随机森林回归)三种模型进行填补,最后按置信度加权融合得到最终填充值。代码完全基于Matlab实现,不依赖Python环境,输入原始时间序列和缺失标记,输出清洗后的完整序列,同时附带误差评估和可视化对比。
这套方案适合谁?如果你手头的数据是设备传感器日志、电网负荷曲线、气象站逐小时观测、金融分钟级行情这类带明显“分段特性”和“时序依赖”的数据,而且你已经受够了单一插值方法带来的粗糙填补效果,那这套模型可以作为你现有清洗流程的一个升级选项。即使你对LSTM不太熟悉,只要会基本的Matlab脚本操作,跟着代码走一遍也能跑通。
我先把整个模型的设计思路和关键代码讲清楚,再把我踩过的坑一起列出来。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 整体设计与思路拆解
2.1 为什么不是“单模型搞定”而是组合方案
先聊一个最根本的问题:为什么要用K均值+KNN-LSTM-RF这么一堆东西,不直接选一个模型做填补?
我早期做时序数据填补时,用的是单一LSTM。短缺失率5%时效果很好,RMSE很低;但一旦数据出现长段缺失(连续缺失几十个点)或者数据本身有多个明显不同的运行状态(比如设备正常、启停过渡、满负荷三种工况),单一LSTM在切换点附近的填补就非常拉胯——它倾向于用过去的模式外推,而状态切换后的数据规律和过去完全不同。
后来试过KNN补缺。这个方法思路是找最相似的“邻居序列段”来加权平均,对局部不规则缺失效果不错,但它的缺点是只看局部相似度,对长期趋势变化的感知很差。RF回归填补也是类似,虽然能通过特征工程弥补一部分时序信息,但对于强周期、强趋势的成分捕捉有限。
于是我把问题做了一个分层拆解:
- 先用K均值聚类对时间序列做“语义分段”,让不同运行状态的片段进入各自的局部模型。
- 在每个片段内部,用KNN负责“局部形态还原”,捕捉相似历史片段的细节形状。
- 用LSTM负责“时序动态拟合”,捕捉片段的先后依赖和趋势演进。
- 用RF负责“特征映射回归”,把能手工构造的时序统计特征和缺失点取值之间建立非线性关系。
- 最后用自适应权重把这三种填补结果融合起来。
这样做的直接好处是:不同填补器擅长的时间尺度不同,短板之间可以互补。
2.2 K均值聚类在这里的真正用途
很多文章会把K均值聚类放在数据清洗的“异常检测”环节里用——把离群点识别出来。但我这里K聚类的用途不太一样:它是为后续填补器做数据分片的。
时序数据常常不是一条平稳的单一模式,而是由若干个可区分状态的片段拼接而成。以设备振动数据为例:怠速段、加速段、稳定运行段、减速段,它们的幅值范围、波动频率、噪声特性都不同。直接在整个序列上训练一个LSTM,相当于让一个模型去记住多种完全不同的动态规律,模型容量被摊薄,梯度更新方向也会互相干扰。
K均值聚类的处理逻辑是:先把整个序列按窗口切段,对每个窗口提取统计特征(窗口均值、方差、峰值、过零率、斜率等),然后对这些特征向量做K均值聚类。完成后,同一簇里的窗口就是“同一个运行状态下的片段”。后续训练LSTM时,我们按簇分别建模——也就是对状态A训练一个LSTM,对状态B训练一个LSTM,以此类推。填补时先判断缺失窗口属于哪个簇,再用对应簇的模型去补值。
这里有一个细节值得说清楚:聚类用的窗口不要求与缺失位置严格对齐。实际实现里我用的窗口通常是64个时间步长,滑动步长可以设置成16~32,这样每个运行状态能产生多个重叠窗口,K均值聚类会更稳定。窗口太小,统计特征区分度不足;窗口太大,短时切换状态的片段会被淹没。
关于K值的选择,我用的方法是手肘法结合实际运行状态数来定。比如设备数据通常有2~4个典型工况,那K取3或4是合理的。如果你的数据没有明显分段特征,K取1相当于退化为“全序列统一建模”,所以K均值聚类不会让效果变差,它只是让模型有机会把复杂问题拆成简单问题。
2.3 KNN、LSTM、RF三种填补器的定位差异
三种填补器不是盲目堆叠,它们各自解决不同维度的问题:
KNN填补器本质上是个查表器。它的核心逻辑是:缺失点附近的局部形态,如果在历史数据中存在相似的形态,就用这些历史形态的对应位置值来加权平均。做法是把完整的历史序列切成长度为L的小段,对缺失段也切一个同样的长度(缺失点位于末端或中间),然后计算缺失段与历史段之间的欧氏距离(忽略缺失位置),选出距离最近的K个历史段,再用这些历史段在缺失位置的值做距离反比加权平均。它的特点是:填补值忠实于局部真实形态,不会凭空产生不存在的模式,但缺点是依赖历史库的覆盖度——历史里没出现过的新模式,KNN填补就很挣扎。
LSTM填补器是对时序动态的生成式建模。我用的是带滑窗监督方式的训练:把每个完整片段通过“前L个点预测后H个点”的方式构造训练样本。损失函数用均方误差(MSE)。预测时,如果缺失段在序列中间,我会从缺失段之前的最后一个已知点开始滚动预测,同时也从缺失段之后的第一个已知点反向滚动预测,得到两个方向的预测序列,再按距离加权合成。这样填补出来的数值在趋势连续性上很好,因为LSTM建模了长期的时序依赖,它知道你数据大致应该怎么走。缺点是短序列上容易过拟合,且训练计算量明显大于KNN和RF。
RF填补器走的是特征回归路线。思路是把问题转化成一个监督回归任务:对每个待填补位置,构造一个特征向量,比如当前时刻的周期位置、近期窗口的均值/方差/一阶差分、前后已知值的差值、上一时刻填补值(迭代式)等,然后训练随机森林回归模型,让模型学习从这些特征到真实值的映射。RF的好处是训练快、对特征尺度不敏感,能自动捕捉特征之间的非线性交互;缺点在于它对“序列本身形态”的表达能力有限,因为特征是人手工构造的,信息量上限取决于特征设计水平。
这三种模型各有侧重,最后用加权融合把它们综合起来。
2.4 融合策略:让每个模型在它擅长的地方多说两句
融合并不是简单取平均。如果三种模型精度差距大,等权平均反而会被差模型拖累。我用的是自适应置信度加权:先在验证集上模拟与
