3、数据预处理与清洗:缺失值处理、异常值检测、数据去重、时间戳对齐、数据标准化

各位同学,咱们今天聊点实在的。

数据预处理,说白了就是给数据「洗澡」。你从现场拿回来的储能数据,十个里面有八个是脏的。我做了这么多年储能系统,见过太多「数据很漂亮,一跑模型就崩」的案例。嗯,这里要敲黑板——预处理做不好,后面所有算法都是白搭。

核心观点:数据预处理不是「可选项」,而是「必选项」。它占整个数据融合工作量的 60% 以上。

3.1 缺失值处理

先说说缺失值。储能系统的数据采集,经常因为传感器故障、通信中断、存储溢出等原因,导致某些时间点的数据没记下来。你想想看,一个 BMS 上报的电压数据,突然跳了个空值,这怎么处理?

我个人习惯把缺失值分成三类:

  • 完全随机缺失:比如通信偶尔丢包,这种可以直接删掉或插值
  • 随机缺失:比如某个传感器温度过高导致暂时失效,这种需要谨慎处理
  • 非随机缺失:比如系统停机期间全部数据缺失,这种不能随便补

我在项目中遇到过最头疼的情况——某储能电站的 SOC 数据,每天凌晨 2 点到 4 点全部缺失。后来排查发现,是那个时段的定时校时任务把采集线程给阻塞了。这种缺失就不是随机事件,你如果用均值填充,模型会直接跑偏。

常用的处理方法,我列个表:

方法 适用场景 我的建议
删除法 缺失比例 < 5%,且随机缺失 简单粗暴,但别滥用
均值/中位数填充 数值型数据,波动不大 适合电压、温度等稳定指标
前向/后向填充 时间序列数据,变化缓慢 SOC 用这个效果不错
插值法 数据有趋势性变化 线性插值最常用,别搞太复杂
模型预测填充 缺失比例高,且关系复杂 慎用,容易过拟合

小技巧:处理缺失值时,我建议先画个缺失值分布图。用热力图一看,哪些时间段、哪些变量缺失严重,一目了然。别上来就 fillna(),那是新手干的事。

3.2 异常值检测

异常值,说白了就是「看着不对劲」的数据。比如电池电压突然跳到 10V,或者 SOC 从 50% 瞬间变成 120%。这种数据不处理,模型会学出什么鬼东西来?

我常用的检测方法有几种:

  • 3σ 原则:适合正态分布的数据,超出均值±3倍标准差就算异常
  • 箱线图法:用 IQR(四分位距)来判定,不受极端值影响
  • DBSCAN 聚类:适合多维数据的异常检测,我在做电池一致性分析时常用
  • 孤立森林:高维数据效果好,但参数调起来有点烦

我曾经踩过一个坑——某项目用 3σ 原则检测电流异常,结果发现每天都有大量「异常值」。后来一查,是电池在充放电切换时,电流确实会瞬间跳变。这种「业务上的正常值」,算法却判成了异常。所以啊,异常值检测一定要结合业务场景,不能纯靠数学。

避坑指南:我曾经因为没做异常值检测,直接把数据喂给模型训练,结果模型收敛极慢,准确率还不到 60%。后来发现是某个传感器的噪声数据把模型带偏了。记住:异常值不处理,模型就是「垃圾进,垃圾出」。

3.3 数据去重

数据去重,听起来简单,做起来坑多。

储能系统的数据采集,经常因为重复上报、缓存重传、时间戳精度不够等原因,出现完全一样或高度相似的多条记录。你想想看,如果同一个时间点有两条一模一样的 SOC 数据,你留哪条?

我一般分两种情况处理:

  • 完全重复:所有字段都一样,直接删掉一条,保留一条
  • 部分重复:时间戳相同但其他字段不同,需要判断是合并还是保留最新

这里有个细节——时间戳精度。有些系统的采样周期是 1 秒,但时间戳只精确到秒,导致同一秒内有多条数据。这种情况不能简单去重,得先判断是不是正常的多点采样。

