Coverage for hopwise/evaluator/register.py: 81%
43 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-09-30 13:25 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-09-30 13:25 +0000
1# @Time : 2021/6/23
2# @Author : Zihan Lin
3# @Email : zhlin@ruc.edu.cn
5# UPDATE
6# @Time : 2021/8/29
7# @Author : Zhichao Feng
8# @email : fzcbupt@gmail.com
10"""hopwise.evaluator.register
11################################################
12"""
14import inspect
15import sys
18def cluster_info(module_name):
19 """Collect information of all metrics, including:
21 - ``metric_need``: Information needed to calculate this metric, the combination of ``rec.items, rec.topk,
22 rec.meanrank, rec.score, data.num_items, data.num_users, data.count_items, data.count_users, data.label``.
23 - ``metric_type``: Whether the scores required by metric are grouped by user, range in ``EvaluatorType.RANKING``
24 and ``EvaluatorType.VALUE``.
25 - ``smaller``: Whether the smaller metric value represents better performance,
26 range in ``True`` and ``False``, default to ``False``.
28 Note:
29 For ``metric_type``: in current hopwise, all the "grouped-score" metrics are ranking-based and all the
30 "non-grouped-score" metrics are value-based. To keep with our paper, we adopted the more formal terms:
31 ``RANKING`` and ``VALUE``.
33 Args:
34 module_name (str): the name of module ``hopwise.evaluator.metrics``.
36 Returns:
37 dict: Three dictionaries containing the above information
38 and a dictionary matching metric names to metric classes.
39 """ # noqa: E501
40 smaller_m = []
41 m_dict, m_info, m_types = {}, {}, {}
42 metric_class = inspect.getmembers(
43 sys.modules[module_name],
44 lambda x: inspect.isclass(x) and x.__module__ == module_name,
45 )
46 for name, metric_cls in metric_class:
47 name = name.lower() # noqa: PLW2901
48 m_dict[name] = metric_cls
49 if hasattr(metric_cls, "metric_need"):
50 m_info[name] = metric_cls.metric_need
51 else:
52 raise AttributeError(f"Metric '{name}' has no attribute [metric_need].")
53 if hasattr(metric_cls, "metric_type"):
54 m_types[name] = metric_cls.metric_type
55 else:
56 raise AttributeError(f"Metric '{name}' has no attribute [metric_type].")
57 if metric_cls.smaller is True:
58 smaller_m.append(name)
59 return smaller_m, m_info, m_types, m_dict
62metric_module_name = "hopwise.evaluator.metrics"
63smaller_metrics, metric_information, metric_types, metrics_dict = cluster_info(metric_module_name)
66class Register:
67 """Register module load the registry according to the metrics in config.
68 It is a member of DataCollector.
69 The DataCollector collect the resource that need for Evaluator under the guidance of Register
70 """
72 def __init__(self, config):
73 self.config = config
74 self.metrics = [metric.lower() for metric in self.config["metrics"]]
75 self._build_register()
77 def _build_register(self):
78 for metric in self.metrics:
79 metric_needs = metric_information[metric]
80 for info in metric_needs:
81 setattr(self, info, True)
83 def has_metric(self, metric: str):
84 if metric.lower() in self.metrics:
85 return True
86 else:
87 return False
89 def need(self, key: str):
90 if hasattr(self, key):
91 return getattr(self, key)
92 return False
95class Register_KG(Register):
96 """Register module load the registry according to the metrics in config.
97 It is a member of DataCollector.
98 The DataCollector collect the resource that need for Evaluator under the guidance of Register
99 """
101 def __init__(self, config):
102 super().__init__(config)
103 self.metrics = [metric.lower() for metric in self.config["metrics_lp"]]
104 self._build_register()