1
1
<?php
2
2
3
+ declare (strict_types=1 );
3
4
4
5
namespace EnzoMC \PhpFPGrowth ;
5
6
7
+ use drupol \phpermutations \Generators \Combinations ;
6
8
7
9
class FPGrowth
8
10
{
9
- protected $ support = 3 ;
10
- protected $ confidence = 0.7 ;
11
+ protected int $ support = 3 ;
12
+ protected float $ confidence = 0.7 ;
11
13
12
14
private $ patterns ;
13
15
private $ rules ;
14
16
15
17
/**
16
- * @return mixed
18
+ * @return int
17
19
*/
18
- public function getSupport ()
20
+ public function getSupport (): int
19
21
{
20
22
return $ this ->support ;
21
23
}
22
24
23
25
/**
24
- * @param mixed $support
26
+ * @param int $support
27
+ * @return self
25
28
*/
26
- public function setSupport ($ support )
29
+ public function setSupport (int $ support ): self
27
30
{
28
31
$ this ->support = $ support ;
29
32
return $ this ;
30
33
}
31
34
32
35
/**
33
- * @return mixed
36
+ * @return float
34
37
*/
35
- public function getConfidence ()
38
+ public function getConfidence (): float
36
39
{
37
40
return $ this ->confidence ;
38
41
}
39
42
40
43
/**
41
- * @param mixed $confidence
44
+ * @param float $confidence
45
+ * @return self
42
46
*/
43
- public function setConfidence ($ confidence )
47
+ public function setConfidence (float $ confidence ): self
44
48
{
45
49
$ this ->confidence = $ confidence ;
46
50
return $ this ;
@@ -64,48 +68,57 @@ public function getRules()
64
68
65
69
/**
66
70
* FPGrowth constructor.
67
- * @param $support 1, 2, 3 ...
68
- * @param $confidence 0 ... 1
71
+ * @param int $support 1, 2, 3 ...
72
+ * @param float $confidence 0 ... 1
69
73
*/
70
- public function __construct ($ support , $ confidence )
74
+ public function __construct (int $ support , float $ confidence )
71
75
{
72
- $ this ->support = $ support ;
73
- $ this ->confidence = $ confidence ;
76
+ $ this ->setSupport ( $ support) ;
77
+ $ this ->setConfidence ( $ confidence) ;
74
78
}
75
79
76
80
/**
77
81
* Do algorithm
78
- * @param $transactions
82
+ * @param array $transactions
79
83
*/
80
- public function run ($ transactions )
84
+ public function run (array $ transactions )
81
85
{
82
- $ this ->patterns = $ this ->findFrequentPatterns ($ transactions, $ this -> support );
83
- $ this ->rules = $ this ->generateAssociationRules ($ this ->patterns , $ this -> confidence );
86
+ $ this ->patterns = $ this ->findFrequentPatterns ($ transactions );
87
+ $ this ->rules = $ this ->generateAssociationRules ($ this ->patterns );
84
88
}
85
89
86
- protected function findFrequentPatterns ($ transactions , $ support_threshold )
90
+ /**
91
+ * @param array $transactions
92
+ * @return array<string,int>
93
+ */
94
+ protected function findFrequentPatterns (array $ transactions ): array
87
95
{
88
- $ tree = new FPTree ($ transactions , $ support_threshold , null , null );
89
- return $ tree ->minePatterns ($ support_threshold );
96
+ $ tree = new FPTree ($ transactions , $ this -> support , null , 0 );
97
+ return $ tree ->minePatterns ($ this -> support );
90
98
}
91
99
92
- protected function generateAssociationRules ($ patterns , $ confidence_threshold )
100
+ /**
101
+ * @param array $patterns
102
+ * @return array
103
+ */
104
+ protected function generateAssociationRules (array $ patterns ): array
93
105
{
94
106
$ rules = [];
95
- foreach (array_keys ($ patterns ) as $ itemsetStr ) {
96
- $ itemset = explode (', ' , $ itemsetStr );
97
- $ upper_support = $ patterns [$ itemsetStr ];
98
- for ($ i = 1 ; $ i < count ($ itemset ); $ i ++) {
99
- foreach (self ::combinations ($ itemset , $ i ) as $ antecedent ) {
107
+ foreach (array_keys ($ patterns ) as $ pattern ) {
108
+ $ itemSet = explode (', ' , $ pattern );
109
+ $ upperSupport = $ patterns [$ pattern ];
110
+ for ($ i = 1 ; $ i < count ($ itemSet ); $ i ++) {
111
+ $ combinations = new Combinations ($ itemSet , $ i );
112
+ foreach ($ combinations ->generator () as $ antecedent ) {
100
113
sort ($ antecedent );
101
114
$ antecedentStr = implode (', ' , $ antecedent );
102
- $ consequent = array_diff ($ itemset , $ antecedent );
115
+ $ consequent = array_diff ($ itemSet , $ antecedent );
103
116
sort ($ consequent );
104
117
$ consequentStr = implode (', ' , $ consequent );
105
118
if (isset ($ patterns [$ antecedentStr ])) {
106
- $ lower_support = $ patterns [$ antecedentStr ];
107
- $ confidence = ( floatval ($ upper_support ) / $ lower_support ) ;
108
- if ($ confidence >= $ confidence_threshold ) {
119
+ $ lowerSupport = $ patterns [$ antecedentStr ];
120
+ $ confidence = floatval ($ upperSupport ) / $ lowerSupport ;
121
+ if ($ confidence >= $ this -> confidence ) {
109
122
$ rules [] = [$ antecedentStr , $ consequentStr , $ confidence ];
110
123
}
111
124
}
@@ -114,66 +127,4 @@ protected function generateAssociationRules($patterns, $confidence_threshold)
114
127
}
115
128
return $ rules ;
116
129
}
117
-
118
- public static function iter ($ var )
119
- {
120
-
121
- switch (true ) {
122
- case $ var instanceof \Iterator:
123
- return $ var ;
124
-
125
- case $ var instanceof \Traversable:
126
- return new \IteratorIterator ($ var );
127
-
128
- case is_string ($ var ):
129
- $ var = str_split ($ var );
130
-
131
- case is_array ($ var ):
132
- return new \ArrayIterator ($ var );
133
-
134
- default :
135
- $ type = gettype ($ var );
136
- throw new \InvalidArgumentException ("' $ type' type is not iterable " );
137
- }
138
-
139
- return ;
140
- }
141
-
142
- public static function combinations ($ iterable , $ r )
143
- {
144
- $ pool = is_array ($ iterable ) ? $ iterable : iterator_to_array (self ::iter ($ iterable ));
145
- $ n = sizeof ($ pool );
146
-
147
- if ($ r > $ n ) {
148
- return ;
149
- }
150
-
151
- $ indices = range (0 , $ r - 1 );
152
- yield array_slice ($ pool , 0 , $ r );
153
-
154
- for (; ;) {
155
- for (; ;) {
156
- for ($ i = $ r - 1 ; $ i >= 0 ; $ i --) {
157
- if ($ indices [$ i ] != $ i + $ n - $ r ) {
158
- break 2 ;
159
- }
160
- }
161
-
162
- return ;
163
- }
164
-
165
- $ indices [$ i ]++;
166
-
167
- for ($ j = $ i + 1 ; $ j < $ r ; $ j ++) {
168
- $ indices [$ j ] = $ indices [$ j - 1 ] + 1 ;
169
- }
170
-
171
- $ row = [];
172
- foreach ($ indices as $ i ) {
173
- $ row [] = $ pool [$ i ];
174
- }
175
-
176
- yield $ row ;
177
- }
178
- }
179
130
}
0 commit comments