3. 数据采集与预处理:数据源类型、数据清洗方法、异常值处理、数据归一化
做储能EMS,说白了就是跟数据打交道。我刚开始入行那会儿,以为算法牛逼就完事了。结果呢?数据一塌糊涂,算法再牛也白搭。这就像做饭——食材不新鲜,厨神来了也没辙。
所以这一章,咱们聊聊数据的前处理。嗯,这是所有算法的基础,也是我踩坑最多的地方。
3.1 数据源类型:你从哪儿搞数据?
储能系统的数据源,我归纳下来主要有三类。每一类都有自己的脾气,你得摸透了。
| 数据源类型 | 典型数据 | 采集频率 | 我遇到的坑 |
|---|---|---|---|
| BMS(电池管理系统) | 电压、电流、温度、SOC、SOH | 100ms - 1s | 通讯中断,数据直接卡死 |
| PCS(储能变流器) | 功率、频率、效率、运行状态 | 1s - 5s | 功率值偶尔跳变,像抽风一样 |
| 电表/传感器 | 并网点功率、环境温度、湿度 | 1s - 15min | 精度不够,小数点后两位就飘 |
我个人习惯,先把这些数据源按优先级排个序。BMS的数据最核心,PCS次之,电表数据用来做校准。你想想看,如果BMS的SOC都错了,后面所有的策略都是瞎搞。
3.2 数据清洗方法:脏数据怎么处理?
数据清洗,说白了就是「去伪存真」。我在项目里见过最离谱的情况——某个电芯电压连续3个小时纹丝不动,一看就是传感器坏了。这种数据不洗掉,算法会以为电池性能好得离谱。
常用的清洗方法,我列了四个:
- 去重: 同一时间戳出现多条记录,保留第一条或最后一条。我建议保留最后一条,因为可能是重传数据,更接近真实值。
- 补全: 时间戳缺失,用插值法补上。最简单的就是线性插值,前后两个有效值取平均。
- 滤波: 高频噪声太多,用滑动平均或中值滤波。我习惯用中值滤波,对尖峰噪声的抑制效果更好。
- 格式统一: 有的设备传的是字符串,有的是浮点数。统一转成float64,省得后面计算时报类型错误。
避坑指南: 我曾经在清洗时把正常数据也洗掉了。原因是滤波窗口设得太大,把一次真实的功率波动当成了噪声。后来我学乖了——先可视化看一眼数据分布,再动手清洗。
3.3 异常值处理:那些「离谱」的数据
异常值,就是那些明显不符合物理规律的数据。比如电池电压突然从3.2V跳到5.0V,或者SOC从50%瞬间变成100%。
我常用的异常值检测方法有三种:
- 阈值法: 设定上下限,超出就标记。比如锂电池电压正常范围是2.5V-4.2V,超出这个范围直接剔除。
- 3σ原则: 计算均值和标准差,超出均值±3倍标准差的数据视为异常。这个方法适合正态分布的数据,比如环境温度。
- IQR法: 四分位距法。用Q1-1.5*IQR和Q3+1.5*IQR作为边界。这个方法对偏态分布的数据更友好。
处理异常值,我一般分两步走:先标记,再处理。标记出来看看是不是传感器故障,如果是,直接剔除;如果是真实工况(比如大电流放电导致的电压骤降),那就保留。
3.4 数据归一化:让数据「站在同一起跑线」
归一化,说白了就是把不同量纲的数据拉到同一个尺度上。电压是伏特(3.2V),电流是安培(100A),温度是摄氏度(25°C)。如果不归一化,算法会天然地「偏爱」数值大的特征。
常用的归一化方法有两种:
| 方法 | 公式 | 适用场景 |
|---|---|---|
| Min-Max归一化 | x' = (x - min) / (max - min) | 数据分布有明确边界,比如SOC(0-100%) |
| Z-score标准化 | x' = (x - μ) / σ | 数据分布未知,或有异常值存在 |
我个人习惯,对于BMS数据(电压、电流、温度)用Z-score标准化。因为这些数据经常有异常值,Min-Max会被异常值拉偏。对于SOC、SOH这种有明确物理意义的数据,用Min-Max归一化,保留原始比例关系。
下面是一个简单的Python代码示例,展示如何对电压和电流做Z-score标准化:
import numpy as np
# 假设这是采集到的电压和电流数据
voltage = np.array([3.2, 3.3, 3.1, 3.4, 3.2])
current = np.array([100, 102, 98, 105, 101])
# Z-score标准化
def z_score_normalize(data):
mean = np.mean(data)
std = np.std(data)
return (data - mean) / std
voltage_norm = z_score_normalize(voltage)
current_norm = z_score_normalize(current)
print("标准化后的电压:", voltage_norm)
print("标准化后的电流:", current_norm)
嗯,这里要注意一点:归一化的参数(均值和标准差)一定要用训练集的数据计算,然后应用到验证集和测试集上。我见过有人把全部数据一起归一化,结果模型在线上部署时直接崩了——因为线上数据跟训练集的分布不一样。
3.5 本章知识体系
下面这张图,是我梳理的数据采集与预处理的核心逻辑。从数据源到最终可用的特征数据,每一步都不能少。
数据预处理这件事,看起来琐碎,但真的决定了算法的上限。我见过太多项目,算法模型选得再好,数据一塌糊涂,最后结果就是「垃圾进,垃圾出」。所以,别嫌麻烦,把数据搞干净了,后面的路就好走了。