【数据挖掘】基于卷积神经网络的非侵入式负荷分解(NILM)Python实现

       本方法主要利用基于卷积神经网络的非侵入式负荷分解方法实现住宅设备的识别,输入数据为在设备运行时获得的瞬态功率信号数据。训练卷积神经网络使用数据为开源数据REDD(1Hz),具体实现原理请参考文献下载链接。只供学习参考,Python实现代码如下:

1 第一部分:数据可视化

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
data = pd.read_csv("data.csv")
#print(data)

n = int(data.max(axis = 0, skipna = True)[1]) + 1  # gets the number of readings
h = int(data.max(axis = 0, skipna = True)[0]) # gets the number of houses

houses = np.zeros((n,5,h))  # time, tv inst power, aggr power, filtered tv , on/off

for i in range(h):
    houses[:,0:3,i] =  data[data['House']==i+1  ].values[:,1:]   # data is now seperated by house

# visulise data
plt.figure()
plt.suptitle('Tv power and agg power seperated ')
plt.subplot(211)
for i in range(h):
    plt.plot(houses[:,0,i],houses[:,1,i], label = 'House ' + str(i+1) )
plt.subplot(212)
for i in range(h):
    plt.plot(houses[:,0,i],houses[:,2,i], label = 'House ' + str(i+1) )
plt.legend()
# plt.show()

plt.figure()
plt.suptitle('Normalised data, shown by house')
for i in range(h):
    plt.subplot(3,1,i+1)
    plt.plot(houses[:,0,i],houses[:,1,i]/np.average(houses[:,1,i]) )
    plt.plot(houses[:, 0, i], houses[:, 2, i]/np.average( houses[:, 2, i]) )
plt.legend()
plt.show()

实验结果:

【数据挖掘】基于卷积神经网络的非侵入式负荷分解(NILM)Python实现_第1张图片

【数据挖掘】基于卷积神经网络的非侵入式负荷分解(NILM)Python实现_第2张图片

  

过滤并标准化电视即时功率

from scipy.signal import *
houses[:,3,:] = savgol_filter(houses[:, 1, :] / np.average(houses[:, 1, :],axis=0), 11, 2,axis=0)
thres = 1.15  # the threshold for seperation
plt.figure()
plt.suptitle('Filtered inst power, and determined state')
for i in range(h):
    houses[ np.argwhere( houses[:,3,i] >= thres ) ,4,i  ] +=1   # makes the 4th row qual to 1 if the filtered result is higher then the threshold
    plt.subplot(3, 1, i + 1)
    plt.plot(  houses[:, 0, i],houses[:, 3, i]  ) # plot filtered curve
    plt.plot(houses[:, 0, i], houses[:, 4, i]) # plot on state
    plt.plot(houses[:, 0, i], houses[:, 1, i] / np.average(houses[:, 1, i])) # plot normalised curve
plt.show()

实验结果:

【数据挖掘】基于卷积神经网络的非侵入式负荷分解(NILM)Python实现_第3张图片

2 卷积神经网络实现负荷识别

#总功率问题
# - 存在非常大的峰
# - 其他电器出现的一些周期性峰值,这些在每个房子中的频率不同
# - 噪声/峰值平坦度与一号房的电视电源使用量相似
# 想法
# - 针对开/关状态测试/检查
# - 测试/检查状态改变的时间
# - 使用 CNN/ANN/MLP 进行分类
# - 输入应该是整个时间,还是 N 个时间步长的夹头
# - N 时间步长意味着它可以推广到不同的测试输入大小
# - 然后应该建立这 N 个大输入的训练集和测试集,每一张幻灯片
# - 允许在输入中打开状态的位置进行概括
# - 输出N 1/0(或开启的概率,然后是阈值)每个时间步对应的输出
import numpy as np
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers import Dropout
from keras.models import Sequential
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import MaxPooling1D
def sep_data(houses, T=0.8):
    # seperate the house data into windowed sections winin each house
    # split into training (T%) and test set, no validation set is being used
    # record the class as a one hot vector of if the last state is on/off

    window_len = 20
    #at size 20 the classifier was classfiing the periodic sections as the tv being on in house one #filter sized 6,3 wights 1.8,1
    #at length 30 a similar thing happened, filters 6,3 weights at 3:1, not as accurate as ^
    # at 10, with 3,3, stride and 2.2:1 similar problems

    ntrain = int((n-window_len)*T) # amount of data from each house to train on
    train = np.zeros((ntrain*h,window_len,1,2))                         # [#windows x samples per window x 1(as only one input feature) x 2 (for rata, and weights)
    test = np.zeros( ( (n-window_len-ntrain)*h,window_len,1,2)  )
    for j in range(h): #each house
        for i in range(n-window_len):
            train_index = i+j*ntrain ## which row in the reformatted array is being filled
            test_index = i-ntrain + j*(n-window_len-ntrain)

            if i#%d: %.3f' % (r + 1, score))
    scores.append(score)


model_variability(scores)

【数据挖掘】基于卷积神经网络的非侵入式负荷分解(NILM)Python实现_第4张图片

【数据挖掘】基于卷积神经网络的非侵入式负荷分解(NILM)Python实现_第5张图片

数据:下载

你可能感兴趣的:(NILM,python,python,数据挖掘,数据分析,机器学习,人工智能)