Example #1
0
    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
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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)