Як нормалізувати дані до діапазону 0-1?


265

Я загубився в нормалізації, чи не міг би хтось мене навести.

У мене мінімальні та максимальні значення, скажімо, -23,89 та 7,54990767 відповідно.

Якщо я отримаю значення 5.6878, як я можу масштабувати це значення за шкалою від 0 до 1.


8
це так = (значення-хв) / (макс-хв)
Анджело

3
Це може допомогти вам прочитати цей потік: нормалізація як перевірити-розповсюдження-нормалізується . Якщо це відповідає на ваше запитання, ви можете видалити цей Q; якщо ні, відредагуйте Q, щоб вказати, що ви досі не розумієте.
гунг

1
Пояснення захисту: це питання залучає додаткові відповіді, що містять лише рішення коду. Хоча це може бути цікавим чи корисним для деяких читачів, це не є метою резюме, щоб забезпечити сховища кодових рішень.
Нік Кокс

1
надані рішення враховують лінійне значення контрасту - чи хотіли б ви різної нормалізації, наприклад, такої, яка б домоглася рівномірної ймовірності для виходу?
медуз

Відповіді:


299

Якщо ви хочете нормалізувати свої дані, ви можете зробити так, як ви запропонуєте, і просто обчислити наступне:

zi=ximin(x)max(x)min(x)

де і тепер ваші нормалізовані дані. Як доказ концепції (хоча ви її не просили) ось деякий код та супровідний графік для ілюстрації цього пункту:x=(x1,...,xn)ziithR

введіть тут опис зображення

# Example Data
x = sample(-100:100, 50)

#Normalized Data
normalized = (x-min(x))/(max(x)-min(x))

# Histogram of example data and normalized data
par(mfrow=c(1,2))
hist(x,          breaks=10, xlab="Data",            col="lightblue", main="")
hist(normalized, breaks=10, xlab="Normalized Data", col="lightblue", main="")

11
Мені цікаво лише, як дві досить різні на вигляд гістограми illustrate the pointвідповідають на ваш (правильний) відповідь?
ttnphns

12
@ttnphns Вони виглядають по-різному лише через бінінг гістограм. Моя суть, однак, полягала в тому, щоб показати, що початкові значення жили від -100 до 100, а зараз після нормалізації вони живуть від 0 до 1. Я міг би використовувати інший графік, щоб показати це, я думаю, або просто підсумкову статистику.

20
Лагідний поштовх від @ttnphns мав на меті заохотити вас не тільки використовувати менш складні засоби ілюстрації (простої) ідеї, але й (підозрюю) як натяк на те, що тут може бути корисним більш безпосередньо відповідна ілюстрація. Можна зробити і те, і інше, знайти більш простий спосіб графічного перетворення, коли він застосовується до
мінімуму

1
Чи є спосіб "нормалізувати" спеціальний діапазон замість 0-1?
Джон Деметріу

1
@JohnDemetriou Не може бути найчистішим рішенням, але ви можете масштабувати нормовані значення для цього. Якщо ви хочете, наприклад, діапазон 0-100, ви просто помножте кожне число на 100. Якщо ви хочете, щоб діапазон, який не починається з 0, як 10-100, ви зробите це шляхом масштабування MAX-MIN, а потім до пункту Значення, які ви отримуєте від додавання MIN. Отже, масштабуйте на 90, а потім додайте 10. Цього повинно вистачити для більшості призначених для вас діапазонів.
Олександр Росса

47

Загальна однолінійна формула для лінійного масштабування значень даних, що спостерігають min та max у новий довільний діапазон min ' до max' ,

  newvalue= (max'-min')/(max-min)*(value-max)+max'
  or
  newvalue= (max'-min')/(max-min)*(value-min)+min'.

9
Це правильно, але не ефективно. Це лінійна трансформація, тож ви б перерахували aі bконстанти, а потім просто застосувати newvalue = a * value + b. a = (max'-min')/(max-min)іb = max - a * max
Марк Лаката

1
Ви знаєте, як це цитувати? Я маю на увазі, чи є десь "оригінальна" довідка?
Trefex

3
@MarkLakata Незначне виправлення (помилка?): b = max' - a * maxАбоb = min' - (a * min)
Нік

@Nick - так. Я пропускаю '
Марк Лаката

Чи можете ви порівняти свою нормалізацію тут se.mathworks.com/matlabcentral/answers/…, тобто рівняння u = -1 + 2.*(u - min(u))./(max(u) - min(u));.
Лео Леопольд Герц 준영

13

Ось моя реалізація PHP для нормалізації:

function normalize($value, $min, $max) {
	$normalized = ($value - $min) / ($max - $min);
	return $normalized;
}

Але в той час як я будував власні штучні нейронні мережі, мені потрібно було перетворити нормалізований вихід назад до вихідних даних, щоб отримати гарний читабельний вихід для графіка.

function denormalize($normalized, $min, $max) {
	$denormalized = ($normalized * ($max - $min) + $min);
	return $denormalized;
}

$int = 12;
$max = 20;
$min = 10;

$normalized = normalize($int, $min, $max); // 0.2
$denormalized = denormalize($normalized, $min, $max); //12

Для денормалізації використовується наступна формула:

x(maxmin)+min


