示例#1
0
 def __init__(self,
              preprocessor=None,
              convergence=None,
              personalization_transform: Postprocessor = None,
              preserve_norm: bool = True,
              **kwargs):
     """
     Args:
         preprocessor: Optional. Method to extract a scipy sparse matrix from a networkx graph.
             If None (default), pygrank.algorithms.utils.preprocessor is used with keyword arguments
             automatically extracted from the ones passed to this constructor.
         convergence: Optional. The ConvergenceManager that determines when iterations stop. If None (default),
             a ConvergenceManager is used with keyword arguments
             automatically extracted from the ones passed to this constructor.
         personalization_transform: Optional. A Postprocessor whose `transform` method is used to transform
             the personalization before applying the graph filter. If None (default) a Tautology is used.
         preserve_norm: Optional. If True (default) the input's norm is used to scale the output. For example,
             if *convergence* is L1, this effectively means that the sum of output values is equal to the sum
             of input values.
     """
     self.preprocessor = call(
         default_preprocessor,
         kwargs) if preprocessor is None else preprocessor
     self.convergence = call(ConvergenceManager,
                             kwargs) if convergence is None else convergence
     self.personalization_transform = Tautology(
     ) if personalization_transform is None else personalization_transform
     self.preserve_norm = preserve_norm
     ensure_used_args(kwargs, [default_preprocessor, ConvergenceManager])
示例#2
0
 def _transform(self, ranks: GraphSignal, **kwargs):
     ensure_used_args(kwargs)
     return {
         v: order + 1
         for order, v in enumerate(
             sorted(ranks, key=ranks.get, reverse=True))
     }
示例#3
0
    def __init__(self,
                 ranker_generator: Callable[[list], NodeRanking] = None,
                 measure: Callable[[GraphSignal, GraphSignal],
                                   Supervised] = Cos,
                 basis: Optional[str] = "Krylov",
                 tuning_backend: Optional[str] = None,
                 autoregression: int = 0,
                 num_parameters: int = 20,
                 tunable_offset: Optional[Callable[[GraphSignal, GraphSignal],
                                                   Supervised]] = None,
                 pre_diffuse: Optional[NodeRanking] = None,
                 **kwargs):
        """
        Instantiates the tuning mechanism.
        Args:
            ranker_generator: A callable that constructs a ranker based on a list of parameters.
                If None (default) then a pygrank.algorithms.learnable.GenericGraphFilter
                is constructed with automatic normalization and assuming immutability (this is the most common setting).
                These parameters can be overriden and other ones can be passed to the algorithm'personalization constructor simply
                by including them in kwargs.
            measure: Callable to constuct a supervised measure with given known node scores.
            basis: Can use either the "Krylov" or the "Arnoldi" orthonormal basis of the krylov space.
                The latter does not produce a ranking algorithm.
            tuning_backend: Specifically switches to a designted backend for the tuning process before restoring
                the previous one to perform the actual ranking. If None (default), this functionality is ignored.
            tunable_offset: If None, no offset is added to estimated parameters. Otherwise, a supervised measure
                generator (e.g. a supervised measure class) can be passed. Default is `pygrank.AUC`.
            kwargs: Additional arguments are passed to the automatically instantiated GenericGraphFilter.

        Example:
            >>> import pygrank as pg
            >>> graph, personalization = ...
            >>> tuner = pg.HopTuner(measure=AUC)
            >>> ranks = tuner.rank(graph, personalization)
        """
        if ranker_generator is None:
            if "optimization_dict" not in kwargs:
                kwargs["optimization_dict"] = SelfClearDict()
            from pygrank.algorithms import GenericGraphFilter

            def ranker_generator(params):
                return GenericGraphFilter(params, **kwargs)
        else:
            ensure_used_args(kwargs, [])
        self.ranker_generator = ranker_generator
        self.measure = measure
        self.tuning_backend = tuning_backend
        self.autoregression = autoregression
        self.num_parameters = num_parameters
        self.tunable_offset = tunable_offset
        self.pre_diffuse = pre_diffuse
        self.basis = basis.lower()
示例#4
0
 def _transform(self,
                ranks: GraphSignal,
                **kwargs):
     ensure_used_args(kwargs)
     threshold = 0
     fraction_of_training = self.fraction_of_training*backend.length(ranks) if self.fraction_of_training < 1 else self.fraction_of_training
     fraction_of_training = int(fraction_of_training)
     for v in sorted(ranks, key=ranks.get, reverse=True):
         fraction_of_training -= 1
         if fraction_of_training == 0:
             threshold = ranks[v]
             break
     return {v: 1. if ranks[v] >= threshold else 0. for v in ranks.keys()}
示例#5
0
 def _transform(self, ranks: GraphSignal, **kwargs):
     ensure_used_args(kwargs)
     threshold = self.threshold
     if threshold == "gap":
         # TODO maybe enable ranks = {v: ranks[v] / ranks.graph.degree(v) for v in ranks} with a postprocessor
         max_diff = 0
         threshold = 0
         prev_rank = 0
         for v in sorted(ranks, key=ranks.get, reverse=True):
             if prev_rank > 0:
                 diff = (prev_rank - ranks[v]) / prev_rank
                 if diff > max_diff:
                     max_diff = diff
                     threshold = ranks[v]
             prev_rank = ranks[v]
     return {v: 1 if ranks[v] >= threshold else 0 for v in ranks.keys()}
