سؤال
لدي مجموعة بيانات تتراوح من 1 إلى 30،000
أريد تطبيعها، بحيث يصبح 0.1 إلى 10
ما هي أفضل طريقة / وظيفة للقيام بذلك؟
سيقدر ذلك بشكل كبير إذا كنت تستطيع إعطاء بعض التعليمات البرمجية!
المحلول
إليك مقتطف رمز، على افتراض أنك تريد خطي تطبيع. إنها نسخة مبسطة للغاية (رمز مستقيم فقط، لا توجد طرق)، حتى تتمكن من رؤية "كيف تعمل" ويمكنك تطبيقها على أي شيء.
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
يضمن أننا لا نقع في الثقب الأسود من قسم الأعداد الصحيحة)
نصائح أخرى
إليك طريقة Ruby للحالة الشائعة لإعداد دقيقة صفيف إلى 0.0 و 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]
لمدة دقيقة وكحد أقصى من 0 و 1، أضف الحجج إلى normalize!
في طريقة إجابة Elfstrom.
هذه طريقة معروفة لتوسيع نطاق أرقام المجموعة. لديها اسم أكثر دقة ولكن لا أستطيع أن أتذكر وفشل في جوجل ذلك.
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]
كما ترون، عليك أن تكون على دراية بقضايا التقريب. ربما يجب أن تتأكد أيضا من عدم وجود أعداد صحيحة مثل Min & Max لأن قسم عدد صحيح سيضر النتيجة.
x = x / 3030.3031 + 0.1