Module ifra.aggregations

Expand source code
from typing import List
from ruleskit import RuleSet
import logging
from .duplicated_rules_updater import update_duplicated_rules

logger = logging.getLogger(__name__)


class Aggregation:
    """Abstract class for aggregating node models."""

    # noinspection PyUnresolvedReferences
    def __init__(self, aggregator: "Aggregator", **kwargs):
        """
        Parameters
        ----------
        aggregator: CentralServer
            `ifra.aggregator.Aggregator` object
        kwargs:
            Any additionnal keyword argument that the overleading class accepts. Those arguments will become attributes.
        """
        self.aggregator = aggregator
        for arg in kwargs:
            setattr(self, arg, kwargs[arg])

    def _aggregate(self, rulesets: List[RuleSet]) -> str:
        """To be implemented in daughter class.
        Aggregates the node models into aggregated model. Must NOT drop duplicated rules.

        Parameters
        ----------
        rulesets: List[RuleSet]
            New rulesets provided by the nodes.

        Returns
        -------
        str\n
          * "updated" if new rules were found\n
          * "pass" otherwise
        """
        pass

    def aggregate(self, rulesets: List[RuleSet]) -> str:
        """
        Aggregates the node models into aggregated model. Will handle the fact that rules will be duplicated by
        using `ifra.aggegations.aggregator_rules_attributes_setter`.

        Parameters
        ----------
        rulesets: List[RuleSet]
            New rulesets provided by the nodes.

        Returns
        -------
        str\n
          * "updated" if new rules were found\n
          * "pass" otherwise
        """
        aggregated = self._aggregate(rulesets)
        if aggregated == "updated":
            success = update_duplicated_rules(
                self.aggregator.model,
                self.aggregator.aggregator_configs.weight,
                self.aggregator.aggregator_configs.best,
                name="Aggregation"
            )
            if not success:
                self.aggregator.model = None
                aggregated = "Nein!"
            else:
                logger.info(f"Aggrgation - Aggregated {len(self.aggregator.model)} new rules")
        return aggregated


class AdaBoostAggregation(Aggregation):
    """Among all rules generated by the nodes in the current iteration, will keep only the most recurrent rule(s).

    Can be used by giving *adaboost* as *aggregation* argument when creating`ifra.aggregator.Aggregator`.
    """

    def _aggregate(self, rulesets: List[RuleSet]) -> str:
        """In AdaBoostAggregation, 'aggregate' only returns "updated", for bad and already known rules should have been
        filtered out by the nodes already."""
        logger.info("Aggrgation - Aggregating fit results using AdaBoost method...")
        all_rules = []

        for rs in rulesets:
            all_rules += rs.rules

        occurences = {r: all_rules.count(r) for r in set(all_rules)}

        max_occurences = max(list(occurences.values()))

        new_rules = RuleSet()

        for r in occurences:
            if occurences[r] == max_occurences:
                for rs in rulesets:
                    for r2 in rs:
                        if r2 == r:
                            new_rules.append(r, update_activation=False)

        del self.aggregator.model
        self.aggregator.model = new_rules
        return "updated"


class ReverseAdaBoostAggregation(Aggregation):
    """Among all rules generated by the nodes in the current iteration, will keep only the least recurrent rule(s).

    Can be used by giving *reverseadaboost* as *aggregation* argument when creating`ifra.aggregator.Aggregator`.
    """

    def _aggregate(self, rulesets: List[RuleSet]) -> str:
        """In ReverseAdaBoostAggregation, 'aggregate' only returns "updated", for bad and already known rules should
        have been filtered out by the nodes already."""
        logger.info("Aggrgation - Aggregating fit results using ReverseAdaBoost method...")
        all_rules = []

        for rs in rulesets:
            all_rules += rs.rules

        occurences = {r: all_rules.count(r) for r in set(all_rules)}

        max_occurences = min(list(occurences.values()))

        new_rules = RuleSet()

        for r in occurences:
            if occurences[r] == max_occurences:
                for rs in rulesets:
                    for r2 in rs:
                        if r2 == r:
                            new_rules.append(r, update_activation=False)

        del self.aggregator.model
        self.aggregator.model = new_rules
        return "updated"


