245
$\begingroup$

I am lost in normalizing, could anyone guide me please.

I have a minimum and maximum values, say -23.89 and 7.54990767, respectively.

If I get a value of 5.6878 how can I scale this value on a scale of 0 to 1.

$\endgroup$
  • 8
    $\begingroup$ is this the way =(value-min)/(max-min) $\endgroup$ – Angelo Sep 23 '13 at 15:31
  • 2
    $\begingroup$ It may help you to read this thread: how-to-verify-a-distribution-is-normalized. If that answers your question, you can delete this Q; if not, edit your Q to specify what you still don't understand. $\endgroup$ – gung Sep 23 '13 at 16:00
  • $\begingroup$ Explanation of protection: This question is attracting extra answers containing code solutions only. While these may be interesting or useful to some readers, it's not an aim of CV to provide repositories of code solutions. $\endgroup$ – Nick Cox May 27 '15 at 8:42
  • $\begingroup$ the solutions provided consider a linear contrast value - would you like a different normalization, for instance one that achieve an uniform probability for the output? $\endgroup$ – meduz May 21 '18 at 16:31
273
$\begingroup$

If you want to normalize your data, you can do so as you suggest and simply calculate the following:

$$z_i=\frac{x_i-\min(x)}{\max(x)-\min(x)}$$

where $x=(x_1,...,x_n)$ and $z_i$ is now your $i^{th}$ normalized data. As a proof of concept (although you did not ask for it) here is some R code and accompanying graph to illustrate this point:

enter image description here

# 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="")
$\endgroup$
  • 10
    $\begingroup$ I only wonder how the two quite different-looking histograms do illustrate the point of your (correct) answer? $\endgroup$ – ttnphns Sep 23 '13 at 16:21
  • 11
    $\begingroup$ @ttnphns They look only different due to the binning of the histograms. My point however was to show that the original values lived between -100 to 100 and now after normalization they live between 0 and 1. I could have used a different graph to show this I suppose or just summary statistics. $\endgroup$ – user25658 Sep 23 '13 at 16:23
  • 17
    $\begingroup$ The gentle nudge by @ttnphns was meant to encourage you not only to use a less complicated means of illustrating a (simple) idea, but also (I suspect) as a hint that a more directly relevant illustration might be beneficial here. You could do both by finding a more straightforward way to graph the transformation when it is applied to the min and max actually supplied by the O.P. $\endgroup$ – whuber Sep 23 '13 at 17:12
  • 1
    $\begingroup$ Is there a way to "normalize" to custom range instead of 0-1? $\endgroup$ – John Demetriou Oct 25 '16 at 11:46
  • 1
    $\begingroup$ @JohnDemetriou May not be the cleanest solution, but you can scale the normalized values to do that. If you want for example range of 0-100, you just multiply each number by 100. If you want range that is not beginning with 0, like 10-100, you would do it by scaling by the MAX-MIN and then to the values you get from that just adding the MIN. So scale by 90, then add 10. That should be enough for most of the custom ranges you may want. $\endgroup$ – Alexander Rossa Oct 29 '17 at 18:54
42
$\begingroup$

The general one-line formula to linearly rescale data values having observed min and max into a new arbitrary range min' to max' is

  newvalue= (max'-min')/(max-min)*(value-max)+max'
  or
  newvalue= (max'-min')/(max-min)*(value-min)+min'.
$\endgroup$
  • 8
    $\begingroup$ This is correct, but not efficient. It is a linear transformation, so you would precalculate a and b constants, and then just apply newvalue = a * value + b. a = (max'-min')/(max-min) and b = max - a * max $\endgroup$ – Mark Lakata Sep 23 '13 at 19:18
  • $\begingroup$ Do you know how to cite this? I mean, is there an "original" reference somewhere? $\endgroup$ – Trefex May 11 '14 at 20:18
  • 2
    $\begingroup$ @MarkLakata Slight (typo?) correction: b = max' - a * max or b = min' - (a * min) $\endgroup$ – Nick Dec 29 '14 at 18:09
  • $\begingroup$ @Nick - yes. I'm missing a ' $\endgroup$ – Mark Lakata Dec 30 '14 at 5:33
  • $\begingroup$ Can you please compare your normalisation here se.mathworks.com/matlabcentral/answers/… i.e. the equation u = -1 + 2.*(u - min(u))./(max(u) - min(u));. $\endgroup$ – Léo Léopold Hertz 준영 Oct 24 '16 at 21:41
12
$\begingroup$

