Comment normaliser les données dans la plage 0-1?


267

Je suis perdu dans la normalisation, quelqu'un pourrait-il me guider s'il vous plaît.

J'ai un minimum et des valeurs maximales, par exemple -23,89 et 7,54990767, respectivement.

Si j’obtiens une valeur de 5,6878, comment puis-je redimensionner cette valeur sur une échelle de 0 à 1?


8
est-ce ainsi = (valeur-min) / (max-min)
Angelo

3
Cela peut vous aider à lire ce fil de discussion: comment vérifier une distribution est normalisée . Si cela répond à votre question, vous pouvez supprimer ce Q; sinon, éditez votre Q pour spécifier ce que vous ne comprenez toujours pas.
gung

1
Explication de la protection: Cette question attire des réponses supplémentaires contenant uniquement des solutions de code. Bien que ceux-ci puissent être intéressants ou utiles pour certains lecteurs, l’objectif de CV n’est pas de fournir des référentiels de solutions de code.
Nick Cox

1
les solutions proposées considèrent une valeur de contraste linéaire - aimeriez-vous une normalisation différente, par exemple une normalisation qui permet d'obtenir une probabilité uniforme pour la sortie?
meduz

Réponses:


300

Si vous souhaitez normaliser vos données, vous pouvez le faire comme vous le suggérez et calculer simplement ce qui suit:

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

où et sont maintenant vos données normalisées . Comme preuve de concept (bien que vous ne l'ayez pas demandé), voici un code et un graphique pour illustrer ce point:x=(x1,...,xn)ziithR

entrez la description de l'image ici

# 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
Je me demande seulement comment les deux histogrammes d'aspect très différent font illustrate the pointde votre réponse (correcte)?
ttnphns

12
@ttnphns Ils ne semblent différents qu'en raison du tri des histogrammes. Mon but était cependant de montrer que les valeurs initiales vivaient entre -100 et 100 et que maintenant, après normalisation, elles vivaient entre 0 et 1. J'aurais pu utiliser un graphique différent pour montrer ceci, je suppose ou simplement des statistiques résumées.

20
Le petit coup de pouce de @ttnphns était destiné à vous encourager non seulement à utiliser un moyen moins compliqué d’illustrer une idée (simple), mais également (à mon avis) comme un indice qu’une illustration plus directement pertinente pourrait être utile ici. Vous pouvez faire les deux en trouvant un moyen plus simple de représenter graphiquement la transformation lorsqu'elle est appliquée aux
valeurs

1
Existe-t-il un moyen de "normaliser" une plage personnalisée au lieu de 0-1?
John Demetriou

1
@JohnDemetriou Peut ne pas être la solution la plus propre, mais vous pouvez mettre à l'échelle les valeurs normalisées pour le faire. Si vous voulez par exemple une plage de 0 à 100, il vous suffit de multiplier chaque nombre par 100. Si vous voulez une plage qui ne commence pas par 0, comme 10 à 100, vous le feriez en mettant à l'échelle MAX-MIN, puis à les valeurs que vous obtenez de cela en ajoutant simplement le MIN. Adoptez une échelle de 90, puis ajoutez 10. Cela devrait suffire pour la plupart des gammes personnalisées souhaitées.
Alexander Rossa

47

La formule générale à une ligne pour redimensionner linéairement les valeurs de données ayant observé min et max dans une nouvelle plage arbitraire min ' à max' est

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

9
C'est correct, mais pas efficace. Il s’agit d’une transformation linéaire, vous devez donc calculer aet calculer les bconstantes, puis les appliquer newvalue = a * value + b. a = (max'-min')/(max-min)etb = max - a * max
Mark Lakata le

1
Savez-vous comment citer cela? Je veux dire, y a-t-il une référence "originale" quelque part?
Trefex

3
@MarkLakata Correction légère (faute de frappe?): b = max' - a * maxOub = min' - (a * min)
Nick

@ Nick - oui. Il me manque un
Mark Lakata

Pouvez-vous s'il vous plaît comparer votre normalisation ici se.mathworks.com/matlabcentral/answers/… c'est à dire l'équation u = -1 + 2.*(u - min(u))./(max(u) - min(u));.
Léo Léopold Hertz

13

Voici mon implémentation PHP pour la normalisation:

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

Mais pendant que je construisais mes propres réseaux de neurones artificiels, je devais reconvertir la sortie normalisée en données d'origine pour obtenir une sortie lisible pour le graphique.

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

La dénormalisation utilise la formule suivante:

X(max-min)+min


2
Il existe une différence importante entre cette réponse et la réponse déjà acceptée. Cela expliquait clairement et directement l'idée principale et ensuite, secondairement, comment le faire dans un programme communément utilisé. Inversement, vous postez ici uniquement du code. Bien que je sois heureux de croire que c’est un bon code (je n’écris pas PHP) sur ce forum, nous n’avons normalement pas beaucoup de réponses à toutes les questions qui expliquent comment le faire dans toutes les langues imaginables. Sinon, nous aurions des réponses ici en SAS, SPSS, Stata, MATLAB, C, C ++, C #, Java. Python, etc., etc.
Nick Cox

2
Je ne pense pas que ce soit la seule différence. Dans mon code, j'ai également montré comment renvoyer une valeur normalisée à la valeur qu'elle était avant la normalisation. Je pense que cela en vaut la peine.
jankal

1
Il est toujours vrai que vous ne publiez que du code: je pense que vous devez mettre l'accent sur les vertus supposées spéciales du code dans les commentaires, sinon les lecteurs doivent lire le code pour voir ce qu'ils sont. Il est vraisemblable que l’inversion de la mise à l’échelle n’est utile que lorsque (a) les valeurs initiales ont été écrasées mais (b) que l’utilisateur se soit prudemment rappelé d’enregistrer le minimum et le maximum. Comme indiqué ci-dessus, mon argument plus général est que CV ne vise pas à être un référentiel d’exemples de code.
Nick Cox

Il y a quelques problèmes, dont vous avez besoin pour restaurer la valeur: Nueral Networks par exemple ... Mais vous avez raison, en termes d'analyse de données, cette réponse est très mauvaise.
jankal

3
@ NickCox J'ai trouvé sa réponse plus satisfaisante que celle acceptée.
Karl Morrison

4

Division par zéro

Une chose à garder à l'esprit est que cela max - minpourrait être égal à zéro. Dans ce cas, vous ne voudriez pas effectuer cette division.

Cela se produit lorsque toutes les valeurs de la liste que vous essayez de normaliser sont identiques. Pour normaliser une telle liste, chaque élément serait 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;
   });
}

