Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
12 | class PCA |
||
13 | { |
||
14 | /** |
||
15 | * Total variance to be conserved after the reduction |
||
16 | * |
||
17 | * @var float |
||
18 | */ |
||
19 | public $totalVariance = 0.9; |
||
20 | |||
21 | /** |
||
22 | * Number of features to be preserved after the reduction |
||
23 | * |
||
24 | * @var int |
||
25 | */ |
||
26 | public $numFeatures = null; |
||
27 | |||
28 | /** |
||
29 | * Temporary storage for mean values for each dimension in given data |
||
30 | * |
||
31 | * @var array |
||
32 | */ |
||
33 | protected $means = []; |
||
34 | |||
35 | /** |
||
36 | * Eigenvectors of the covariance matrix |
||
37 | * |
||
38 | * @var array |
||
39 | */ |
||
40 | protected $eigVectors = []; |
||
41 | |||
42 | /** |
||
43 | * Top eigenValues of the covariance matrix |
||
44 | * |
||
45 | * @var type |
||
46 | */ |
||
47 | protected $eigValues = []; |
||
48 | |||
49 | /** |
||
50 | * @var bool |
||
51 | */ |
||
52 | protected $fit = false; |
||
53 | |||
54 | /** |
||
55 | * PCA (Principal Component Analysis) used to explain given |
||
56 | * data with lower number of dimensions. This analysis transforms the |
||
57 | * data to a lower dimensional version of it by conserving a proportion of total variance |
||
58 | * within the data. It is a lossy data compression technique.<br> |
||
59 | * |
||
60 | * @param float $totalVariance Total explained variance to be preserved |
||
61 | * @param int $numFeatures Number of features to be preserved |
||
62 | * |
||
63 | * @throws \Exception |
||
64 | */ |
||
65 | public function __construct($totalVariance = null, $numFeatures = null) |
||
84 | |||
85 | /** |
||
86 | * Takes a data and returns a lower dimensional version |
||
87 | * of this data while preserving $totalVariance or $numFeatures. <br> |
||
88 | * $data is an n-by-m matrix and returned array is |
||
89 | * n-by-k matrix where k <= m |
||
90 | * |
||
91 | * @param array $data |
||
92 | * |
||
93 | * @return array |
||
94 | */ |
||
95 | public function fit(array $data) |
||
109 | |||
110 | /** |
||
111 | * @param array $data |
||
112 | * @param int $n |
||
113 | */ |
||
114 | protected function calculateMeans(array $data, int $n) |
||
123 | |||
124 | /** |
||
125 | * Normalization of the data includes subtracting mean from |
||
126 | * each dimension therefore dimensions will be centered to zero |
||
127 | * |
||
128 | * @param array $data |
||
129 | * @param int $n |
||
130 | * |
||
131 | * @return array |
||
132 | */ |
||
133 | protected function normalize(array $data, int $n) |
||
148 | |||
149 | /** |
||
150 | * Calculates eigenValues and eigenVectors of the given matrix. Returns |
||
151 | * top eigenVectors along with the largest eigenValues. The total explained variance |
||
152 | * of these eigenVectors will be no less than desired $totalVariance value |
||
153 | * |
||
154 | * @param array $matrix |
||
155 | * @param int $n |
||
156 | * |
||
157 | * @return array |
||
158 | */ |
||
159 | protected function eigenDecomposition(array $matrix, int $n) |
||
190 | |||
191 | /** |
||
192 | * Returns the reduced data |
||
193 | * |
||
194 | * @param array $data |
||
195 | * |
||
196 | * @return array |
||
197 | */ |
||
198 | protected function reduce(array $data) |
||
205 | |||
206 | /** |
||
207 | * Transforms the given sample to a lower dimensional vector by using |
||
208 | * the eigenVectors obtained in the last run of <code>fit</code>. |
||
209 | * |
||
210 | * @param array $sample |
||
211 | * |
||
212 | * @return array |
||
213 | */ |
||
214 | public function transform(array $sample) |
||
228 | } |
||
229 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.