Come normalizzare i dati nell'intervallo 0-1?


267

Mi sono perso nella normalizzazione, qualcuno potrebbe guidarmi per favore.

Ho un valore minimo e massimo, diciamo rispettivamente -23.89 e 7.54990767.

Se ottengo un valore di 5,6878 come posso ridimensionare questo valore su una scala da 0 a 1.


8
è così = (valore-min) / (massimo-min)
Angelo

3
Può aiutarti a leggere questa discussione: come-verificare-una-distribuzione-è-normalizzata . Se questo risponde alla tua domanda, puoi eliminare questa Q; in caso contrario, modifica la tua Q per specificare ciò che ancora non capisci.
gung

1
Spiegazione di protezione: questa domanda sta attirando risposte extra contenenti solo soluzioni di codice. Sebbene questi possano essere interessanti o utili per alcuni lettori, non è uno scopo del CV fornire archivi di soluzioni di codice.
Nick Cox,

1
le soluzioni fornite considerano un valore di contrasto lineare - desideri una diversa normalizzazione, ad esempio una che raggiunga una probabilità uniforme per l'output?
Meduz,

Risposte:


299

Se vuoi normalizzare i tuoi dati, puoi farlo come suggerisci e semplicemente calcolare quanto segue:

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

dove e sono ora tuoi dati normalizzati . Come prova del concetto (anche se non lo hai richiesto) ecco un po 'di codice e un grafico che accompagna per illustrare questo punto:x=(x1,...,xn)ziithR

inserisci qui la descrizione dell'immagine

# 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
Mi chiedo solo come fanno i due istogrammi di aspetto piuttosto diverso illustrate the pointdella tua (corretta) risposta?
ttnphns,

12
@ttnphns Sembrano diversi solo a causa del binning degli istogrammi. Il mio punto tuttavia era mostrare che i valori originali vivevano tra -100 e 100 e ora dopo la normalizzazione vivono tra 0 e 1. Avrei potuto usare un grafico diverso per mostrare questo suppongo o solo statistiche riassuntive.

20
La leggera spinta di @ttnphns aveva lo scopo di incoraggiarti non solo a utilizzare un mezzo meno complicato per illustrare un'idea (semplice), ma anche (sospetto) come suggerimento che un'illustrazione più direttamente pertinente potrebbe essere utile qui. Puoi fare entrambe le cose trovando un modo più semplice per rappresentare graficamente la trasformazione quando viene applicata al minimo e al massimo effettivamente forniti dall'OP
whuber

1
Esiste un modo per "normalizzare" l'intervallo personalizzato anziché 0-1?
John Demetriou,

1
@JohnDemetriou Potrebbe non essere la soluzione più pulita, ma è possibile ridimensionare i valori normalizzati per farlo. Se vuoi ad esempio un intervallo di 0-100, devi solo moltiplicare ogni numero per 100. Se vuoi un intervallo che non inizia con 0, come 10-100, lo faresti ridimensionando per MAX-MIN e poi per il valori che ottieni semplicemente aggiungendo il MIN. Quindi ridimensiona di 90, quindi aggiungi 10. Questo dovrebbe essere sufficiente per la maggior parte degli intervalli personalizzati che potresti desiderare.
Alexander Rossa,

47

La formula generale a una riga per ridimensionare linearmente i valori dei dati dopo aver osservato min e max in un nuovo intervallo arbitrario min ' a max' è

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

9
Questo è corretto, ma non efficiente. È una trasformazione lineare, quindi dovresti precalcolare ae bcostanti, e quindi applicare newvalue = a * value + b. a = (max'-min')/(max-min)eb = max - a * max
Mark Lakata,

1
Sai come citare questo? Voglio dire, c'è un riferimento "originale" da qualche parte?
Trefex,

3
@MarkLakata Correzione lieve (errore di battitura?): b = max' - a * maxOppureb = min' - (a * min)
Nick,

@Nick - si. Mi manca un '
Mark Lakata il

Potete per favore confrontare la vostra normalizzazione qui se.mathworks.com/matlabcentral/answers/… cioè l'equazione u = -1 + 2.*(u - min(u))./(max(u) - min(u));.
Léo Léopold Hertz

13

Ecco la mia implementazione di PHP per la normalizzazione:

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

Ma mentre stavo costruendo le mie reti neurali artificiali, avevo bisogno di trasformare l'output normalizzato ai dati originali per ottenere un output leggibile per il grafico.

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 denormalizzazione utilizza la seguente formula:

x(maxmin)+min


2
C'è una differenza importante tra questa risposta e la risposta già accettata. Ciò ha spiegato l'idea principale in modo chiaro e diretto e poi ha mostrato secondariamente come farlo in un programma comunemente usato. Al contrario, pubblichi qui solo il codice. Anche se sono felice di credere che questo sia un buon codice (non scrivo PHP) su questo forum, normalmente non abbiamo un fascio di risposte a ogni domanda che spieghi come farlo in ogni linguaggio immaginabile. Altrimenti avremmo risposte qui in SAS, SPSS, Stata, MATLAB, C, C ++, C #, Java. Python, ecc. Ecc.
Nick Cox,

2
Non penso che questa sia l'unica differenza. Nel mio codice, ho anche mostrato come restituire un valore normalizzato al valore precedente alla normalizzazione. Penso che valga la pena rispondere.
jankal,

1
È ancora vero che pubblichi solo codice: penso che tu debba enfatizzare qualsiasi virtù apparentemente speciale del codice nei commenti, poiché altrimenti i lettori devono leggere il codice per vedere cosa sono. Presumibilmente invertire il ridimensionamento è utile solo quando (a) i valori originali sono stati sovrascritti ma (b) l'utente ha prudentemente ricordato di salvare il minimo e il massimo. Il mio punto più ampio, come commentato sopra, è che CV non mira ad essere un repository di esempi di codice.
Nick Cox,

Ci sono alcuni problemi, dove è necessario ripristinare il valore: Nueral Networks ad esempio ... Ma hai ragione, in termini di analisi dei dati, questa risposta è pessima.
jankal,

3
@NickCox Ho trovato la sua risposta più soddisfacente di quella accettata.
Karl Morrison,

4

Divisione per zero

Una cosa da tenere a mente è che max - minpotrebbe essere uguale a zero. In questo caso, non vorrai eseguire quella divisione.

Il caso in cui ciò accada è quando tutti i valori nell'elenco che stai tentando di normalizzare sono gli stessi. Per normalizzare tale elenco, ogni elemento sarebbe 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;
   });
}

Esempio:

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

Questo è un riscalamento di una somma 1, non di un intervallo 0-1. Penso solo che la risposta sia fuori tema quindi.
ttnphns,

Non così. normalize([12, 20, 10])output [0.2, 1.0, 0.0], che è lo stesso che otterresti (val - min) / (max - min).
rodrigo-silveira,

@ rodrigo-silveira Non vedo perché l'output di tutti 0,25. Non è meglio tutto 0,5? Tutti gli elementi sono uguali, quindi devono essere mantenuti centrati nell'intervallo.
javierdvalle,

0

la risposta è giusta ma ho un suggerimento, cosa succede se i tuoi dati di allenamento affrontano un numero fuori portata? potresti usare la tecnica di schiacciamento. sarà garantito per non andare mai fuori portata. piuttosto che questo

inserisci qui la descrizione dell'immagine

ti consiglio di usare questo

inserisci qui la descrizione dell'immagine

con schiacciamento come questo in min e max di portata

inserisci qui la descrizione dell'immagine

e la dimensione del gap fuori range atteso è direttamente proporzionale al grado di confidenza che ci saranno valori fuori range.

per maggiori informazioni puoi google: schiacciare i numeri fuori range e fare riferimento al libro di preparazione dei dati di "dorian pyle"


5
Modifica la risposta per utilizzare le maiuscole come convenzionali. Le lettere minuscole coerenti possono sembrare divertenti o efficienti, ma è più difficile da leggere per quasi tutti.
Nick Cox,

3
Le illustrazioni non trasmettono adeguatamente la tua risposta. Cos'è esattamente una "tecnica di schiacciamento"?
whuber

0

Prova questo. È coerente con la scala delle funzioni

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
C'è una differenza importante tra questa risposta e la risposta già accettata. Ciò ha spiegato l'idea principale in modo chiaro e diretto e poi ha mostrato secondariamente come farlo in un programma di uso comune. Al contrario, pubblichi qui solo il codice. Anche se sono felice di credere che questo sia un buon codice (in una lingua inspiegabile) su questo forum, normalmente non abbiamo un fascio di risposte a ogni domanda che spieghi come farlo in ogni lingua immaginabile. Altrimenti avremmo risposte qui in SAS, SPSS, Stata, MATLAB, C, C ++, C #, Java. Python, ecc. Ecc.
Nick Cox,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.