ensemble de données normalisant avec rubis
-
19-09-2019 - |
Question
I ai un ensemble de données qui varie de 1 à 30 000
Je veux normaliser, de sorte qu'il devient 0,1 à 10
Quelle est la meilleure méthode / fonction pour le faire?
apprécierais beaucoup si vous pouviez donner un exemple de code!
La solution
Voici un extrait de code, en supposant que vous souhaitez linéaire normalisation. Il est une version très simpliste (juste code droit, aucune méthode), vous pouvez donc voir « comment cela fonctionne » et peut l'appliquer à quoi que ce soit.
xmin = 1.0
xmax = 30000.0
ymin = 0.1
ymax = 10.0
xrange = xmax-xmin
yrange = ymax-ymin
y = ymin + (x-xmin) * (yrange / xrange)
Et là, il se fait en fonction:
def normalise(x, xmin, xmax, ymin, ymax)
xrange = xmax - xmin
yrange = ymax - ymin
ymin + (x - xmin) * (yrange.to_f / xrange)
end
puts normalise(2000, 1, 30000, 0.1, 10)
(Note: le to_f
assure ne pas tomber dans le trou noir de la division entière)
Autres conseils
Voici le chemin Ruby pour le cas commun de définition de min d'un tableau à 0,0 et à 1,0 max.
class Array
def normalize!
xMin,xMax = self.minmax
dx = (xMax-xMin).to_f
self.map! {|x| (x-xMin) / dx }
end
end
a = [3.0, 6.0, 3.1416]
a.normalize!
=> [0.0, 1.0, 0.047199999999999985]
Pour un min et max autre que 0 et 1, ajouter des arguments à normalize!
de la manière de la réponse de Elfstrom.
Ceci est un moyen bien connu à l'échelle un nombre de collecte. Il a le nom plus précis, mais je ne me souviens pas et ne parviennent pas à elle google.
def scale(numbers, min, max)
current_min = numbers.min
current_max = numbers.max
numbers.map {|n| min + (n - current_min) * (max - min) / (current_max - current_min)}
end
dataset = [1,30000,15000,200,3000]
result = scale(dataset, 0.1, 10.0)
=> [0.1, 10.0, 5.04983499449982, 0.165672189072969, 1.08970299009967]
scale(result, 1, 30000)
=> [1.0, 30000.000000000004, 15000.0, 199.99999999999997, 3000.0000000000005]
Comme vous pouvez le voir, vous devez être au courant des problèmes d'arrondi. Vous devriez probablement également vous assurer que vous ne recevez pas des entiers comme min et max, car la division entière endommagera le résultat.
x = x / 3030.3031 + 0.1