示例#6
0
 def _transform(self, ranks: GraphSignal, **kwargs):
     ensure_used_args(kwargs)
     min_rank = 0
     if self.method == "range":
         max_rank = float(backend.max(ranks.np))
         min_rank = float(backend.min(ranks.np))
     elif self.method == "max":
         max_rank = float(backend.max(ranks.np))
     elif self.method == "sum":
         max_rank = float(backend.sum(ranks.np))
     else:
         raise Exception("Can only normalize towards max or sum")
     if min_rank == max_rank:
         return ranks
     ret = (ranks.np - min_rank) / (max_rank - min_rank)
     return ret
示例#7
0
 def __init__(self,
              preprocessor=None,
              convergence=None,
              personalization_transform: Postprocessor = None,
              **kwargs):
     """
     Args:
         preprocessor: Optional. Method to extract a scipy sparse matrix from a networkx graph.
             If None (default), pygrank.algorithms.utils.preprocessor is used with keyword arguments
             automatically extracted from the ones passed to this constructor.
         convergence: Optional. The ConvergenceManager that determines when iterations stop. If None (default),
             a ConvergenceManager is used with keyword arguments
             automatically extracted from the ones passed to this constructor.
         personalization_transform: Optional. A Postprocessor whose `transform` method is used to transform
             the personalization before applying the graph filter. If None (default) a Tautology is used.
     """
     self.preprocessor = call(
         default_preprocessor,
         kwargs) if preprocessor is None else preprocessor
     self.convergence = call(ConvergenceManager,
                             kwargs) if convergence is None else convergence
     self.personalization_transform = Tautology(
     ) if personalization_transform is None else personalization_transform
     ensure_used_args(kwargs, [default_preprocessor, ConvergenceManager])
示例#8
0
    def __init__(self,
                 ranker_generator: Callable[[list], NodeRanking] = None,
                 measure: Callable[[GraphSignal, GraphSignal], Measure] = AUC,
                 fraction_of_training: float = 0.8,
                 combined_prediction: bool = True,
                 tuning_backend: str = None,
                 **kwargs):
        """
        Instantiates the tuning mechanism.
        Args:
            ranker_generator: A callable that constructs a ranker based on a list of parameters.
                If None (default) then a pygrank.algorithms.learnable.GenericGraphFilter
                is constructed with automatic normalization and assuming immutability (this is the most common setting).
                These parameters can be overriden and other ones can be passed to the algorithm'personalization
                constructor by including them in kwargs.
            measure: Callable to constuct a supervised measure with given known node scores and an iterable of excluded
                scores.
            fraction_of_training: A number in (0,1) indicating how to split provided graph signals into training and
                validaton ones by randomly sampling training nodes to meet the required fraction of all graph nodes.
                Numbers outside this range can also be used (not recommended without specific reason) per the
                conventions of `pygrank.split(...)`. Default is 0.8.
            combined_prediction: If True (default), after the best version of algorithms is determined, the whole
                personalization is used to produce the end-result. Otherwise, only the training portion of the
                training-validation split is used.
            tuning_backend: Specifically switches to a designted backend for the tuning process before restoring
                the previous one to perform the actual ranking. If None (default), this functionality is ignored.
            kwargs: Additional arguments can be passed to pygrank.algorithms.autotune.optimization.optimize. Otherwise,
                the respective arguments are retrieved from the variable *default_tuning_optimization*, which is crafted
                for fast convergence of the default ranker_generator. Arguments passable to the ranker_generator are
                also passed to it.
                Make sure to declare both the upper **and** the lower bounds of parameter values.

        Example:
            >>> import pygrank as pg
            >>> graph, personalization = ...
            >>> tuner = pg.ParameterTuner(measure=AUC, deviation_tol=0.01)
            >>> ranks = tuner.rank(graph, personalization)

        Example to tune pagerank'personalization float parameter alpha in the range [0.5, 0.99]:
            >>> import pygrank as pg
            >>> graph, personalization = ...
            >>> tuner = pg.ParameterTuner(lambda params: pg.PageRank(alpha=params[0]),
            >>>                           measure=AUC, deviation_tol=0.01, max_vals=[0.99], min_vals=[0.5])
            >>> ranks = tuner.rank(graph, personalization)
        """
        if ranker_generator is None:
            from pygrank.algorithms import GenericGraphFilter
            if 'preprocessor' not in kwargs and 'assume_immutability' not in kwargs and 'normalization' not in kwargs:
                kwargs['preprocessor'] = preprocessor(assume_immutability=True)
            if "optimization_dict" not in kwargs:
                kwargs["optimization_dict"] = SelfClearDict()

            def ranker_generator(params):
                return GenericGraphFilter(params,
                                          **remove_used_args(optimize, kwargs))
        else:
            ensure_used_args(kwargs, [optimize])
        self.ranker_generator = ranker_generator
        self.measure = measure
        self.fraction_of_training = fraction_of_training
        self.optimize_args = {
            kwarg: kwargs.get(kwarg, val)
            for kwarg, val in default_tuning_optimization.items()
        }
        self.combined_prediction = combined_prediction
        self.tuning_backend = tuning_backend
示例#9
0
 def _transform(self,
                ranks: GraphSignal,
                **kwargs):
     ensure_used_args(kwargs)
     uniforms = self.centrality(ranks.graph).np
     return ranks.np - uniforms
示例#10
0
 def _transform(self, ranks: GraphSignal, **kwargs):
     ensure_used_args(kwargs)
     try:
         return self.expr(ranks.np)
     except:
         return {v: self.expr(ranks[v]) for v in ranks}