2
Існує важлива різниця між цією відповіддю і вже прийнятою відповіддю. Це пояснювало головну ідею чітко і безпосередньо, а потім вдруге показало, як це зробити в одній часто використовуваній програмі. І навпаки, ви розміщуєте тут лише код. Хоча я радий вважати, що це хороший код (я не пишу PHP) на цьому форумі, як правило, ми не маємо набір відповідей на кожне запитання, що пояснює, як це зробити будь-якою можливою мовою. Інакше ми мали би відповіді тут у SAS, SPSS, Stata, MATLAB, C, C ++, C #, Java. Пітон, тощо, тощо
Нік Кокс

2
Я не думаю, що це єдина різниця. У своєму коді я також показав, як повернути нормоване значення до значення, яке було до нормалізації. Я думаю, що це заслуговує на цю відповідь.
jankal

1
Це все-таки вірно, що ви публікуєте лише код: я думаю, вам потрібно підкреслити будь-які нібито особливі чесноти коду в коментарях, оскільки в іншому випадку читачі повинні прочитати код, щоб побачити, що вони є. Імовірно, інвертування масштабування використовується лише тоді, коли (a) початкові значення були перезаписані, але (b) користувач розважливо пам’ятав, щоб зберегти мінімум та максимум. Моя більш широка думка, як коментується вище, полягає в тому, що резюме не має на меті бути сховищем прикладів коду.
Нік Кокс

Є деякі проблеми, коли вам потрібно відновити значення: Nueral Networks, наприклад ... Але ви праві, що в аналізі даних ця відповідь дуже погана.
jankal

3
@NickCox Я вважав, що його відповідь задовільніша за прийняту.
Карл Моррісон

4

Ділення на нуль

Слід пам’ятати, що це max - minможе дорівнювати нулю. У цьому випадку ви не хочете виконувати цей поділ.

У випадку, коли це станеться, коли всі значення в списку, який ви намагаєтесь нормалізувати, однакові. Для нормалізації такого списку кожен пункт був би 1 / length.

// JavaScript
function normalize(list) {
   var minMax = list.reduce((acc, value) => {
      if (value < acc.min) {
         acc.min = value;
      }

      if (value > acc.max) {
         acc.max = value;
      }

      return acc;
   }, {min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY});

   return list.map(value => {
      // Verify that you're not about to divide by zero
      if (minMax.max === minMax.min) {
         return 1 / list.length
      }

      var diff = minMax.max - minMax.min;
      return (value - minMax.min) / diff;
   });
}

Приклад:

normalize([3, 3, 3, 3]); // output => [0.25, 0.25, 0.25, 0.25]

Це перерахунок на суму 1, а не на діапазон 0-1. Я просто думаю, що відповідь поза темою.
ttnphns

Не так. normalize([12, 20, 10])Виходи [0.2, 1.0, 0.0], те саме, що ви отримали б (val - min) / (max - min).
rodrigo-silveira

@ rodrigo-silveira Я не бачу, чому всі 0.25 вихід. Хіба не краще всі 0,5? Усі елементи рівні, тому їх слід тримати по центру в інтервалі.
javierdvalle

0

відповідь правильна, але у мене є пропозиція, що робити, якщо ваші дані тренувань стикаються з деякою кількістю поза діапазоном? ви можете використовувати техніку сквош. це гарантовано ніколи не вийде за межі діапазону. а не це

введіть тут опис зображення

я рекомендую використовувати це

введіть тут опис зображення

при такому тиску в хв і макс

введіть тут опис зображення

а розмір очікуваного розриву поза межами діапазону прямо пропорційний ступеня впевненості, що будуть значення поза межами діапазону.

для отримання додаткової інформації ви можете google: скоротити номери поза межами діапазону та звернутися до книги підготовки даних "доріанської палі"


5
Відредагуйте свою відповідь, щоб використовувати великі літери як звичайні. Послідовний нижній регістр може здатися кумедним чи ефективним, але читати майже кожному складніше.
Нік Кокс

3
Ілюстрації не передають належним чином вашу відповідь. Що саме таке "техніка розчавлення"?
whuber

0

Спробуйте це. Це відповідає шкалі функцій

normalize <- function(x) { 
  x <- as.matrix(x)
  minAttr=apply(x, 2, min)
  maxAttr=apply(x, 2, max)
  x <- sweep(x, 2, minAttr, FUN="-") 
  x=sweep(x, 2,  maxAttr-minAttr, "/") 
  attr(x, 'normalized:min') = minAttr
  attr(x, 'normalized:max') = maxAttr
  return (x)
} 

7
Існує важлива різниця між цією відповіддю і вже прийнятою відповіддю. Це пояснювало головну ідею чітко і безпосередньо, а потім вдруге показало, як це зробити в одній часто використовуваній програмі. І навпаки, ви розміщуєте тут лише код. Хоча я радий вважати, що це хороший код (якоюсь незрозумілою мовою) на цьому форумі, як правило, ми не маємо набір відповідей на кожне питання, що пояснює, як це зробити будь-якою можливою мовою. Інакше ми мали би відповіді тут у SAS, SPSS, Stata, MATLAB, C, C ++, C #, Java. Пітон, тощо, тощо
Нік Кокс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.