def FTE_func(predictions, ground_truth): both_sets_of_meters = iterate_through_submeters_of_two_metergroups( predictions, ground_truth) total_pred_list = [] total_gt_list = [] fraction_pred = [] fraction_gt = [] fraction_min = [] total_pred = 0.0 total_gt = 0.0 for pred_meter, ground_truth_meter in both_sets_of_meters: total_app_pred = 0.0 total_app_gt = 0.0 for aligned_meters_chunk in align_two_meters(pred_meter, ground_truth_meter): total_pred += aligned_meters_chunk.icol(0).sum() total_gt += aligned_meters_chunk.icol(1).sum() total_app_pred += aligned_meters_chunk.icol(0).sum() total_app_gt += aligned_meters_chunk.icol(1).sum() total_pred_list.append(total_app_pred) total_gt_list.append(total_app_gt) fraction_gt = np.array(total_gt_list) / total_gt fraction_pred = np.array(total_pred_list) / total_pred for i in range(len(fraction_pred)): fraction_min.append(min(fraction_pred[i], fraction_gt[i])) return np.array(fraction_min).sum()
def error_in_assigned_energy(predictions, ground_truth): """Compute error in assigned energy. .. math:: error^{(n)} = \\left | \\sum_t y^{(n)}_t - \\sum_t \\hat{y}^{(n)}_t \\right | Parameters ---------- predictions, ground_truth : nilmtk.MeterGroup Returns ------- errors : pd.Series Each index is an meter instance int (or tuple for MeterGroups). Each value is the absolute error in assigned energy for that appliance, in kWh. """ errors = {} both_sets_of_meters = iterate_through_submeters_of_two_metergroups( predictions, ground_truth) for pred_meter, ground_truth_meter in both_sets_of_meters: sections = pred_meter.good_sections() ground_truth_energy = ground_truth_meter.total_energy(sections=sections) predicted_energy = pred_meter.total_energy(sections=sections) errors[pred_meter.instance()] = np.abs(ground_truth_energy - predicted_energy) #return errors return pd.Series(errors)
def rms_error_power(predictions, ground_truth): '''Compute RMS error in assigned power .. math:: error^{(n)} = \\sqrt{ \\frac{1}{T} \\sum_t{ \\left ( y_t - \\hat{y}_t \\right )^2 } } Parameters ---------- predictions, ground_truth : nilmtk.MeterGroup Returns ------- error : pd.Series Each index is an meter instance int (or tuple for MeterGroups). Each value is the RMS error in predicted power for that appliance. ''' error = {} both_sets_of_meters = iterate_through_submeters_of_two_metergroups( predictions, ground_truth) for pred_meter, ground_truth_meter in both_sets_of_meters: sum_of_squared_diff = 0.0 n_samples = 0 for aligned_meters_chunk in align_two_meters(pred_meter, ground_truth_meter): diff = aligned_meters_chunk.icol(0) - aligned_meters_chunk.icol(1) diff.dropna(inplace=True) sum_of_squared_diff += (diff ** 2).sum() n_samples += len(diff) error[pred_meter.instance()] = math.sqrt(sum_of_squared_diff / n_samples) return pd.Series(error)
def mean_normalized_error_power(predictions, ground_truth): '''Compute mean normalized error in assigned power .. math:: error^{(n)} = \\frac { \\sum_t {\\left | y_t^{(n)} - \\hat{y}_t^{(n)} \\right |} } { \\sum_t y_t^{(n)} } Parameters ---------- predictions, ground_truth : nilmtk.MeterGroup Returns ------- mne : pd.Series Each index is an meter instance int (or tuple for MeterGroups). Each value is the MNE for that appliance. ''' mne = {} both_sets_of_meters = iterate_through_submeters_of_two_metergroups( predictions, ground_truth) for pred_meter, ground_truth_meter in both_sets_of_meters: total_abs_diff = 0.0 sum_of_ground_truth_power = 0.0 for aligned_meters_chunk in align_two_meters(pred_meter, ground_truth_meter): diff = aligned_meters_chunk.icol(0) - aligned_meters_chunk.icol(1) total_abs_diff += sum(abs(diff.dropna())) sum_of_ground_truth_power += aligned_meters_chunk.icol(1).sum() mne[pred_meter.instance()] = total_abs_diff / sum_of_ground_truth_power return pd.Series(mne)
def f1_score(predictions, ground_truth): '''Compute F1 scores. .. math:: F_{score}^{(n)} = \\frac {2 * Precision * Recall} {Precision + Recall} Parameters ---------- predictions, ground_truth : nilmtk.MeterGroup Returns ------- f1_scores : pd.Series Each index is an meter instance int (or tuple for MeterGroups). Each value is the F1 score for that appliance. If there are multiple chunks then the value is the weighted mean of the F1 score for each chunk. ''' # If we import sklearn at top of file then sphinx breaks. from sklearn.metrics import f1_score as sklearn_f1_score # sklearn produces lots of DepreciationWarnings with PyTables import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) # align_two_meters does not work!! f1_scores = {} both_sets_of_meters = iterate_through_submeters_of_two_metergroups( predictions, ground_truth) for pred_meter, ground_truth_meter in both_sets_of_meters: scores_for_meter = pd.DataFrame(columns=['score', 'n_samples']) aligned_states_chunks = align_two_meters(pred_meter, ground_truth_meter, 'when_on') for aligned_states_chunk in aligned_states_chunks: aligned_states_chunk.dropna(inplace=True) aligned_states_chunk = aligned_states_chunk.astype(int) score = sklearn_f1_score(aligned_states_chunk.icol(0), aligned_states_chunk.icol(1)) scores_for_meter = scores_for_meter.append( {'score': score, 'n_samples': len(aligned_states_chunk)}, ignore_index=True) # Calculate weighted mean tot_samples = scores_for_meter['n_samples'].sum() scores_for_meter['proportion'] = (scores_for_meter['n_samples'] / tot_samples) avg_score = (scores_for_meter['score'] * scores_for_meter['proportion']).sum() f1_scores[pred_meter.instance()] = avg_score return pd.Series(data=f1_scores.values(), index=f1_scores.keys(), dtype=np.float32)
def acc_score(predictions, ground_truth): '''Compute F1 scores. .. math:: F_{score}^{(n)} = \\frac {2 * Precision * Recall} {Precision + Recall} Parameters ---------- predictions, ground_truth : nilmtk.MeterGroup Returns ------- f1_scores : pd.Series Each index is an meter instance int (or tuple for MeterGroups). Each value is the F1 score for that appliance. If there are multiple chunks then the value is the weighted mean of the F1 score for each chunk. ''' # If we import sklearn at top of file then sphinx breaks. from sklearn.metrics import accuracy_score as sklearn_acc_score # sklearn produces lots of DepreciationWarnings with PyTables import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) f1_scores = {} both_sets_of_meters = iterate_through_submeters_of_two_metergroups( predictions, ground_truth) for pred_meter, ground_truth_meter in both_sets_of_meters: scores_for_meter = pd.DataFrame(columns=['score', 'n_samples']) for aligned_states_chunk in align_two_meters(pred_meter, ground_truth_meter, 'when_on'): aligned_states_chunk.dropna(inplace=True) aligned_states_chunk = aligned_states_chunk.astype(int) score = sklearn_acc_score(aligned_states_chunk.icol(0), aligned_states_chunk.icol(1)) scores_for_meter = scores_for_meter.append( {'score': score, 'n_samples': len(aligned_states_chunk)}, ignore_index=True) # Calculate weighted mean tot_samples = scores_for_meter['n_samples'].sum() scores_for_meter['proportion'] = (scores_for_meter['n_samples'] / tot_samples) avg_score = (scores_for_meter['score'] * scores_for_meter['proportion']).sum() f1_scores[pred_meter.instance()] = avg_score return pd.Series(f1_scores)
def total_disag_err(predictions, ground_truth): #only iterate for the instance in the prediction/ elecmeter with lesser instance both_sets_of_meters = iterate_through_submeters_of_two_metergroups( predictions, ground_truth) # additional of total variable total_diff = 0.0 total_pred = 0.0 total_gt = 0.0 for pred_meter, ground_truth_meter in both_sets_of_meters: for aligned_meters_chunk in align_two_meters(pred_meter, ground_truth_meter): diff = aligned_meters_chunk.icol(0) - aligned_meters_chunk.icol(1) total_pred += aligned_meters_chunk.icol(0).sum() total_diff += sum(abs(diff.dropna())) total_gt += aligned_meters_chunk.icol(1).sum() return float(total_diff) / float(total_gt)