最近帮实验室做了一个项目,做的是电器负荷识别的,近年来特别火爆,而我看网上好像相关的开源点很少,所以我跟大家分享一下:参数化的CUSUM检测算法。
当然我不是特别了解这个内容,只是学会了如何去使用这个算法罢了,如果有想法的也可以底下评论交流。
电器负荷投入或者切除的暂态过程定义为一个暂态事件,而对暂态事件检测可以归结为变点检测问题。说白了也就是说当负荷状态发生改变,有一些特征就会发生改变,例如说均值或者方差等。而在电器负荷识别中,最常用到的应该就是电压有效值和电流有效值了,所以我们观察电流有效值就可以了。
这里讲一下公式:
我不会用这里的公式编辑器,还是mathtype用起来舒服先。
![单边状态检测公式](https://img-blog.csdnimg.cn/20210127165329824.png#pic_center)
若检测投切时间为d,当gk>0时,采样序列发生了变化,但小于阙值h,则令检测延迟时间d=d+1,否则令d=0。当gk>h,则一个暂态事件被检测出来,则采样序列突变发生的时刻可以倒推为 t=k-d。
讲一下代码:
timecount = 1
i=0
sumsave=[]
alarm = []
flag=1
while(timecount<25 and flag):
#timecount表示25个循环检测,以1s为一次检测时长,1s有2000个采样周期,flag为0时表示检测到突变
if i<timecount*2000:
meancount = mean(record[2000*(timecount-1):2000*timecount,1]) #每一秒的均值
lalarm =1 #警报值5,
# minmiss=2 #能够容忍的最小误差
minmiss = 0.5
minn = 10 #初始化累计和最小值
summ = 0 #累计和初始化
for i in range((timecount-1)*2000,timecount*2000+1):
summ = max(0,summ+(record[i,1]-meancount-minmiss)) #累计和
sumsave.append(summ)
if sumsave[i]<minn: #寻找最小误差
minn = sumsave[i]
d = sumsave[i]-minn #计算其他累计和与最小累计和的差d
if d >=lalarm:
alarm.append(1)
testcusum[jj-ran1[0]] = 1
alarmtime.append(i)#alarmtime表示突变时间
flag = 0
break
else:
alarm.append(0)
else:
timecount +=1
plt.figure()
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.plot(record[:,1].tolist(),color = colornames[count])
plt.xlabel('index/0.5ms')
plt.ylabel('Amp/A')
plt.title('随时间的电流波形CUSUM暂态事件检测%s' %(filenames[jj][0:9]))
plt.plot(alarm,'r')
plt.show()
下面是检测结果:
当负荷电器稳态时,红色值为1。