1111from collections import defaultdict
1212from itertools import combinations
1313
14+
1415def load_data () -> list [list [str ]]:
1516 """
1617 Returns a sample transaction dataset.
@@ -24,7 +25,9 @@ def load_data() -> list[list[str]]:
2425class Apriori :
2526 """Apriori algorithm class with support, confidence, and lift filtering."""
2627
27- def __init__ (self , transactions , min_support = 0.25 , min_confidence = 0.5 , min_lift = 1.0 ):
28+ def __init__ (
29+ self , transactions , min_support = 0.25 , min_confidence = 0.5 , min_lift = 1.0
30+ ):
2831 self .transactions = [set (t ) for t in transactions ]
2932 self .min_support = min_support
3033 self .min_confidence = min_confidence
@@ -37,7 +40,9 @@ def __init__(self, transactions, min_support=0.25, min_confidence=0.5, min_lift=
3740
3841 def _get_support (self , itemset : frozenset ) -> float :
3942 """Return support of an itemset."""
40- return sum (1 for t in self .transactions if itemset .issubset (t )) / len (self .transactions )
43+ return sum (1 for t in self .transactions if itemset .issubset (t )) / len (
44+ self .transactions
45+ )
4146
4247 def confidence (self , antecedent : frozenset , consequent : frozenset ) -> float :
4348 """Calculate confidence of a rule A -> B."""
@@ -59,7 +64,11 @@ def find_frequent_itemsets(self):
5964 item_counts [frozenset ([item ])] += 1
6065
6166 total = len (self .transactions )
62- current_itemsets = {k : v / total for k , v in item_counts .items () if v / total >= self .min_support }
67+ current_itemsets = {
68+ k : v / total
69+ for k , v in item_counts .items ()
70+ if v / total >= self .min_support
71+ }
6372 self .itemsets .append (current_itemsets )
6473
6574 k = 2
@@ -69,10 +78,17 @@ def find_frequent_itemsets(self):
6978 for i in range (len (keys )):
7079 for j in range (i + 1 , len (keys )):
7180 union = keys [i ] | keys [j ]
72- if len (union ) == k and all (frozenset (sub ) in current_itemsets for sub in combinations (union , k - 1 )):
73- candidates .add (union )
74-
75- freq_candidates = {c : self ._get_support (c ) for c in candidates if self ._get_support (c ) >= self .min_support }
81+ if len (union ) == k and all (
82+ frozenset (sub ) in current_itemsets
83+ for sub in combinations (union , k - 1 )
84+ ):
85+ candidates .add (union )
86+
87+ freq_candidates = {
88+ c : self ._get_support (c )
89+ for c in candidates
90+ if self ._get_support (c ) >= self .min_support
91+ }
7692 if not freq_candidates :
7793 break
7894
@@ -115,6 +131,6 @@ def generate_association_rules(self):
115131 print ("\n Association Rules:" )
116132 for rule in model .rules :
117133 antecedent , consequent , conf , lift = rule
118- print (f" { set ( antecedent ) } -> { set ( consequent ) } , conf= { conf :.2f } , lift= { lift :.2f } " )
119-
120-
134+ print (
135+ f" { set ( antecedent ) } -> { set ( consequent ) } , conf= { conf :.2f } , lift= { lift :.2f } "
136+ )
0 commit comments