class AggregateAll(Aggregation):
    """Keep al rules.

    Can be used by giving *keepall* as *aggregation* argument when creating`ifra.aggregator.Aggregator`.
    """

    def _aggregate(self, rulesets: List[RuleSet]) -> str:
        """In AggregateAll, 'aggregate' only returns "updated", for bad and already known rules should
        have been filtered out by the nodes already."""
        logger.info("Aggrgation - Aggregating fit results using AggregateAll method...")
        all_rules = []

        for rs in rulesets:
            all_rules += rs.rules

        new_rules = RuleSet(rules_list=list(set(all_rules)))

        del self.aggregator.model
        self.aggregator.model = new_rules
        return "updated"

Classes

class AdaBoostAggregation (aggregator: Aggregator, **kwargs)

Among all rules generated by the nodes in the current iteration, will keep only the most recurrent rule(s).

Can be used by giving adaboost as aggregation argument when creatingAggregator.

Parameters

aggregator : CentralServer
Aggregator object

kwargs: Any additionnal keyword argument that the overleading class accepts. Those arguments will become attributes.

Expand source code
class AdaBoostAggregation(Aggregation):
    """Among all rules generated by the nodes in the current iteration, will keep only the most recurrent rule(s).

    Can be used by giving *adaboost* as *aggregation* argument when creating`ifra.aggregator.Aggregator`.
    """

    def _aggregate(self, rulesets: List[RuleSet]) -> str:
        """In AdaBoostAggregation, 'aggregate' only returns "updated", for bad and already known rules should have been
        filtered out by the nodes already."""
        logger.info("Aggrgation - Aggregating fit results using AdaBoost method...")
        all_rules = []

        for rs in rulesets:
            all_rules += rs.rules

        occurences = {r: all_rules.count(r) for r in set(all_rules)}

        max_occurences = max(list(occurences.values()))

        new_rules = RuleSet()

        for r in occurences:
            if occurences[r] == max_occurences:
                for rs in rulesets:
                    for r2 in rs:
                        if r2 == r:
                            new_rules.append(r, update_activation=False)

        del self.aggregator.model
        self.aggregator.model = new_rules
        return "updated"

Ancestors

Inherited members

class AggregateAll (aggregator: Aggregator, **kwargs)

Keep al rules.

Can be used by giving keepall as aggregation argument when creatingAggregator.

Parameters

aggregator : CentralServer
Aggregator object

kwargs: Any additionnal keyword argument that the overleading class accepts. Those arguments will become attributes.

Expand source code
class AggregateAll(Aggregation):
    """Keep al rules.

    Can be used by giving *keepall* as *aggregation* argument when creating`ifra.aggregator.Aggregator`.
    """

    def _aggregate(self, rulesets: List[RuleSet]) -> str:
        """In AggregateAll, 'aggregate' only returns "updated", for bad and already known rules should
        have been filtered out by the nodes already."""
        logger.info("Aggrgation - Aggregating fit results using AggregateAll method...")
        all_rules = []

        for rs in rulesets:
            all_rules += rs.rules

        new_rules = RuleSet(rules_list=list(set(all_rules)))

        del self.aggregator.model
        self.aggregator.model = new_rules
        return "updated"

Ancestors

Inherited members

class Aggregation (aggregator: Aggregator, **kwargs)

Abstract class for aggregating node models.

Parameters

aggregator : CentralServer
Aggregator object

kwargs: Any additionnal keyword argument that the overleading class accepts. Those arguments will become attributes.

