1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace robotomize\regression\Math; |
4
|
|
|
|
5
|
|
|
use IllegalArgumentException; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Class Math |
9
|
|
|
* |
10
|
|
|
* @package Regression\Math |
11
|
|
|
* @author [email protected] |
12
|
|
|
*/ |
13
|
|
|
class Math |
14
|
|
|
{ |
15
|
|
|
|
16
|
|
|
const ERROR_ARRAY_LENGTH = 'The length of the arrays does not match'; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* The quadratic mean square error |
20
|
|
|
* |
21
|
|
|
* @param array $rightData |
22
|
|
|
* @param array $hypothesisData |
23
|
|
|
* @return float |
24
|
|
|
* @throws IllegalArgumentException |
25
|
|
|
*/ |
26
|
|
|
public static function mse(array $rightData, array $hypothesisData): float |
27
|
|
|
{ |
28
|
|
|
$score = 0; |
29
|
|
|
|
30
|
|
|
if (count($hypothesisData) !== count($rightData)) { |
31
|
|
|
throw new IllegalArgumentException(self::ERROR_ARRAY_LENGTH); |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
foreach ($rightData as $k => $v) { |
35
|
|
|
$score += pow($v - $hypothesisData[$k], 2); |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
return $score; |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Total Sum of Squares |
43
|
|
|
* |
44
|
|
|
* @param array $rightData |
45
|
|
|
* @return float |
46
|
|
|
*/ |
47
|
|
|
public static function tss(array $rightData): float |
48
|
|
|
{ |
49
|
|
|
$score = 0; |
50
|
|
|
$avgConst = array_sum($rightData) / count($rightData); |
51
|
|
|
|
52
|
|
|
foreach ($rightData as $v) { |
53
|
|
|
$score += pow($v - $avgConst, 2); |
54
|
|
|
} |
55
|
|
|
return $score; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* @param array $rightData |
60
|
|
|
* @param array $hypothesisData |
61
|
|
|
* @return float |
62
|
|
|
* @throws IllegalArgumentException |
63
|
|
|
*/ |
64
|
|
|
public static function r2(array $rightData, array $hypothesisData):float |
65
|
|
|
{ |
66
|
|
|
return 1 - self::mse($rightData, $hypothesisData) / self::tss($rightData); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Mean absolute percentage error |
71
|
|
|
* |
72
|
|
|
* @param array $rightData |
73
|
|
|
* @param array $hypothesisData |
74
|
|
|
* @return float |
75
|
|
|
* @throws IllegalArgumentException |
76
|
|
|
*/ |
77
|
|
View Code Duplication |
public static function mape(array $rightData, array $hypothesisData): float |
|
|
|
|
78
|
|
|
{ |
79
|
|
|
$score = 0; |
80
|
|
|
if (count($rightData) !== count($hypothesisData)) { |
81
|
|
|
throw new IllegalArgumentException(self::ERROR_ARRAY_LENGTH); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
foreach ($rightData as $k => $v) { |
85
|
|
|
$score += abs($v - $hypothesisData[$k]) / $v; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
return $score / count($rightData); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Mean absolute error |
93
|
|
|
* |
94
|
|
|
* @param array $rightData |
95
|
|
|
* @param array $hypothesisData |
96
|
|
|
* @return float |
97
|
|
|
* @throws IllegalArgumentException |
98
|
|
|
*/ |
99
|
|
View Code Duplication |
public static function mae(array $rightData, array $hypothesisData): float |
|
|
|
|
100
|
|
|
{ |
101
|
|
|
$score = 0; |
102
|
|
|
if (count($rightData) !== count($hypothesisData)) { |
103
|
|
|
throw new IllegalArgumentException(self::ERROR_ARRAY_LENGTH); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
foreach ($rightData as $k => $v) { |
107
|
|
|
$score += abs($v - $hypothesisData[$k]); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
return $score / count($rightData); |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* 1- mae |
115
|
|
|
* |
116
|
|
|
* @param array $rightData |
117
|
|
|
* @param array $hypothesisData |
118
|
|
|
* @return float |
119
|
|
|
* @throws IllegalArgumentException |
120
|
|
|
*/ |
121
|
|
|
public static function mpmae(array $rightData, array $hypothesisData): float |
122
|
|
|
{ |
123
|
|
|
return 1 - self::mae($rightData, $hypothesisData); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* The accuracy of the forecast |
128
|
|
|
* |
129
|
|
|
* @param array $rightData |
130
|
|
|
* @param array $hypothesisData |
131
|
|
|
* @return float |
132
|
|
|
* @throws IllegalArgumentException |
133
|
|
|
*/ |
134
|
|
|
public static function mpe(array $rightData, array $hypothesisData): float |
135
|
|
|
{ |
136
|
|
|
return 1 - self::mape($rightData, $hypothesisData); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Moving Average |
141
|
|
|
* |
142
|
|
|
* @param array $vector |
143
|
|
|
* @return array |
144
|
|
|
*/ |
145
|
|
|
public static function tripleMovingAverage(array $vector): array |
146
|
|
|
{ |
147
|
|
|
$iterior = []; |
148
|
|
|
for ($i = 0; $i < count($vector); $i++) { |
|
|
|
|
149
|
|
|
|
150
|
|
|
if ($i >= count($vector) - 3) { |
151
|
|
|
$iterior[$i] = ($vector[$i] + $vector[$i - 1] + $vector[$i - 2] + $vector[$i - 3]) / 4; |
152
|
|
|
} else { |
153
|
|
|
$iterior[$i] = ($vector[$i] + $vector[$i + 1] + $vector[$i + 2] + $vector[$i + 3]) / 4; |
154
|
|
|
} |
155
|
|
|
} |
156
|
|
|
return $iterior; |
157
|
|
|
} |
158
|
|
|
} |
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.