Как нормализовать данные в диапазоне 0-1?


267

Я потерян в нормировании, может кто-нибудь направит меня, пожалуйста.

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

Если я получу значение 5,6878, как я могу масштабировать это значение по шкале от 0 до 1.


8
это путь = (значение-мин) / (макс-мин)
Angelo

3
Это может помочь вам прочитать эту ветку: как проверить правильность распределения . Если это отвечает на ваш вопрос, вы можете удалить этот вопрос; если нет, отредактируйте свой Q, чтобы указать то, что вы все еще не понимаете.
Gung

1
Объяснение защиты: Этот вопрос привлекает дополнительные ответы, содержащие только решения кода. Хотя они могут быть интересными или полезными для некоторых читателей, целью CV не является предоставление репозиториев программных решений.
Ник Кокс

1
В представленных решениях учитывается значение линейного контраста. Хотите ли вы другую нормализацию, например, такую, которая бы обеспечивала равномерную вероятность для результата?
Медуз

Ответы:


300

Если вы хотите нормализовать ваши данные, вы можете сделать это так, как вы предлагаете, и просто рассчитать следующее:

Zязнак равноИкся-мин(Икс)Максимум(Икс)-мин(Икс)

где Иксзнак равно(Икс1,,,,,ИксN) и Zя теперь ваш яTчас нормализованный данные. В качестве подтверждения концепции (хотя вы не просили об этом) приведем Rкод и сопровождающий график, чтобы проиллюстрировать этот момент:

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

# 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, а затем до значения, которые вы получаете от этого просто добавив МИН. Поэтому масштабируйте до 90, а затем добавьте 10. Этого должно быть достаточно для большинства пользовательских диапазонов, которые вы можете захотеть.
Александр Росса

47

Общая однострочная формула для линейного масштабирования значений данных с учетом min и max в новый произвольный диапазон min ' to 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)
Ник

@ Ник - да. Я
скучаю

Можете ли вы сравнить вашу нормировку здесь 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

Денормализация использует следующую формулу:

Икс(Максимум-мин)+мин


2
Существует важное различие между этим ответом и уже принятым ответом. Это объясняет основную идею четко и прямо, а затем вторично показывает, как это сделать в одной обычно используемой программе. И наоборот, вы размещаете здесь только код. Несмотря на то, что я рад, что это хороший код (я не пишу PHP) на этом форуме, у нас обычно нет пакета ответов на каждый вопрос, объясняющего, как это сделать на всех мыслимых языках. В противном случае у нас были бы ответы здесь в SAS, SPSS, Stata, MATLAB, C, C ++, C #, Java. Питон и т. Д. И т. Д.
Ник Кокс,

2
Я не думаю, что это единственная разница. В своем коде я также показал, как вернуть нормализованное значение к значению, которое было до нормализации. Я думаю, это стоит того, чтобы ответить.
Январь

1
Все еще верно, что вы публикуете только код: я думаю, что вам нужно подчеркивать любые предположительно особые достоинства кода в комментариях, так как в противном случае читатели должны читать код, чтобы увидеть, что это такое. Предположительно инвертирование масштабирования полезно только тогда, когда (а) исходные значения были перезаписаны, но (б) пользователь разумно запомнил сохранение минимума и максимума. Мое более широкое замечание, как прокомментировано выше, состоит в том, что CV не стремится быть хранилищем примеров кода.
Ник Кокс

Есть некоторые проблемы, когда вам нужно восстановить значение: Nueral Networks, например ... Но вы правы, в смысле анализа данных, этот ответ очень плохой.
Январь

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 Я не понимаю, почему все 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.