def disaggregate_chunk(self, mains): """In-memory disaggregation. Parameters ---------- mains : pd.Series Returns ------- appliance_powers : pd.DataFrame where each column represents a disaggregated appliance. Column names are the integer index into `self.model` for the appliance in question. """ if not self.model: raise RuntimeError("The model needs to be instantiated before" " calling `disaggregate`. The model" " can be instantiated by running `train`.") if len(mains) < self.MIN_CHUNK_LENGTH: raise RuntimeError("Chunk is too short.") # Because CombinatorialOptimisation could have been trained using # either train() or train_on_chunk(), we must # set state_combinations here. self._set_state_combinations_if_necessary() """ # Add vampire power to the model if vampire_power is None: vampire_power = get_vampire_power(mains) if vampire_power > 0: print("Including vampire_power = {} watts to model..." .format(vampire_power)) n_rows = self.state_combinations.shape[0] vampire_power_array = np.zeros((n_rows, 1)) + vampire_power state_combinations = np.hstack( (self.state_combinations, vampire_power_array)) else: state_combinations = self.state_combinations """ state_combinations = self.state_combinations summed_power_of_each_combination = np.sum(state_combinations, axis=1) # summed_power_of_each_combination is now an array where each # value is the total power demand for each combination of states. # Start disaggregation indices_of_state_combinations, residual_power = find_nearest( summed_power_of_each_combination, mains.values) appliance_powers_dict = {} for i, model in enumerate(self.model): print("Estimating power demand for '{}'".format( model['training_metadata'])) predicted_power = state_combinations[indices_of_state_combinations, i].flatten() column = pd.Series(predicted_power, index=mains.index, name=i) appliance_powers_dict[self.model[i]['training_metadata']] = column appliance_powers = pd.DataFrame(appliance_powers_dict, dtype='float32') return appliance_powers
def disaggregate(self, test_mains): appliance_list = [appliance for appliance in self.model] list_of_appliances_centroids = [self.model[appliance] for appliance in appliance_list] states_combination = list(itertools.product (*list_of_appliances_centroids)) sum_combination = np.array(np.zeros(len(states_combination))) for i in range(0, len(states_combination)): sum_combination[i] = sum(states_combination[i]) length_sequence = len(test_mains.values) states = np.zeros(length_sequence) residual_power = np.zeros(length_sequence) for i in range(length_sequence): [states[i], residual_power[i]] = find_nearest(sum_combination,test_mains.values[i]) [predicted_states, predicted_power] = decode_co(length_sequence, self.model, appliance_list, states, residual_power) self.predictions = pd.DataFrame(predicted_power)
def disaggregate(self, test_mains): appliance_list = [appliance for appliance in self.model] list_of_appliances_centroids = [ self.model[appliance] for appliance in appliance_list ] states_combination = list( itertools.product(*list_of_appliances_centroids)) sum_combination = np.array(np.zeros(len(states_combination))) for i in range(0, len(states_combination)): sum_combination[i] = sum(states_combination[i]) length_sequence = len(test_mains.values) states = np.zeros(length_sequence) residual_power = np.zeros(length_sequence) for i in range(length_sequence): [states[i], residual_power[i]] = find_nearest(sum_combination, test_mains.values[i]) [predicted_states, predicted_power] = decode_co(length_sequence, self.model, appliance_list, states, residual_power) self.predictions = pd.DataFrame(predicted_power)
def disaggregate_chunk(self, mains, vampire_power=None): """In-memory disaggregation. Parameters ---------- mains : pd.Series vampire_power : None or number (watts) If None then will automatically determine vampire power from data. If you do not want to use vampire power then set vampire_power = 0. Returns ------- appliance_powers : pd.DataFrame where each column represents a disaggregated appliance. Column names are the integer index into `self.model` for the appliance in question. """ if not self.model: raise RuntimeError("The model needs to be instantiated before" " calling `disaggregate`. The model" " can be instantiated by running `train`.") if len(mains) < self.MIN_CHUNK_LENGTH: raise RuntimeError("Chunk is too short.") # sklearn produces lots of DepreciationWarnings with PyTables import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) # Because CombinatorialOptimisation could have been trained using # either train() or train_on_chunk(), we must # set state_combinations here. self._set_state_combinations_if_necessary() # Add vampire power to the model if vampire_power is None: vampire_power = get_vampire_power(mains) if vampire_power > 0: print("Including vampire_power = {} watts to model...".format( vampire_power)) n_rows = self.state_combinations.shape[0] vampire_power_array = np.zeros((n_rows, 1)) + vampire_power state_combinations = np.hstack( (self.state_combinations, vampire_power_array)) else: state_combinations = self.state_combinations summed_power_of_each_combination = np.sum(state_combinations, axis=1) # summed_power_of_each_combination is now an array where each # value is the total power demand for each combination of states. # Start disaggregation indices_of_state_combinations, residual_power = find_nearest( summed_power_of_each_combination, mains.values) # add priority last_combi = summed_power_of_each_combination[ indices_of_state_combinations[0]] indices_test = indices_of_state_combinations for i in range(len(indices_test) - 1): delta = self.get_tolerance_margin(mains.values[i + 1]) #delta = 25 if abs(mains.values[i + 1] - last_combi) <= delta: indices_test[i + 1] = indices_test[i] else: last_combi = summed_power_of_each_combination[indices_test[i + 1]] indices_of_state_combinations = indices_test appliance_powers_dict = {} for i, model in enumerate(self.model): print("Estimating power demand for '{}'".format( model['training_metadata'])) predicted_power = state_combinations[indices_of_state_combinations, i].flatten() column = pd.Series(predicted_power, index=mains.index, name=i) appliance_powers_dict[i] = column appliance_powers = pd.DataFrame(appliance_powers_dict) return appliance_powers
def disaggregate(self, mains, output_datastore, location_data=None, mains_values=None, baseline=None, **load_kwargs): from sklearn.utils.extmath import cartesian import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) # Get centroids centroids = [model['states'] for model in self.model] state_combinations = cartesian(centroids) try: timezone = location_data.dataset.metadata.get('timezone') except Exception: timezone = '' vampire_power = baseline if baseline is None: vampire_power = mains.vampire_power() #- correction n_rows = state_combinations.shape[0] vampire_power_array = np.zeros((n_rows, 1)) + vampire_power state_combinations = np.hstack((state_combinations, vampire_power_array)) print("vampire_power = {} watts".format(vampire_power)) summed_power_of_each_combination = np.sum(state_combinations, axis=1) self.vampire_power = vampire_power self.state_combinations_all = state_combinations self.summed_power_of_each_combination_all = summed_power_of_each_combination resample_seconds = load_kwargs.pop('resample_seconds', 60) load_kwargs.setdefault('resample', True) load_kwargs.setdefault('sample_period', resample_seconds) timeframes = [] building_path = '/building{}'.format(mains.building()) mains_data_location = '{}/elec/meter1'.format(building_path) if mains_values is None: load_kwargs['sections'] = load_kwargs.pop('sections', mains.good_sections()) mains_values = mains.power_series(**load_kwargs) using_series = False else: mains_values = [mains_values] using_series = True self.mains_used = mains_values self.location_used = 0 self.location_loop = 0 self.co_indices_original = [] self.co_indices_location = [] #No longer applies since indices constantly change after each iteration. We now return the combo self.co_residuals_original = [] self.co_residuals_location = [] self.co_combos_location = [] for chunk in mains_values: # Record metadata if using_series: timeframes.append(TimeFrame(start=chunk.index[0], end=chunk.index[-1])) measurement = ('power', 'apparent') else: timeframes.append(chunk.timeframe) measurement = chunk.name # Start disaggregation print('Calculating original indices of state combinations...') indices_of_state_combinations_original, residuals_power_original = find_nearest( summed_power_of_each_combination, chunk.values) self.co_indices_original.extend(indices_of_state_combinations_original) self.co_residuals_original.extend(residuals_power_original) print('Calculating indices of state combinations...') state_combinations_location, residuals_power_location = self.find_nearest( chunk, location_data, vampire_power, resample_seconds) self.co_combos_location.extend(state_combinations_location) self.co_residuals_location.extend(residuals_power_location) #Write results for i, model in enumerate(self.model): print("Estimating power demand for '{}'".format(model['training_metadata'])) predicted_power = state_combinations_location[:, i].flatten() cols = pd.MultiIndex.from_tuples([measurement]) meter_instance = model['training_metadata'].instance() output_datastore.append('{}/elec/meter{}' .format(building_path, meter_instance), pd.DataFrame(predicted_power, index=chunk.index, columns=cols)) # Copy mains data to disag output output_datastore.append(key=mains_data_location, value=pd.DataFrame(chunk, columns=cols)) ################################## # Add metadata to output_datastore self.add_metadata(output_datastore, measurement, timeframes, mains, timezone, load_kwargs)
def disaggregate_chunk(self, mains): """In-memory disaggregation. Parameters ---------- mains : pd.Series Returns ------- appliance_powers : pd.DataFrame where each column represents a disaggregated appliance. Column names are the integer index into `self.model` for the appliance in question. """ '''if not self.model: raise RuntimeError( "The model needs to be instantiated before" " calling `disaggregate`. The model" " can be instantiated by running `train`.")''' print("...............CO disaggregate_chunk running.............") # sklearn produces lots of DepreciationWarnings with PyTables import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) # Because CombinatorialOptimisation could have been trained using # either train() or train_on_chunk(), we must # set state_combinations here. self._set_state_combinations_if_necessary() """ # Add vampire power to the model if vampire_power is None: vampire_power = get_vampire_power(mains) if vampire_power > 0: print("Including vampire_power = {} watts to model..." .format(vampire_power)) n_rows = self.state_combinations.shape[0] vampire_power_array = np.zeros((n_rows, 1)) + vampire_power state_combinations = np.hstack( (self.state_combinations, vampire_power_array)) else: state_combinations = self.state_combinations """ state_combinations = self.state_combinations summed_power_of_each_combination = np.sum(state_combinations, axis=1) # summed_power_of_each_combination is now an array where each # value is the total power demand for each combination of states. # Start disaggregation test_prediction_list = [] for test_df in mains: appliance_powers_dict = {} indices_of_state_combinations, residual_power = find_nearest( summed_power_of_each_combination, test_df.values) for i, model in enumerate(self.model): print("Estimating power demand for '{}'".format( model['appliance_name'])) predicted_power = state_combinations[ indices_of_state_combinations, i].flatten() column = pd.Series(predicted_power, index=test_df.index, name=i) appliance_powers_dict[self.model[i]['appliance_name']] = column appliance_powers = pd.DataFrame(appliance_powers_dict, dtype='float32') test_prediction_list.append(appliance_powers) return test_prediction_list
def disaggregate_chunk(self, mains): """In-memory disaggregation. Parameters ---------- mains : pd.Series Returns ------- appliance_powers : pd.DataFrame where each column represents a disaggregated appliance. Column names are the integer index into `self.model` for the appliance in question. """ if not self.model: raise RuntimeError( "The model needs to be instantiated before" " calling `disaggregate`. The model" " can be instantiated by running `train`.") if len(mains) < self.MIN_CHUNK_LENGTH: raise RuntimeError("Chunk is too short.") # sklearn produces lots of DepreciationWarnings with PyTables import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) # Because CombinatorialOptimisation could have been trained using # either train() or train_on_chunk(), we must # set state_combinations here. self._set_state_combinations_if_necessary() """ # Add vampire power to the model if vampire_power is None: vampire_power = get_vampire_power(mains) if vampire_power > 0: print("Including vampire_power = {} watts to model..." .format(vampire_power)) n_rows = self.state_combinations.shape[0] vampire_power_array = np.zeros((n_rows, 1)) + vampire_power state_combinations = np.hstack( (self.state_combinations, vampire_power_array)) else: state_combinations = self.state_combinations """ state_combinations = self.state_combinations summed_power_of_each_combination = np.sum(state_combinations, axis=1) # summed_power_of_each_combination is now an array where each # value is the total power demand for each combination of states. # Start disaggregation indices_of_state_combinations, residual_power = find_nearest( summed_power_of_each_combination, mains.values) appliance_powers_dict = {} for i, model in enumerate(self.model): print("Estimating power demand for '{}'" .format(model['training_metadata'])) predicted_power = state_combinations[ indices_of_state_combinations, i].flatten() column = pd.Series(predicted_power, index=mains.index, name=i) appliance_powers_dict[self.model[i]['training_metadata']] = column appliance_powers = pd.DataFrame(appliance_powers_dict, dtype='float32') return appliance_powers
def disaggregate(self, mains, output_datastore, location_data=None, mains_values=None, baseline=None, **load_kwargs): from sklearn.utils.extmath import cartesian import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) # Get centroids centroids = [model['states'] for model in self.model] state_combinations = cartesian(centroids) try: timezone = location_data.dataset.metadata.get('timezone') except Exception: timezone = '' vampire_power = baseline if baseline is None: vampire_power = mains.vampire_power() #- correction n_rows = state_combinations.shape[0] vampire_power_array = np.zeros((n_rows, 1)) + vampire_power state_combinations = np.hstack( (state_combinations, vampire_power_array)) print("vampire_power = {} watts".format(vampire_power)) summed_power_of_each_combination = np.sum(state_combinations, axis=1) self.vampire_power = vampire_power self.state_combinations_all = state_combinations self.summed_power_of_each_combination_all = summed_power_of_each_combination resample_seconds = load_kwargs.pop('resample_seconds', 60) load_kwargs.setdefault('resample', True) load_kwargs.setdefault('sample_period', resample_seconds) timeframes = [] building_path = '/building{}'.format(mains.building()) mains_data_location = '{}/elec/meter1'.format(building_path) if mains_values is None: load_kwargs['sections'] = load_kwargs.pop('sections', mains.good_sections()) mains_values = mains.power_series(**load_kwargs) using_series = False else: mains_values = [mains_values] using_series = True self.mains_used = mains_values self.location_used = 0 self.location_loop = 0 self.co_indices_original = [] self.co_indices_location = [ ] #No longer applies since indices constantly change after each iteration. We now return the combo self.co_residuals_original = [] self.co_residuals_location = [] self.co_combos_location = [] for chunk in mains_values: # Record metadata if using_series: timeframes.append( TimeFrame(start=chunk.index[0], end=chunk.index[-1])) measurement = ('power', 'apparent') else: timeframes.append(chunk.timeframe) measurement = chunk.name # Start disaggregation print('Calculating original indices of state combinations...') indices_of_state_combinations_original, residuals_power_original = find_nearest( summed_power_of_each_combination, chunk.values) self.co_indices_original.extend( indices_of_state_combinations_original) self.co_residuals_original.extend(residuals_power_original) print('Calculating indices of state combinations...') state_combinations_location, residuals_power_location = self.find_nearest( chunk, location_data, vampire_power, resample_seconds) self.co_combos_location.extend(state_combinations_location) self.co_residuals_location.extend(residuals_power_location) #Write results for i, model in enumerate(self.model): print("Estimating power demand for '{}'".format( model['training_metadata'])) predicted_power = state_combinations_location[:, i].flatten() cols = pd.MultiIndex.from_tuples([measurement]) meter_instance = model['training_metadata'].instance() output_datastore.append( '{}/elec/meter{}'.format(building_path, meter_instance), pd.DataFrame(predicted_power, index=chunk.index, columns=cols)) # Copy mains data to disag output output_datastore.append(key=mains_data_location, value=pd.DataFrame(chunk, columns=cols)) ################################## # Add metadata to output_datastore self.add_metadata(output_datastore, measurement, timeframes, mains, timezone, load_kwargs)