2009-10-02 161 views
10

正火的数据集我有从1到30000红宝石

我想归其范围的数据集,使之成为0.1至10

什么是最好的方法/函数来做到这一点?

如果你能给出一些示例代码,将不胜感激!

+0

你确定这叫做数据标准化吗?你可能会考虑调用这个数据转换,我认为规范化是指数据的拓扑结构。 – jrhicks 2009-10-02 15:08:17

回答

14

这里的代码片段,假设你想有一个线性正常化。这是一个非常简单的版本(只是直接的代码,没有方法),所以你可以看到“它是如何工作的”,并可以将它应用于任何事情。

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

xrange = xmax-xmin 
yrange = ymax-ymin 

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

在这里,它是作为一个函数来完成:

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) 

(注:to_f确保我们不会陷入整数除法的黑洞)

+1

谢谢布伦特!这是一个很好和优雅的做法=) – 2009-10-13 17:52:32

6

这是一种众所周知的扩大收集数量的方法。它有更精确的名字,但我不记得,也无法谷歌。

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] 

正如你所看到的,你必须意识到舍入问题。你也应该确保你不会得到最大整数,因为整数除法会损坏结果。

7

下面是将数组的最小值设置为0.0和最大值设置为1.0的常见情况的Ruby方法。

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] 

对于除0和1最低和最高其他,在Elfstrom的回答的方式添加参数normalize!