2009-10-02 10 views
10

Mam zestaw danych, który waha się od 1 do 30000normalizujący zestaw danych z rubinem

Chcę normalizacji, tak że staje się od 0,1 do 10

Jaka jest najlepsza metoda/funkcja to zrobić?

Byłbym bardzo wdzięczny, gdyby można było podać przykładowy kod!

+0

Czy na pewno nazywa się to normalizacją danych? Możesz rozważyć wywołanie tej transformacji danych, wierzę, że normalizacja odnosi się do topologii danych. – jrhicks

Odpowiedz

14

Oto fragment kodu, zakładając chcesz liniowy normalizację. Jest to bardzo uproszczona wersja (tylko prosty kod, brak metod), dzięki czemu można zobaczyć "jak to działa" i zastosować go do czegokolwiek.

xmin = 1.0 
xmax = 30000.0 
ymin = 0.1 
ymax = 10.0 

xrange = xmax-xmin 
yrange = ymax-ymin 

y = ymin + (x-xmin) * (yrange/xrange) 

I oto stało się, funkcję:

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) 

(Uwaga: to_f zapewnia nie wpaść w czarną dziurę podziału całkowitej)

+1

Dzięki brent! to jest miły i elegancki sposób robienia tego =) –

6

ten jest dobrze znanym sposobem skalowania numerów kolekcji. Ma bardziej precyzyjną nazwę, ale nie pamiętam i nie mogę 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] 

Jak widać, trzeba mieć świadomość problemów z zaokrąglaniem. Powinieneś również upewnić się, że nie otrzymujesz liczb całkowitych jako min. & max, ponieważ podział liczb całkowitych spowoduje uszkodzenie wyniku.

7

Oto Rubinowy sposób dla wspólnego przypadku ustawienia tablicy min. 0.0 i maks. 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] 

Przez min i max inny niż 0 i 1, dodać argumenty normalize! w sposób odpowiedź Elfstrom użytkownika.

Powiązane problemy