参数化的CUSUM检测算法——Python
最近帮实验室做了一个项目,做的是电器负荷识别的,近年来特别火爆,而我看网上好像相关的开源点很少,所以我跟大家分享一下:参数化的CUSUM检测算法。 当然我不是特别了解这个内容,只是学会了如何去使用这个算法罢了,如果有想法的也可以底下评论交流。 电器负荷投入或者切除的暂态过程定义为一个暂态事件,而对暂态事件检测可以归结为变点检测问题。说白了也就是说当负荷状态发生改变,有一些特征就会发生改变,例如说均值或者方差等。而在电器负荷识别中,最常用到的应该就是电压有效值和电流有效值了,所以我们观察电流有效值就可以了。 这里讲一下公式: 我不会用这里的公式编辑器,还是mathtype用起来舒服先。  若检测投切时间为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。