第三章 特征工程(上):从充放电曲线提取健康特征
好,咱们进入正题。上一章我们聊了数据清洗,把那些脏数据、异常数据都处理干净了。但光有干净数据还不够,你想想看,原始电压电流曲线直接扔给模型,它根本看不懂。我们需要把这些原始信号翻译成模型能理解的「健康特征」。
这一章,我重点讲两个最经典的特征提取方法:IC曲线(增量容量分析)和DV曲线(差分电压分析)。这两个方法,说白了就是把充放电曲线上的微小变化放大,让电池的老化痕迹无处遁形。
核心观点:IC/DV曲线是电池健康状态的「指纹」。不同老化程度下,曲线的峰位、峰高、峰面积都会发生规律性变化。抓住这些变化,就能预测SOH。
3.1 为什么需要IC/DV曲线?
直接看电压-容量曲线,你能看出什么?
嗯,一条平滑的曲线,随着充放电进行,电压缓慢变化。新电池和旧电池的曲线看起来差不多,只是稍微偏移了一点。这点偏移量,肉眼很难分辨,模型也很难学到有效特征。
但如果我们对容量求微分呢?
dQ/dV,也就是IC曲线。它把电压平台上那些微小的容量变化放大成明显的峰值。每个峰值对应一个电化学反应阶段。电池老化后,活性物质损失、内阻增加,这些峰值就会变矮、变宽、甚至移位。
我在项目中遇到过这样的情况:用原始电压曲线做特征,模型精度只有85%左右。换成IC曲线特征后,直接跳到93%。差别就这么大。
3.2 增量容量分析(IC曲线)
3.2.1 数学原理
IC曲线的定义很简单:
IC = dQ / dV ≈ ΔQ / ΔV
其中Q是容量,V是电压。我们取相邻两个采样点的容量差除以电压差,就得到IC值。
但这里有个坑——噪声放大。微分操作对噪声极其敏感。原始数据里哪怕有1mV的波动,微分后可能变成一个大尖峰。所以,计算IC曲线前,必须做平滑处理。
我曾经踩过的坑:第一次做IC曲线时,没做平滑,直接微分。结果出来的曲线像心电图一样,全是毛刺,根本没法用。后来花了整整两天调平滑参数才搞定。记住:先平滑,再微分。
3.2.2 计算步骤与代码
我个人的习惯是分三步走:
- 数据重采样:把充放电数据按电压间隔均匀采样,比如每10mV取一个点
- 平滑滤波:用Savitzky-Golay滤波器或移动平均,去除高频噪声
- 数值微分:用中心差分法计算dQ/dV
来看代码:
import numpy as np
import pandas as pd
from scipy.signal import savgol_filter
def compute_ic_curve(voltage, capacity, voltage_step=0.01, window_length=11, polyorder=3):
"""
计算IC曲线
voltage: 电压序列 (V)
capacity: 容量序列 (Ah)
voltage_step: 重采样电压间隔 (V)
window_length: SG滤波器窗口长度(必须为奇数)
polyorder: SG滤波器多项式阶数
"""
# 1. 按电压间隔重采样
v_min = np.floor(voltage.min() / voltage_step) * voltage_step
v_max = np.ceil(voltage.max() / voltage_step) * voltage_step
v_bins = np.arange(v_min, v_max + voltage_step, voltage_step)
# 用插值法获取等电压间隔的容量
v_resampled = v_bins
cap_resampled = np.interp(v_resampled, voltage, capacity)
# 2. 平滑处理
cap_smooth = savgol_filter(cap_resampled, window_length, polyorder)
# 3. 计算微分
dq = np.diff(cap_smooth)
dv = np.diff(v_resampled)
ic = dq / dv
# 返回IC曲线(电压取中点)
v_ic = (v_resampled[:-1] + v_resampled[1:]) / 2
return v_ic, ic
小技巧:window_length和polyorder怎么选?我一般先用window_length=11, polyorder=3试跑。如果曲线还有毛刺,就增大window_length;如果曲线过于平滑丢失了峰值,就减小window_length或增大polyorder。多试几次就有手感了。
3.2.3 从IC曲线提取特征
IC曲线出来后,我们要从中提取量化特征。常用的有:
| 特征名称 | 物理含义 | 与老化的关系 |
|---|---|---|
| 峰值位置(电压) | 电化学反应发生的电压 | 随老化向右偏移(内阻增加) |
| 峰值高度 | 反应速率/容量贡献 | 随老化降低(活性物质损失) |
| 峰值半高宽 | 反应均匀性 | 随老化变宽(反应不均匀) |
| 峰面积 | 该阶段贡献的容量 | 随老化减小 |
提取这些特征,可以用scipy.signal的find_peaks函数:
from scipy.signal import find_peaks
def extract_ic_features(v_ic, ic):
"""从IC曲线提取峰值特征"""
# 找峰值(只找正峰值)
peaks, properties = find_peaks(ic, prominence=0.1, width=5)
features = {}
for i, peak_idx in enumerate(peaks):
features[f'peak_{i+1}_voltage'] = v_ic[peak_idx]
features[f'peak_{i+1}_height'] = ic[peak_idx]
features[f'peak_{i+1}_width'] = properties['widths'][i] * (v_ic[1] - v_ic[0])
# 峰面积用梯形法近似
left = int(properties['left_bases'][i])
right = int(properties['right_bases'][i])
features[f'peak_{i+1}_area'] = np.trapz(ic[left:right], v_ic[left:right])
return features
3.3 差分电压分析(DV曲线)
3.3.1 DV曲线与IC曲线的关系
DV曲线是IC曲线的倒数:DV = dV/dQ。它反映的是电压随容量变化的速率。
说白了,IC曲线看的是「容量对电压的敏感度」,DV曲线看的是「电压对容量的敏感度」。两者是互补的。
我个人更喜欢用IC曲线,因为它的峰值更明显。但有些场景下,DV曲线也有独特优势——比如在充电末期,电压快速上升,DV曲线能更清晰地反映极化内阻的变化。
3.3.2 计算DV曲线
计算方法和IC曲线类似,只是微分方向反过来:
def compute_dv_curve(voltage, capacity, capacity_step=0.01, window_length=11, polyorder=3):
"""计算DV曲线"""
# 按容量间隔重采样
c_min = np.floor(capacity.min() / capacity_step) * capacity_step
c_max = np.ceil(capacity.max() / capacity_step) * capacity_step
c_bins = np.arange(c_min, c_max + capacity_step, capacity_step)
v_resampled = np.interp(c_bins, capacity, voltage)
v_smooth = savgol_filter(v_resampled, window_length, polyorder)
dv = np.diff(v_smooth)
dq = np.diff(c_bins)
dv_curve = dv / dq
c_dv = (c_bins[:-1] + c_bins[1:]) / 2
return c_dv, dv_curve
3.3.3 DV曲线的特征提取
DV曲线的特征和IC曲线类似,但关注点不同:
- 谷值位置:对应IC曲线的峰值位置,反映反应阶段
- 谷值深度:反映该阶段的电压变化速率
- 曲线斜率:在充电末期,斜率急剧增大,反映极化加剧
实战经验:我一般同时计算IC和DV曲线,然后取两者的特征做融合。IC曲线对活性物质损失敏感,DV曲线对内阻变化敏感。两者结合,能更全面地刻画电池老化状态。
3.4 实操中的注意事项
嗯,这里要重点说几个坑:
- 数据质量是第一位的:如果原始数据有缺失或异常,IC/DV曲线会一塌糊涂。先做好数据清洗再提取特征。
- 平滑参数要调优:不同电池、不同倍率下,最优的平滑参数不同。我建议做一个参数扫描,选使曲线峰值最清晰的参数。
- 注意充放电倍率的影响:大倍率充放电时,极化效应会扭曲IC/DV曲线。最好用同一倍率的数据做对比。
- 温度补偿:温度对IC/DV曲线影响很大。如果数据来自不同温度,建议先做温度归一化。
我曾经犯过的错:有一次用不同温度下的数据直接提取IC特征,结果模型训练出来完全不准。后来发现,25°C和45°C下的IC峰值位置差了将近50mV。从那以后,我每次都会检查数据温度是否一致,或者做温度补偿。
3.5 本章小结
这一章我们讲了:
- 为什么需要IC/DV曲线——放大老化信号
- IC曲线的计算方法和特征提取
- DV曲线的计算方法和特征提取
- 实操中的注意事项和避坑指南
下一章,我们会继续讲特征工程的下半部分——从统计特征和频域特征入手,进一步挖掘电池健康信息。到时候你会看到,同样的数据,换个角度分析,又能挖出新的宝藏。
课后练习:找一组电池老化数据,分别用IC和DV曲线提取特征。然后对比一下,哪些特征对SOH的预测能力最强?试试用相关性分析或者特征重要性排序来找答案。
好,这一章就到这里。有问题随时交流。