Here is my PHP implementation for normalisation:

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

But while I was building my own artificial neural networks, I needed to transform the normalized output back to the original data to get good readable output for the graph.

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

Denormalisation uses the following formula:

$x (\text{max} - \text{min}) + \text{min}$

$\endgroup$
  • 2
    $\begingroup$ There is an important difference between this answer and the already accepted answer. That explained the main idea clearly and directly and then secondarily showed how to do it in one commonly used program. Conversely, you post here only code. While I am happy to believe that this is good code (I don't write PHP) on this forum we don't normally have a bundle of answers to every question explaining how to do it in every conceivable language. Otherwise we would have answers here in SAS, SPSS, Stata, MATLAB, C, C++, C#, Java. Python, etc, etc. $\endgroup$ – Nick Cox May 27 '15 at 8:38
  • 2
    $\begingroup$ I don't think, that this is the only difference. In my code, I also showed, how to return a normalized value to the value it was before normalisation. I think, that makes it worth this answer. $\endgroup$ – jankal May 27 '15 at 9:02
  • 1
    $\begingroup$ It's still true that you post only code: I think you need to emphasise any supposedly special virtues of code in commentary, as otherwise readers have to read the code to see what they are. Presumably inverting the scaling is of use only when (a) the original values have been overwritten but (b) the user has prudently remembered to save the minimum and maximum. My wider point, as commented above, is that CV does not aim to be a repository of code examples. $\endgroup$ – Nick Cox May 27 '15 at 9:10
  • $\begingroup$ There are some problems, whre you need to restore the value: Nueral Networks for example... But you're right, in manner of data analysis, this answer is very bad. $\endgroup$ – jankal May 27 '15 at 9:25
  • 3
    $\begingroup$ @NickCox I found his answer to be more satisfactory than the accepted one. $\endgroup$ – Karl Morrison Aug 30 '15 at 18:40
4
$\begingroup$

Division by zero

One thing to keep in mind is that max - min could equal zero. In this case, you would not want to perform that division.

The case where this would happen is when all values in the list you're trying to normalize are the same. To normalize such a list, each item would be 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;
   });
}

Example:

normalize([3, 3, 3, 3]); // output => [0.25, 0.25, 0.25, 0.25]
$\endgroup$
  • $\begingroup$ This is a rescaling to a sum 1, not to a range 0-1. I just think the answer is off-topic therefore. $\endgroup$ – ttnphns Oct 4 '17 at 17:31
  • $\begingroup$ Not so. normalize([12, 20, 10]) outputs [0.2, 1.0, 0.0], which is the same you would get with (val - min) / (max - min). $\endgroup$ – rodrigo-silveira Jan 16 at 15:23
  • $\begingroup$ @rodrigo-silveira I don't see why the all 0.25 output. Isn't it better all 0.5? All items are equal, so should be kept centered in the interval. $\endgroup$ – javierdvalle Apr 2 at 14:56
0
$\begingroup$

the answer is right but i have a suggestion , what if your training data face some number out of range ? you could use squashing technique. it will be guaranteed never to go out of range. rather than this

enter image description here

i recommend use this

enter image description here

with squashing like this in min and max of range

enter image description here

and the size of the expected out-of-range gap is directly proportional to the degree of confidence that there will be out-of-range values.

for more information you can google : squashing the out-of-range numbers and refer to data preparation book of "dorian pyle"

$\endgroup$
  • 4
    $\begingroup$ Please edit your answer to use capitalisation as conventional. Consistent lower case may seem amusing or efficient, but it is more difficult for almost everyone to read. $\endgroup$ – Nick Cox Sep 25 '13 at 12:12
  • 2
    $\begingroup$ The illustrations do not adequately convey your answer. What exactly is a "squashing technique"? $\endgroup$ – whuber Sep 25 '13 at 14:47
0
$\begingroup$

Try this. It is consistent with the function scale

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)
} 
$\endgroup$
  • 6
    $\begingroup$ There is an important difference between this answer and the already accepted answer. That explained the main idea clearly and directly and then secondarily showed how to do it in one commonly used program. Conversely, you post here only code. While I am happy to believe that this is good code (in some unexplained language) on this forum we don't normally have a bundle of answers to every question explaining how to do it in every conceivable language. Otherwise we would have answers here in SAS, SPSS, Stata, MATLAB, C, C++, C#, Java. Python, etc, etc. $\endgroup$ – Nick Cox May 27 '15 at 8:35

protected by Nick Cox May 27 '15 at 8:40

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.