我在项目中遇到过最离谱的事——某 PCS 上报的数据,每 5 分钟重复一次,持续了整整一个月。后来发现是通信协议里的确认机制出了问题,数据发了两次。这种去重很简单,按时间戳去重就行。但如果是毫秒级的数据,就得小心了。

3.4 时间戳对齐

时间戳对齐,这是多源数据融合里最头疼的问题之一。

BMS 的数据是 100ms 上报一次,PCS 是 1s 上报一次,气象站是 5min 上报一次。这些数据的时间戳都不对齐,你怎么融合?

我常用的对齐策略:

  • 降采样:把所有数据统一到最粗的时间粒度。比如都按 1 分钟对齐,简单但会丢失细节
  • 升采样:把低频数据插值到高频。比如把气象数据从 5 分钟插值到 1 秒,但要注意别引入虚假信息
  • 最近邻对齐:找时间上最接近的点进行匹配。适合实时性要求高的场景

我个人习惯用 pandas 的 resample 方法,配合 asfreq 或 interpolate。举个例子:

import pandas as pd

# 假设 bms_data 是 BMS 的原始数据,时间戳为索引
# 统一对齐到 1 秒
bms_aligned = bms_data.resample('1S').mean()

# 如果数据有缺失,用前向填充
bms_aligned = bms_data.resample('1S').ffill()

# 对于气象数据这种低频的,用线性插值
weather_aligned = weather_data.resample('1S').interpolate(method='linear')

经验之谈:时间戳对齐前,一定要先检查各个数据源的时间基准是否一致。我遇到过 BMS 用 UTC 时间,PCS 用本地时间,差了 8 个小时。这种问题不解决,对齐就是笑话。

3.5 数据标准化

最后说说标准化。不同传感器采集的数据,量纲不一样。电压是 V,电流是 A,温度是 ℃,SOC 是 %。这些数据直接放一起,数值大的变量会主导模型,数值小的变量就被淹没了。

常用的标准化方法:

  • Min-Max 标准化:把数据缩放到 [0,1] 区间。适合数据分布比较均匀的情况
  • Z-score 标准化:减去均值,除以标准差。适合数据近似正态分布的情况
  • Robust 标准化:用中位数和 IQR,对异常值不敏感。我处理储能数据时最常用这个

为什么我偏爱 Robust 标准化?因为储能数据里经常有尖峰电流、瞬时电压波动,这些异常值如果用 Min-Max 标准化,会把正常数据压缩到很小的范围。用 Robust 的话,中位数和 IQR 不受极端值影响,效果稳定得多。

举个例子:

from sklearn.preprocessing import RobustScaler
import numpy as np

# 假设 data 是包含电压、电流、温度的三维数组
scaler = RobustScaler()
data_scaled = scaler.fit_transform(data)

# 标准化后的数据,中位数为 0,IQR 为 1
print(f"标准化后中位数: {np.median(data_scaled, axis=0)}")
print(f"标准化后 IQR: {np.percentile(data_scaled, 75, axis=0) - np.percentile(data_scaled, 25, axis=0)}")

重要提醒:标准化参数(均值、标准差、中位数等)一定要在训练集上计算,然后应用到验证集和测试集。千万别在整个数据集上算,否则会造成数据泄露,模型评估结果会虚高。

知识体系总览

下面这张图,是我梳理的数据预处理核心流程。你可以把它当成一个检查清单,每次做数据融合前,对着走一遍:

数据预处理与清洗核心流程 原始多源数据 步骤1:缺失值处理 步骤2:异常值检测 步骤3:数据去重 步骤4:时间戳对齐 步骤5:数据标准化

这张图看着简单,但每一步都有讲究。缺失值处理不好,后面的异常值检测就会误判;时间戳没对齐,标准化就是瞎搞。所以我的建议是:按顺序来,别跳步

好了,数据预处理这块就聊到这儿。记住一句话:数据预处理做得好,后面建模没烦恼。你花 80% 的时间在预处理上,一点都不亏。