有关NILM中的评价指标的解释请看我们另外一篇博文
,下面简单解释一下代码实现,代码为python版本。
import numpy as np
def tp_tn_fp_fn(states_pred, states_ground): # 定义tp,tn,fp,fn,np.logical_and为逻辑与
tp = np.sum(np.logical_and(states_pred == 1, states_ground == 1),axis = 0).reshape([1,-1]) //
fp = np.sum(np.logical_and(states_pred == 1, states_ground == 0),axis = 0).reshape([1,-1])
fn = np.sum(np.logical_and(states_pred == 0, states_ground == 1),axis = 0).reshape([1,-1])
tn = np.sum(np.logical_and(states_pred == 0, states_ground == 0),axis = 0).reshape([1,-1])
return tp, tn, fp, fn
def recall_precision_accuracy_f1(pred,ground):
thresh = [100,50,20,200] # 电器功率的阈值,超过该功率则该电器处于开状态,否则为关状态,列表中的每一个元素代表了一种电器的阈值
sum_samples = pred.shape[0] # 预测序列的总长
pr = np.array([0 if pred[i][j] < thresh[j] else 1 for i in range(pred.shape[0]) for j in range(pred.shape[1])]).reshape([pred.shape[0],pred.shape[1]]) # 利用阈值将实际的消耗功率转换成0-1状态,这个是预测序列的转换
gr = np.array([0 if ground[i][j] < thresh[j] else 1 for i in range(ground.shape[0]) for j in range(pred.shape[1])]).reshape([pred.shape[0],pred.shape[1]]) # 真实序列的转换
tp,tn,fp,fn = tp_tn_fp_fn(pr,gr) #根据真实序列和预测序列的0-1状态值得到tp,tn,fp,fn,用于评估指标的计算
res_recall = recall(tp,fn)
res_precision = precision(tp,fp)
res_f1 = f1(res_precision,res_recall)
res_accuracy = accuracy(tp,tn,sum_samples)
return (res_recall,res_precision,res_accuracy,res_f1)
def recall(tp,fn): #召回率
return tp / (tp + fn)
def precision(tp,fp): # 精确度
return tp / (tp + fp)
def f1(prec,rec): // f1值
return 2 * (prec * rec) / (prec + rec)
def accuracy(tp,tn,samples): #准确率
return (tp + tn) / samples
def mean_absolute_error(pred,ground): #平均绝对误差
sum_samples = pred.shape[0] # 预测序列的总长
total_sum = np.sum(abs(pred - ground),axis = 0)
return total_sum / sum_samples
def get_sae(pred,ground): # signal aggregate error
sample_period = 60 # 采样周期为60s,这个根据实际数据的采样周期进行相应的修改。如REDD中的采样周期有3s的,wikienergy数据的采样周期为60s,UK—DALE的采样周期又是不同的。
r = np.sum(ground * sample_period * 1.0 / 3600,axis = 0)
rhat = np.sum(pred * sample_period * 1.0 / 3600,axis = 0)
return np.abs(r - rhat) / np.abs(r)
我的输入数据是这样的,pred和groud 均是numpy格式的ndarray格式的矩阵或者数组,如果是矩阵的话,矩阵的每一列表示的是单个电器的历史消耗功率值,如pred.shape = (40000,5)
,40000表示的是历史的测试样本的个数,5表示的是五种电器。