严格地说,一个电池组中的电池单元并不完全相同。鉴于制造工艺、使用中的热条件、平衡状态等的变化,串联中相同类型的电池可能具有不同的OCV和内阻。
不同的OCV:会导致电池电压的偏移(体现在加法上)
内阻的不同:会导致不同幅度的电压波动(体现在乘法上);(不同老化程度的电池表现出不同的内部电阻)
鉴于相关系数衡量的是两条曲线的趋势是否匹配,趋势的相似性。这里引入相关系数的思想,用相
关系数提取电压下降的非趋势性信息来检测短路的初始阶段,并将变化反映在相关系数的下降上。
应用移动平均窗口来保持电池的最新电压趋势,保持对短路故障的检测灵敏度。
理想情况下,两个串联电池电压的相关系数在正常运行时应接近1,当发生短路时,异常的电压降
低会影响电池电压的同步波动,从而被相关系数降低所反映。
利用移动窗口滤波器来忘记过去的数据并保持对故障的检测灵敏度,即在每个时间瞬间,只计算历
史时间窗口中的数据的相关系数
移动窗口大小:太大,由短路导致的异常电压变化对相关系数的影响可以忽略不计,太小,噪
声将被视为异常波动。
图3(b):三种不同窗口大小的计算结果之间的比较表明,较小的窗口大小会导致对异常电压变
化的更高灵敏度
对两个电压增加了独立同分布的白噪声
图4(b):提供的相关系数比图3(b)中的相关系数表现得更加波动。
鉴于相关系数公式特性,对两个电压增加方波,以防止在休息期间噪音主导电压变化时出现错误检测
防止假阳性检测。图4(a):当电池处于静止状态时,相关系数下降,图4©显示了加入方波后
的相关系数,表明诱发的故障可以很容易被识别。
太难调参数了,结果不稳定,方波是个啥我也不知道。
from scipy.stats import pearsonr
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# 正常显示中文和负号
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 原始数据展示
data = pd.read_csv('data/raw.csv')
data = data.rename(columns = {'u1': 'a1', 'u2': 'a2'})
data = data.dropna()
x_columns = [x for x in data.columns if x in ['a1', 'a2']]
data = data[x_columns]
time = range(0, len(data["a1"]))
plt.subplot(231)
plt.plot(time, data["a1"], '#20B2AA', label = 'u1')
plt.plot(time, data["a2"], '#F08080', label = 'u2')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('mv')
plt.title('两个电芯电压图示')
# 按照滑动窗口w计算原始数据的相关系数
w = 5
l_cor = []
for i in range(len(data['a1']) - w):
l_V1fn = []
l_V2n = []
for j in range(i, i + w, 1):
l_V1fn.append(data["a1"][j])
l_V2n.append(data["a2"][j])
cor12 = pearsonr(l_V1fn, l_V2n)[0]
l_cor.append(cor12)
plt.subplot(232)
time = range(0, len(l_cor))
plt.plot(time, l_cor, '#20B2AA')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('相关系数')
plt.title('两个电芯电压的相关系数,计算相关系数的滑动窗口设为5')
# 加了白噪声后的图示
mean = 0
std = 0.1
samples1 = np.random.normal(mean, std, size = len(data['a1']))
data["a11"] = data["a1"] + samples1
samples2 = np.random.normal(mean, std, size = len(data['a1']))
data["a12"] = data["a2"] + samples2
time = range(0, len(data["a1"]))
plt.subplot(233)
plt.plot(time, data["a11"], '#20B2AA', label = '电芯1的电压+白噪声')
plt.plot(time, data["a12"], '#F08080', label = '电芯2的电压+白噪声')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('mv')
plt.title('加了白噪声后两个电芯电压图示')
# 白噪声后相关系数
w = 5
l_cor = []
for i in range(len(data['a11']) - w):
l_V1fn = []
l_V2n = []
for j in range(i, i + w, 1):
l_V1fn.append(data["a11"][j])
l_V2n.append(data["a12"][j])
cor12 = pearsonr(l_V1fn, l_V2n)[0]
l_cor.append(cor12)
plt.subplot(234)
time = range(0, len(l_cor))
plt.plot(time, l_cor, '#20B2AA')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('相关系数')
plt.title('加了白噪声后两个电芯电压的相关系数,计算相关系数的滑动窗口设为5')
# 构造异常
data["a12"][2] = data["a12"][2] - 30
time = range(0, len(data["a11"]))
plt.subplot(235)
plt.plot(time, data["a11"], '#20B2AA', label = 'u1+白噪声')
plt.plot(time, data["a12"], '#F08080', label = 'u2+白噪声+异常')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('mv')
plt.title('加了白噪声后电芯电压和加了白噪声加了异常后电芯电压图示')
# 加了白噪声后u1和加了白噪声加了异常u2图示相关系数
w = 5
l_cor = []
for i in range(len(data['a11']) - w):
l_V1fn = []
l_V2n = []
for j in range(i, i + w, 1):
l_V1fn.append(data["a11"][j])
l_V2n.append(data["a12"][j])
cor12 = pearsonr(l_V1fn, l_V2n)[0]
l_cor.append(cor12)
plt.subplot(236)
time = range(0, len(l_cor))
plt.plot(time, l_cor, '#20B2AA')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('相关系数')
plt.title('加了白噪声后的u1和加了白噪声加了异常后u2的相关系数')
plt.show()
调试脚本
"""
调试过程
"""
import numpy as np
import pandas as pd
from scipy.stats import pearsonr
import matplotlib.pyplot as plt
# 正常显示中文和负号
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用黑体显示中文
plt.rcParams['axes.unicode_minus'] = False # 正常显示负号
def graph(u1, u2, type):
if type == 1:
time = range(0, len(u1))
plt.plot(time, u1, '#20B2AA', label = 'u1')
plt.plot(time, u2, '#F08080', label = 'u2')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('mv')
plt.title('u1和u2图示')
elif type == 2:
time = range(0, len(u2))
plt.plot(time, u2, '#20B2AA')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('相关系数')
plt.title('u1和u2的相关系数')
elif type == 3:
time = range(0, len(u1))
plt.plot(time, u1, '#20B2AA', label = 'u1+白噪声')
plt.plot(time, u2, '#F08080', label = 'u2+白噪声')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('mv')
plt.title('加了白噪声后u1和u2图示')
elif type == 4:
time = range(0, len(u1))
plt.plot(time, u1, '#20B2AA', label = 'u1+白噪声')
plt.plot(time, u2, '#F08080', label = 'u2+白噪声+异常')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('mv')
plt.title('加了白噪声后u1和加了白噪声加了异常u2图示')
elif type == 5:
time = range(0, len(u2))
plt.plot(time, u2, '#20B2AA')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('相关系数')
plt.title('加了白噪声后的u1和加了白噪声加了异常后u2的相关系数')
plt.show()
def corre(u1, u2, type):
w = 5
l_cor = []
for i in range(len(u1) - w):
l_V1fn = []
l_V2n = []
for j in range(i, i + w, 1):
l_V1fn.append(u1[j])
l_V2n.append(u2[j])
cor12 = pearsonr(l_V1fn, l_V2n)[0]
l_cor.append(cor12)
if type == 1:
graph(1, l_cor, 2)
else:
graph(1, l_cor, 5)
# corre ()
def raw_data():
""" 原始数据图及原始数据相关系数
:return:
"""
data = pd.read_csv('data/raw.csv')
data = data.rename(columns = {'u1': 'a1', 'u2': 'a2'})
data = data.dropna()
x_columns = [x for x in data.columns if x in ['a1', 'a2']]
data = data[x_columns]
graph(data["a1"], data["a2"], 1)
corre(data["a1"], data["a2"], 1)
data.to_csv("data/raw1.csv")
# raw_data()
def white_Noises():
"""对内短路电压数据,3列正常电压数据添加0均值1方差的白噪声
:return:
"""
data = pd.read_csv("data/raw1.csv")
mean = 0
std = 0.1
num_samples = len(data['a1'])
samples1 = np.random.normal(mean, std, size = num_samples)
data["a11"] = data["a1"] + samples1
samples2 = np.random.normal(mean, std, size = num_samples)
data["a12"] = data["a2"] + samples2
# data.to_csv ("data/White.csv")
graph(data["a11"], data["a12"], 3)
# white_Noises ()
def buildData_InternalShortcircuit():
"""构造内短路数据v1f
:return:
"""
data = pd.read_csv("data/White.csv")
data["a12"][2] = data["a12"][2] - 30
graph(data["a11"], data["a12"], 4)
data.to_csv("data/dataISC.csv")
corre(data["a11"], data["a12"], 2)
# buildData_InternalShortcircuit()