-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalcs.go
185 lines (151 loc) · 4.61 KB
/
calcs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package main
import (
"math"
)
// Exemple de calcul
// 10, 25, 30, 40, 41, 42, 50, 55, 70, 101, 110, 111 => 12 Valeurs
//
// 40 42+50 70
//
// => M = 42+50/2 => 46
// => Q1 = 12/4=> 4 eme valeur => 40
// => Q2 = 12*3/4 => 9 eme valeur => 70
//
// Dans la fonction qui suit, R[0]==Mediane, R[1]=Q1 et R[2]=Q3
//
// https://fastercapital.com/fr/contenu/Valeurs-aberrantes-dans-les-quartiles---identification-des-valeurs-extremes-dans-l-ensemble-de-donnees.html#Introduction-aux-valeurs-aberrantes-et-aux-quartiles
// quartileCalcf32 return quartiles Q1-3 from []float32 array
func quartileCalcf32(data []float32) [3]float32 { // Return Q1 Q2 Q3
var Q [3]float32
var n float64
var i int
sortSlice(data)
N := len(data)
if N < 4 {
// log.Printf("bad quartileCalc %v", d)
return [3]float32{-1, 0, 0}
}
// Calcul de la mediane Q[0]
if N%2 == 0 { // Pair
Q[0] = (data[N/2-1] + data[N/2]) / 2
} else {
Q[0] = data[(int)(math.Ceil((float64)(N)/2))-1]
}
// Calc Q1
n = (float64)(N) / 4
if isDecimal(n) { // entier
i = (N / 4) + 1
} else {
i = (int)(math.Ceil(n))
}
Q[1] = data[i-1]
// calc Q3
n = (float64)(N) * 3 / 4
if isDecimal(n) { // entier
i = (N * 3) / 4
} else {
i = (int)(math.Ceil((float64)(N) * 3 / 4))
}
Q[2] = (float32)(data[i-1])
return Q
}
// isDecimal function test if float is decimal
func isDecimal(n float64) bool {
return math.Floor(n) == n
}
/*
*
1. Méthode de la boîte à moustaches
La méthode Boxplot est une méthode graphique permettant de détecter les valeurs
aberrantes dans les données. Un boxplot affiche la distribution d'un ensemble de
données en affichant la médiane, les quartiles et la plage des données. La
fourchette est définie comme la différence entre les quartiles supérieur et
inférieur. Tout point de données qui se situe en dehors des moustaches du
boxplot est considéré comme une valeur aberrante.
La méthode du boxplot est simple, rapide et efficace.
2. Méthode Z-Score.
La méthode Z-score est une méthode statistique permettant de détecter les
valeurs aberrantes dans les données. Le score Z mesure la distance entre un
point de données et la moyenne de l'ensemble de données en termes d'écart type.
Tout point de données qui s’écarte de plus de trois écarts types de la moyenne
est considéré comme une valeur aberrante. La méthode du score Z est efficace
mais peut être influencée par les valeurs extrêmes de l'ensemble de données.
3. Méthode Z-Score modifiée
La méthode Z-score modifiée est une variante de la méthode Z-score. Il est plus
robuste et moins influencé par les valeurs extrêmes de l’ensemble de données.
Le score Z modifié mesure la distance entre un point de données et la médiane
de l'ensemble de données en termes d'écart absolu médian (MAD). Tout point de
données éloigné de plus de trois MAD de la médiane est considéré comme une
valeur aberrante. La méthode Z-score modifié est efficace et robuste.
*/
// ZScoreCalF32 calculate median and ecart type from []entries > mini value
func ZScoreCalF32(data []entries, mini float64) (float32, float32) {
//
// ZScore => Calculer la moyenne, l'ecart type
// si l'ecart type > 3x l'ecart moyen alors suspect
//
var somme, sommeecarts float32
var count int
for _, v := range data {
if (mini == 0) || (v.value >= float32(mini)) {
somme += v.value
count++
}
}
ecarts := make([]float32, count)
moyenne := somme / (float32)(count)
var i int
for _, v := range data {
if (mini == 0) || (v.value >= float32(mini)) {
ecarts[i] = myAbs(v.value - moyenne)
sommeecarts += ecarts[i]
i++
}
}
ecartmoyen := sommeecarts / (float32)(count)
return moyenne, ecartmoyen
}
func ZScoreMADCalF32(data []entries, mini float64) (float32, float32) {
//
// ZScore => Calculer la moyenne, l'ecart type
// si l'ecart type > 3x l'ecart moyen alors suspect
//
var sommeecarts float32
var count, myidx int
// Par rapport au nombre, trouver le point médian (!! pas la moyenne)
Arr := getNumbers(data, mini)
sortSlice(Arr)
N := len(Arr)
if N == 0 {
return 0, 0
}
if N%2 == 1 { // imPair
myidx = (N + 1) / 2
} else {
myidx = N / 2
}
MAD := Arr[myidx] // Median Absolute Data point
for _, v := range data {
if (mini == 0) || (v.value >= float32(mini)) {
count++
}
}
ecarts := make([]float32, count)
var i int
for _, v := range data {
if (mini == 0) || (v.value >= float32(mini)) {
ecarts[i] = myAbs(v.value - MAD)
sommeecarts += ecarts[i]
i++
}
}
ecartmoyen := sommeecarts / (float32)(count)
return MAD, ecartmoyen
}
func myAbs(x float32) float32 {
switch {
case x < 0:
return -x
}
return x
}