77import numpy as np
88from numpy .testing import assert_array_equal
99from mlxtend .utils import assert_raises
10+ from mlxtend .preprocessing import TransactionEncoder
1011import pandas as pd
1112import sys
1213from contextlib import contextmanager
@@ -24,30 +25,37 @@ def captured_output():
2425 sys .stdout , sys .stderr = old_out , old_err
2526
2627
27- class FPTestBase (object ):
28+ class FPTestEdgeCases (object ):
2829 """
29- Base testing class for frequent pattern mining. This class should include
30- setup and tests common to all methods (e.g., error for improper input)
30+ Base class for testing edge cases for pattern mining.
3131 """
3232
33- def setUp (self , fpalgo , one_ary = None ):
34- if one_ary is None :
35- self .one_ary = np .array (
36- [[0 , 0 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 1 ],
37- [0 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1 ],
38- [1 , 0 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 ],
39- [0 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 ],
40- [0 , 1 , 0 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0 ]])
33+ def setUp (self , fpalgo ):
34+ self .fpalgo = fpalgo
4135
42- else :
43- self .one_ary = one_ary
36+ def test_empty (self ):
37+ df = pd .DataFrame ([[]])
38+ res_df = self .fpalgo (df )
39+ expect = pd .DataFrame ([], columns = ['support' , 'itemsets' ])
40+ compare_dataframes (res_df , expect )
4441
42+
43+ class FPTestErrors (object ):
44+ """
45+ Base class for testing expected errors for pattern mining.
46+ """
47+
48+ def setUp (self , fpalgo ):
49+ self .one_ary = np .array (
50+ [[0 , 0 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 1 ],
51+ [0 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1 ],
52+ [1 , 0 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 ],
53+ [0 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 ],
54+ [0 , 1 , 0 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0 ]])
4555 self .cols = ['Apple' , 'Corn' , 'Dill' , 'Eggs' , 'Ice cream' ,
4656 'Kidney Beans' , 'Milk' ,
4757 'Nutmeg' , 'Onion' , 'Unicorn' , 'Yogurt' ]
48-
4958 self .df = pd .DataFrame (self .one_ary , columns = self .cols )
50-
5159 self .fpalgo = fpalgo
5260
5361 def test_itemsets_type (self ):
@@ -84,6 +92,31 @@ def test_sparsedataframe_notzero_column(self):
8492 '`df.columns = [str(i) for i in df.columns`].' ,
8593 self .fpalgo , dfs )
8694
95+
96+ class FPTestEx1 (object ):
97+ """
98+ Base class for testing frequent pattern mining on a small example.
99+ """
100+
101+ def setUp (self , fpalgo , one_ary = None ):
102+ if one_ary is None :
103+ self .one_ary = np .array (
104+ [[0 , 0 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 1 ],
105+ [0 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1 ],
106+ [1 , 0 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 ],
107+ [0 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 ],
108+ [0 , 1 , 0 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0 ]])
109+ else :
110+ self .one_ary = one_ary
111+
112+ self .cols = ['Apple' , 'Corn' , 'Dill' , 'Eggs' , 'Ice cream' ,
113+ 'Kidney Beans' , 'Milk' ,
114+ 'Nutmeg' , 'Onion' , 'Unicorn' , 'Yogurt' ]
115+
116+ self .df = pd .DataFrame (self .one_ary , columns = self .cols )
117+
118+ self .fpalgo = fpalgo
119+
87120 def test_frozenset_selection (self ):
88121 res_df = self .fpalgo (self .df , use_colnames = True )
89122 assert res_df .values .shape == self .fpalgo (self .df ).values .shape
@@ -117,9 +150,9 @@ def test_with_fill_values(fill_value):
117150 test_with_fill_values (False )
118151
119152
120- class FPTestAll ( FPTestBase ):
153+ class FPTestEx1All ( FPTestEx1 ):
121154 def setUp (self , fpalgo , one_ary = None ):
122- FPTestBase .setUp (self , fpalgo , one_ary = one_ary )
155+ FPTestEx1 .setUp (self , fpalgo , one_ary = one_ary )
123156
124157 def test_default (self ):
125158 res_df = self .fpalgo (self .df )
@@ -162,27 +195,62 @@ def test_low_memory_flag(self):
162195 assert True
163196
164197
165- class FPTestMaximal (FPTestBase ):
166- def setUp (self , fpalgo , one_ary = None ):
167- FPTestBase .setUp (self , fpalgo , one_ary = one_ary )
198+ class FPTestEx2 (object ):
199+ """
200+ Base class for testing frequent pattern mining on a small example.
201+ """
168202
169- def test_default (self ):
170- res_df = self .fpalgo (self .df )
171- expect = pd .DataFrame ([[0.6 , frozenset ([5 , 6 ])],
172- [0.6 , frozenset ([5 , 10 ])],
173- [0.6 , frozenset ([3 , 5 , 8 ])]],
203+ def setUp (self ):
204+ database = [['a' ], ['b' ], ['c' , 'd' ], ['e' ]]
205+ te = TransactionEncoder ()
206+ te_ary = te .fit (database ).transform (database )
207+
208+ self .df = pd .DataFrame (te_ary , columns = te .columns_ )
209+
210+
211+ class FPTestEx2All (FPTestEx2 ):
212+ def setUp (self , fpalgo ):
213+ self .fpalgo = fpalgo
214+ FPTestEx2 .setUp (self )
215+
216+ def test_output (self ):
217+ res_df = self .fpalgo (self .df , min_support = 0.001 , use_colnames = True )
218+ expect = pd .DataFrame ([[0.25 , frozenset (['a' ])],
219+ [0.25 , frozenset (['b' ])],
220+ [0.25 , frozenset (['c' ])],
221+ [0.25 , frozenset (['d' ])],
222+ [0.25 , frozenset (['e' ])],
223+ [0.25 , frozenset (['c' , 'd' ])]],
174224 columns = ['support' , 'itemsets' ])
175225
176226 compare_dataframes (res_df , expect )
177227
178- def test_max_len (self ):
179- res_df1 = self .fpalgo (self .df )
180- max_len = np .max (res_df1 ['itemsets' ].apply (len ))
181- assert max_len == 3
182228
183- res_df2 = self .fpalgo (self .df , max_len = 2 )
184- max_len = np .max (res_df2 ['itemsets' ].apply (len ))
185- assert max_len == 2
229+ class FPTestEx3 (object ):
230+ """
231+ Base class for testing frequent pattern mining on a small example.
232+ """
233+
234+ def setUp (self ):
235+ database = [['a' ], ['b' ], ['c' , 'd' ], ['e' ]]
236+ te = TransactionEncoder ()
237+ te_ary = te .fit (database ).transform (database )
238+
239+ self .df = pd .DataFrame (te_ary , columns = te .columns_ )
240+
241+
242+ class FPTestEx3All (FPTestEx3 ):
243+ def setUp (self , fpalgo ):
244+ self .fpalgo = fpalgo
245+ FPTestEx3 .setUp (self )
246+
247+ def test_output3 (self ):
248+ assert_raises (ValueError ,
249+ '`min_support` must be a positive '
250+ 'number within the interval `(0, 1]`. Got 0.0.' ,
251+ self .fpalgo ,
252+ self .df ,
253+ min_support = 0. )
186254
187255
188256def compare_dataframes (df1 , df2 ):
0 commit comments