2009-10-02 8 views
10

J'ai un ensemble de données qui va de 1 à 30 000ensemble de données Normaliser avec Ruby

Je veux normaliser, de sorte qu'il devient 0,1 à 10

Quelle est la meilleure méthode/fonction pour le faire?

J'apprécierais grandement si vous pouviez donner un exemple de code!

+0

Etes-vous sûr que cela s'appelle la normalisation des données? Vous pouvez envisager d'appeler cette transformation de données, je crois que la normalisation se réfère à la topologie des données. – jrhicks

Répondre

14

Voici un extrait de code, en supposant que voulez un linéaire normalisation. C'est une version très simpliste (juste du code direct, pas de méthode), donc vous pouvez voir "comment ça marche" et l'appliquer à n'importe quoi.

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)

+1

Merci brent! c'est une façon agréable et élégante de le faire =) –

6

Cette est un moyen bien connu pour mettre à l'échelle un nombre de collection. Il a un nom plus précis, mais je ne peux pas me souvenir et ne pas le 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 conscient des problèmes d'arrondi. Vous devriez également vous assurer que vous n'obtenez pas d'entiers au minimum & car la division entière endommagera le résultat.

7

Voici le Ruby Way pour le cas courant de la définition d'une matrice de min à 0.0 et max à 1.0.

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.

Questions connexes