Skip to content

Commit afa5231

Browse files
authored
Merge pull request #105 from zStupan/feature-zhang
Implemented Zhang's Metric
2 parents 2e7a503 + 6ab24e5 commit afa5231

File tree

5 files changed

+44
-0
lines changed

5 files changed

+44
-0
lines changed

docs/getting_started.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ The framework currently implements the following interest measures (metrics):
334334
- Comprehensibility
335335
- Netconf [#fn]_
336336
- Yule's Q [#fn]_
337+
- Zhang's Metric [#fn]_
337338

338339
More information about these interest measures can be found in the API reference
339340
of the :class:`~niaarm.rule.Rule` class.

interest_measures.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,19 @@ and 0 reflects independence)
192192
**Reference:** E. V. Altay and B. Alatas, "Sensitivity Analysis of MODENAR Method for Mining of Numeric Association
193193
Rules," 2019 1st International Informatics and Software Engineering Conference (UBMYK), 2019, pp. 1-6,
194194
doi: 10.1109/UBMYK48245.2019.8965539.
195+
196+
# Zhang's Metric
197+
198+
Zheng's metric measures the strength of association (positive or negative) between the antecedent and consequent,
199+
taking into account both their co-occurrence and non-co-occurrence.
200+
201+
```math
202+
zhang(X \implies Y) =
203+
\frac{conf(X \implies Y) - conf(\neg X \implies Y)}{max\{conf(X \implies Y), conf(\neg X \implies Y)\}}
204+
```
205+
206+
**Range:** $`[-1, 1]`$ (-1 reflects total negative association, 1 reflects perfect positive association
207+
and 0 reflects independence)
208+
209+
**Reference:** T. Zhang, “Association Rules,” in Knowledge Discovery and Data Mining. Current Issues and New
210+
Applications, 2000, pp. 245–256. doi: 10.1007/3-540-45571-X_31.

niaarm/rule.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,16 @@ class Rule:
145145
**Reference:** E. V. Altay and B. Alatas, "Sensitivity Analysis of MODENAR Method for Mining of Numeric Association
146146
Rules," 2019 1st International Informatics and Software Engineering Conference (UBMYK), 2019, pp. 1-6,
147147
doi: 10.1109/UBMYK48245.2019.8965539.
148+
zhang: Zheng's metric measures the strength of association (positive or negative) between the antecedent and consequent, taking into account both their co-occurrence and non-co-occurrence.
149+
150+
:math:`zhang(X \implies Y) =
151+
\frac{conf(X \implies Y) - conf(\neg X \implies Y)}{max\{conf(X \implies Y), conf(\neg X \implies Y)\}}`
152+
153+
**Range:** :math:`[-1, 1]` (-1 reflects total negative association, 1 reflects perfect positive association
154+
and 0 reflects independence)
155+
156+
**Reference:** T. Zhang, “Association Rules,” in Knowledge Discovery and Data Mining. Current Issues and New
157+
Applications, 2000, pp. 245–256. doi: 10.1007/3-540-45571-X_31.
148158
149159
"""
150160

@@ -176,6 +186,7 @@ class Rule:
176186
"comprehensibility",
177187
"netconf",
178188
"yulesq",
189+
"zhang",
179190
)
180191

181192
def __init__(self, antecedent, consequent, fitness=0.0, transactions=None):
@@ -304,6 +315,17 @@ def comprehensibility(self):
304315
1 + len(self.antecedent) + len(self.consequent)
305316
)
306317

318+
@property
319+
def zhang(self):
320+
support_x = self.coverage
321+
support_y = self.rhs_support
322+
support = self.support
323+
324+
numerator = support - support_x * support_y
325+
denominator = max(support * (1 - support_x), support_x * (support_y - support))
326+
327+
return numerator / denominator
328+
307329
def __eq__(self, other):
308330
return (
309331
self.antecedent == other.antecedent and self.consequent == other.consequent

niaarm/rule_list.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ def __str__(self):
122122
f'Average comprehensibility: {self.mean("comprehensibility")}\n'
123123
f'Average netconf: {self.mean("netconf")}\n'
124124
f'Average Yule\'s Q: {self.mean("yulesq")}\n'
125+
f'Average Zhang\'s Metric: {self.mean("zhang")}\n'
125126
f"Average antecedent length: {sum(len(rule.antecedent) for rule in self) / len(self)}\n"
126127
f"Average consequent length: {sum(len(rule.consequent) for rule in self) / len(self)}\n"
127128
)

tests/test_metrics.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,7 @@ def test_netconf(self):
6666
def test_yulesq(self):
6767
self.assertAlmostEqual(self.rule_one.yulesq, (6 - 1) / (6 + 1))
6868
self.assertAlmostEqual(self.rule_two.yulesq, (6 - 1) / (6 + 1))
69+
70+
def test_zhang(self):
71+
self.assertAlmostEqual(self.rule_one.zhang, 5 / 9)
72+
self.assertAlmostEqual(self.rule_two.zhang, 5 / 8)

0 commit comments

Comments
 (0)