Exemple:

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

Il s’agit d’une remise à l’échelle à la somme 1 et non à la plage 0-1. Je pense juste que la réponse est donc hors sujet.
ttnphns

Pas si. normalize([12, 20, 10])sorties [0.2, 1.0, 0.0], ce qui est le même que vous obtiendrez (val - min) / (max - min).
rodrigo-silveira

@ rodrigo-silveira Je ne vois pas pourquoi le tout 0,25 sortie. N'est-ce pas mieux tous les 0.5? Tous les éléments sont égaux, doivent donc être maintenus centrés dans l'intervalle.
javierdvalle le

0

la réponse est correcte, mais j’ai une suggestion à faire. Que se passe-t-il si vos données d’entraînement font face à un nombre en dehors des limites? vous pouvez utiliser la technique de compression. il sera garanti de ne jamais sortir de la plage. plutôt que cela

entrez la description de l'image ici

Je recommande d'utiliser ceci

entrez la description de l'image ici

avec écraser comme ça en min et max de gamme

entrez la description de l'image ici

et la taille de l'écart hors limite prévu est directement proportionnelle au degré de confiance qu'il y aura des valeurs hors limites.

Pour plus d'informations, vous pouvez utiliser Google: écrasez les numéros hors limites et reportez-vous au livre de préparation des données de "dorian pyle".


5
Veuillez modifier votre réponse pour utiliser la capitalisation de manière conventionnelle. Des minuscules cohérentes peuvent sembler amusantes ou efficaces, mais il est plus difficile à lire pour presque tout le monde.
Nick Cox

3
Les illustrations ne traduisent pas correctement votre réponse. Qu'est-ce qu'une "technique de compression"?
whuber

0

Essaye ça. Il est cohérent avec l' échelle de la fonction

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
Il existe une différence importante entre cette réponse et la réponse déjà acceptée. Cela expliquait clairement et directement l'idée principale et ensuite, secondairement, comment le faire dans un programme communément utilisé. Inversement, vous postez ici uniquement du code. Bien que je sois heureux de croire que c’est un bon code (dans une langue inexpliquée) sur ce forum, nous n’avons normalement pas un paquet de réponses à toutes les questions expliquant comment le faire dans toutes les langues imaginables. Sinon, nous aurions des réponses ici en SAS, SPSS, Stata, MATLAB, C, C ++, C #, Java. Python, etc., etc.
Nick Cox
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.