Expand source code
class Aggregation:
    """Abstract class for aggregating node models."""

    # noinspection PyUnresolvedReferences
    def __init__(self, aggregator: "Aggregator", **kwargs):
        """
        Parameters
        ----------
        aggregator: CentralServer
            `ifra.aggregator.Aggregator` object
        kwargs:
            Any additionnal keyword argument that the overleading class accepts. Those arguments will become attributes.
        """
        self.aggregator = aggregator
        for arg in kwargs:
            setattr(self, arg, kwargs[arg])

    def _aggregate(self, rulesets: List[RuleSet]) -> str:
        """To be implemented in daughter class.
        Aggregates the node models into aggregated model. Must NOT drop duplicated rules.

        Parameters
        ----------
        rulesets: List[RuleSet]
            New rulesets provided by the nodes.

        Returns
        -------
        str\n
          * "updated" if new rules were found\n
          * "pass" otherwise
        """
        pass

    def aggregate(self, rulesets: List[RuleSet]) -> str:
        """
        Aggregates the node models into aggregated model. Will handle the fact that rules will be duplicated by
        using `ifra.aggegations.aggregator_rules_attributes_setter`.

        Parameters
        ----------
        rulesets: List[RuleSet]
            New rulesets provided by the nodes.

        Returns
        -------
        str\n
          * "updated" if new rules were found\n
          * "pass" otherwise
        """
        aggregated = self._aggregate(rulesets)
        if aggregated == "updated":
            success = update_duplicated_rules(
                self.aggregator.model,
                self.aggregator.aggregator_configs.weight,
                self.aggregator.aggregator_configs.best,
                name="Aggregation"
            )
            if not success:
                self.aggregator.model = None
                aggregated = "Nein!"
            else:
                logger.info(f"Aggrgation - Aggregated {len(self.aggregator.model)} new rules")
        return aggregated

Subclasses

Methods

def aggregate(self, rulesets: List[ruleskit.ruleset.RuleSet]) ‑> str

Aggregates the node models into aggregated model. Will handle the fact that rules will be duplicated by using ifra.aggegations.aggregator_rules_attributes_setter.

Parameters

rulesets : List[RuleSet]
New rulesets provided by the nodes.

Returns

str
 
  • "updated" if new rules were found

  • "pass" otherwise

Expand source code
def aggregate(self, rulesets: List[RuleSet]) -> str:
    """
    Aggregates the node models into aggregated model. Will handle the fact that rules will be duplicated by
    using `ifra.aggegations.aggregator_rules_attributes_setter`.

    Parameters
    ----------
    rulesets: List[RuleSet]
        New rulesets provided by the nodes.

    Returns
    -------
    str\n
      * "updated" if new rules were found\n
      * "pass" otherwise
    """
    aggregated = self._aggregate(rulesets)
    if aggregated == "updated":
        success = update_duplicated_rules(
            self.aggregator.model,
            self.aggregator.aggregator_configs.weight,
            self.aggregator.aggregator_configs.best,
            name="Aggregation"
        )
        if not success:
            self.aggregator.model = None
            aggregated = "Nein!"
        else:
            logger.info(f"Aggrgation - Aggregated {len(self.aggregator.model)} new rules")
    return aggregated
class ReverseAdaBoostAggregation (aggregator: Aggregator, **kwargs)

Among all rules generated by the nodes in the current iteration, will keep only the least recurrent rule(s).

Can be used by giving reverseadaboost as aggregation argument when creatingAggregator.

Parameters

aggregator : CentralServer
Aggregator object

kwargs: Any additionnal keyword argument that the overleading class accepts. Those arguments will become attributes.

Expand source code
class ReverseAdaBoostAggregation(Aggregation):
    """Among all rules generated by the nodes in the current iteration, will keep only the least recurrent rule(s).

    Can be used by giving *reverseadaboost* as *aggregation* argument when creating`ifra.aggregator.Aggregator`.
    """

    def _aggregate(self, rulesets: List[RuleSet]) -> str:
        """In ReverseAdaBoostAggregation, 'aggregate' only returns "updated", for bad and already known rules should
        have been filtered out by the nodes already."""
        logger.info("Aggrgation - Aggregating fit results using ReverseAdaBoost method...")
        all_rules = []

        for rs in rulesets:
            all_rules += rs.rules

        occurences = {r: all_rules.count(r) for r in set(all_rules)}

        max_occurences = min(list(occurences.values()))

        new_rules = RuleSet()

        for r in occurences:
            if occurences[r] == max_occurences:
                for rs in rulesets:
                    for r2 in rs:
                        if r2 == r:
                            new_rules.append(r, update_activation=False)

        del self.aggregator.model
        self.aggregator.model = new_rules
        return "updated"

Ancestors

Inherited members