output.close() for i in test_building_list: test_elec = test.buildings[i].elec test_mains = test_elec.mains() print("========== DISAGGREGATE ============") disag_filename = "StackTest-" + str(i) + ".h5" output = HDFDataStore(disag_filename, 'w') disaggregator.disaggregate(test_mains, output, test_elec[meter_key], sample_period=sample_period) output.close() print("========== RESULTS ============") result = DataSet(disag_filename) res_elec = result.buildings[i].elec rpaf = metrics.recall_precision_accuracy_f1(res_elec[meter_key], test_elec[meter_key]) print("============ Recall: {}".format(rpaf[0])) print("============ Precision: {}".format(rpaf[1])) print("============ Accuracy: {}".format(rpaf[2])) print("============ F1 Score: {}".format(rpaf[3])) print("============ Relative error in total energy: {}".format( metrics.relative_error_total_energy(res_elec[meter_key], test_elec[meter_key]))) print("============ Mean absolute error(in Watts): {}".format( metrics.mean_absolute_error(res_elec[meter_key], test_elec[meter_key])))
def experiment(key_name, start_e, end_e): '''Trains a network and disaggregates the testset Displays the metrics for the disaggregated part Parameters ---------- key_name : The string key of the appliance start_e : The starting number of epochs for Training end_e: The ending number of epochs for Training ''' # ======= Open configuration file if (key_name not in allowed_key_names): print(" Device {} not available".format(key_name)) print(" Available device names: {}", allowed_key_names) conf_filename = "appconf/{}.json".format(key_name) with open(conf_filename) as data_file: conf = json.load(data_file) input_window = conf['lookback'] threshold = conf['on_threshold'] mamax = 5000 memax = conf['memax'] mean = conf['mean'] std = conf['std'] train_buildings = conf['train_buildings'] test_building = conf['test_building'] on_threshold = conf['on_threshold'] meter_key = conf['nilmtk_key'] save_path = conf['save_path'] # ======= Training phase print("Training for device: {}".format(key_name)) print(" train_buildings: {}".format(train_buildings)) # Open train sets X_train = np.load("dataset/trainsets/X-{}.npy".format(key_name)) X_train = normalize(X_train, mamax, mean, std) y_train = np.load("dataset/trainsets/Y-{}.npy".format(key_name)) y_train = normalize(y_train, memax, mean, std) model = create_model(input_window) # Train model and save checkpoints if start_e > 0: model = load_model( save_path + "CHECKPOINT-{}-{}epochs.hdf5".format(key_name, start_e)) if end_e > start_e: filepath = save_path + "CHECKPOINT-" + key_name + "-{epoch:01d}epochs.hdf5" checkpoint = ModelCheckpoint(filepath, verbose=1, save_best_only=False) history = model.fit(X_train, y_train, batch_size=128, epochs=(end_e - start_e), shuffle=True, initial_epoch=start_e, callbacks=[checkpoint]) losses = history.history['loss'] model.save( "{}CHECKPOINT-{}-{}epochs.hdf5".format(save_path, key_name, end_e), model) # Save training loss per epoch try: a = np.loadtxt("{}losses.csv".format(save_path)) losses = np.append(a, losses) except: pass np.savetxt("{}losses.csv".format(save_path), losses, delimiter=",") # ======= Disaggregation phase mains, meter = opends(test_building, key_name) X_test = normalize(mains, mamax, mean, std) y_test = meter # Predict data X_batch, Y_batch = gen_batch(X_test, y_test, len(X_test) - input_window, 0, input_window) pred = model.predict(X_batch) pred = denormalize(pred, memax, mean, std) pred[pred < 0] = 0 pred = np.transpose(pred)[0] # Save results np.save("{}pred-{}-epochs{}".format(save_path, key_name, end_e), pred) rpaf = metrics.recall_precision_accuracy_f1(pred, Y_batch, threshold) rete = metrics.relative_error_total_energy(pred, Y_batch) mae = metrics.mean_absolute_error(pred, Y_batch) print("============ Recall: {}".format(rpaf[0])) print("============ Precision: {}".format(rpaf[1])) print("============ Accuracy: {}".format(rpaf[2])) print("============ F1 Score: {}".format(rpaf[3])) print("============ Relative error in total energy: {}".format(rete)) print("============ Mean absolute error(in Watts): {}".format(mae)) res_out = open( "{}results-pred-{}-{}epochs".format(save_path, key_name, end_e), 'w') for r in rpaf: res_out.write(str(r)) res_out.write(',') res_out.write(str(rete)) res_out.write(',') res_out.write(str(mae)) res_out.close()
model.fit(X_train, y_train, batch_size=128, epochs=epochs_per_checkpoint, shuffle=True) model.save( "SYNTH-LOOKBACK-{}-ALL-{}epochs-1WIN.h5".format( key_name, epochs + epochs_per_checkpoint), model) # ======= Disaggregation phase mains, meter = opends(test_building, key_name) X_test = mains y_test = meter * mmax # Predict data X_batch, Y_batch = gen_batch(X_test, y_test, len(X_test) - input_window, 0, input_window) pred = model.predict(X_batch) * mmax pred[pred < 0] = 0 pred = np.transpose(pred)[0] # Save results np.save('pred.results', pred) # Calculate and show metrics print("============ Recall Precision Accurracy F1 {}".format( metrics.recall_precision_accuracy_f1(pred, Y_batch, threshold))) print("============ relative_error_total_energy {}".format( metrics.relative_error_total_energy(pred, Y_batch))) print("============ mean_absolute_error {}".format( metrics.mean_absolute_error(pred, Y_batch)))
def experiment(key_name, start_e, end_e): if (key_name not in allowed_key_names): conf_filename = "appconf/{}.json".format(key_name) with open(conf_filename) as data_file: conf = json.load(data_file) input_window = conf['lookback'] threshold = conf['on_threshold'] mamax = 5000 memax = conf['memax'] mean = conf['mean'] std = conf['std'] train_buildings = conf['train_buildings'] test_building = conf['test_building'] on_threshold = conf['on_threshold'] meter_key = conf['nilmtk_key'] save_path = conf['save_path'] X_train = np.load("dataset/trainsets/X-{}.npy".format(key_name)) X_train = normalize(X_train, mamax, mean, std) y_train = np.load("dataset/trainsets/Y-{}.npy".format(key_name)) y_train = normalize(y_train, memax, mean, std) model = create_model(input_window) if start_e>0: model = load_model(save_path+"CHECKPOINT-{}-{}epochs.hdf5".format(key_name, start_e)) if end_e > start_e: filepath = save_path+"CHECKPOINT-"+key_name+"-{epoch:01d}epochs.hdf5" checkpoint = ModelCheckpoint(filepath, verbose=1, save_best_only=False) history = model.fit(X_train, y_train, batch_size=128, epochs=end_e, shuffle=True, initial_epoch=start_e, callbacks=[checkpoint]) losses = history.history['loss'] model.save("{}CHECKPOINT-{}-{}epochs.hdf5".format(save_path, key_name, end_e),model) try: a = np.loadtxt("{}losses.csv".format(save_path)) losses = np.append(a,losses) except: pass np.savetxt("{}losses.csv".format(save_path), losses, delimiter=",") mains, meter = opends(test_building, key_name) X_test = normalize(mains, mamax, mean, std) y_test = meter X_batch, Y_batch = gen_batch(X_test, y_test, len(X_test)-input_window, 0, input_window) pred = model.predict(X_batch) pred = denormalize(pred, memax, mean, std) pred[pred<0] = 0 pred = np.transpose(pred)[0] np.save("{}pred-{}-epochs{}".format(save_path, key_name, end_e), pred) rpaf = metrics.recall_precision_accuracy_f1(pred, Y_batch, threshold) rete = metrics.relative_error_total_energy(pred, Y_batch) mae = metrics.mean_absolute_error(pred, Y_batch) res_out = open("{}results-pred-{}-{}epochs".format(save_path, key_name, end_e), 'w') for r in rpaf: res_out.write(str(r)) res_out.write(',') res_out.write(str(rete)) res_out.write(',') res_out.write(str(mae)) res_out.close() if __name__ == "__main__": if len(sys.argv) == 1 or sys.argv[1] == "": exit() key_name = sys.argv[1] experiment(key_name, 0, 7)
def runExperiment(experiment: experimentInfo, metricsResFileName, clearMetricsFile): dsPathsList_Test = experiment.dsList outFileName = experiment.outName test_building = experiment.building meter_key = experiment.meter_key pathOrigDS = experiment.pathOrigDS meterTH = experiment.meterTH print('House ', test_building) # Load a "complete" dataset to have the test's timerange test = DataSet(dsPathsList_Test[0]) test_elec = test.buildings[test_building].elec testRef_meter = test_elec.submeters( )[meter_key] # will be used as reference to align all meters based on this # Align every test meter with testRef_meter as master test_series_list = [] for path in dsPathsList_Test: test = DataSet(path) test_elec = test.buildings[test_building].elec test_meter = test_elec.submeters()[meter_key] # print('Stack test: ', test_meter.get_timeframe().start.date(), " - ", test_meter.get_timeframe().end.date()) aligned_meters = align_two_meters(testRef_meter, test_meter) test_series_list.append(aligned_meters) # Init vars for the output MIN_CHUNK_LENGTH = 300 # Depends on the basemodels of the ensemble timeframes = [] building_path = '/building{}'.format(test_meter.building()) mains_data_location = building_path + '/elec/meter1' data_is_available = False disag_filename = outFileName output_datastore = HDFDataStore(disag_filename, 'w') run = True chunkDataForOutput = None # -- Used to hold necessary data for saving the results using NILMTK (e.g. timeframes). # -- (in case where chunks have different size (not in current implementation), must use the chunk whose windowsSize is the least (to have all the data)) while run: try: testX = [] columnInd = 0 # Get Next chunk of each series for testXGen in test_series_list: chunkALL = next(testXGen) chunk = chunkALL[ 'slave'] # slave is the meter needed (master is only for aligning) chunk.fillna(0, inplace=True) if (columnInd == 0): chunkDataForOutput = chunk # Use 1st found chunk for it's metadata if (testX == []): testX = np.zeros( [len(chunk), len(test_series_list)] ) # Initialize the array that will hold all of the series as columns testX[:, columnInd] = chunk[:] columnInd += 1 testX = scaler.transform(testX) except: run = False break if len(chunkDataForOutput) < MIN_CHUNK_LENGTH: continue # print("New sensible chunk: {}".format(len(chunk))) startTime = chunkDataForOutput.index[0] endTime = chunkDataForOutput.index[ -1] # chunkDataForOutput.shape[0] - 1 # print('Start:',startTime,'End:',endTime) timeframes.append(TimeFrame( startTime, endTime)) #info needed for output for use with NILMTK measurement = ('power', 'active') pred = clf.predict(testX) column = pd.Series(pred, index=chunkDataForOutput.index, name=0) appliance_powers_dict = {} appliance_powers_dict[0] = column appliance_power = pd.DataFrame(appliance_powers_dict) appliance_power[appliance_power < 0] = 0 # Append prediction to output data_is_available = True cols = pd.MultiIndex.from_tuples([measurement]) meter_instance = test_meter.instance() df = pd.DataFrame(appliance_power.values, index=appliance_power.index, columns=cols, dtype="float32") key = '{}/elec/meter{}'.format(building_path, meter_instance) output_datastore.append(key, df) # Append aggregate data to output mains_df = pd.DataFrame(chunkDataForOutput, columns=cols, dtype="float32") # Note (For later): not 100% right. Should be mains. But it won't be used anywhere, so it doesn't matter in this case output_datastore.append(key=mains_data_location, value=mains_df) # Save metadata to output if data_is_available: disagr = Disaggregator() disagr.MODEL_NAME = 'Stacked model' disagr._save_metadata_for_disaggregation( output_datastore=output_datastore, sample_period=sample_period, measurement=measurement, timeframes=timeframes, building=test_meter.building(), meters=[test_meter]) #======================== Calculate Metrics ===================================== testYDS = DataSet(pathOrigDS) testYDS.set_window(start=test_meter.get_timeframe().start.date(), end=test_meter.get_timeframe().end.date()) testY_elec = testYDS.buildings[test_building].elec testY_meter = testY_elec.submeters()[meter_key] test_mains = testY_elec.mains() result = DataSet(disag_filename) res_elec = result.buildings[test_building].elec rpaf = metrics.recall_precision_accuracy_f1(res_elec[meter_key], testY_meter, meterTH, meterTH) relError = metrics.relative_error_total_energy(res_elec[meter_key], testY_meter) MAE = metrics.mean_absolute_error(res_elec[meter_key], testY_meter) RMSE = metrics.RMSE(res_elec[meter_key], testY_meter) print("============ Recall: {}".format(rpaf[0])) print("============ Precision: {}".format(rpaf[1])) print("============ Accuracy: {}".format(rpaf[2])) print("============ F1 Score: {}".format(rpaf[3])) print("============ Relative error in total energy: {}".format(relError)) print("============ Mean absolute error(in Watts): {}".format(MAE)) print("=== For docs: {:.4}\t{:.4}\t{:.4}\t{:.4}\t{:.4}\t{:.4}".format( rpaf[0], rpaf[1], rpaf[2], rpaf[3], relError, MAE)) # print("============ RMSE: {}".format(RMSE)) # print("============ TECA: {}".format(metrics.TECA([res_elec[meter_key]],[testY_meter],test_mains))) resDict = { 'model': 'TEST', 'building': test_building, 'Appliance': meter_key, 'Appliance_Type': 2, 'Recall': rpaf[0], 'Precision': rpaf[1], 'Accuracy': rpaf[2], 'F1': rpaf[3], 'relError': relError, 'MAE': MAE, 'RMSE': RMSE } metrics.writeResultsToCSV(resDict, metricsResFileName, clearMetricsFile)