Provo a convertire il codice matlab in numpy e ho capito che numpy ha un risultato diverso con la funzione std.
in matlab
std([1,3,4,6])
ans = 2.0817
in numpy
np.std([1,3,4,6])
1.8027756377319946
È normale? E come dovrei gestirlo?
Provo a convertire il codice matlab in numpy e ho capito che numpy ha un risultato diverso con la funzione std.
in matlab
std([1,3,4,6])
ans = 2.0817
in numpy
np.std([1,3,4,6])
1.8027756377319946
È normale? E come dovrei gestirlo?
Risposte:
La funzione NumPy np.std
accetta un parametro opzionale ddof
: "Delta Degrees of Freedom". Per impostazione predefinita, questo è 0
. Impostalo su 1
per ottenere il risultato MATLAB:
>>> np.std([1,3,4,6], ddof=1)
2.0816659994661326
Per aggiungere un po 'più di contesto, nel calcolo della varianza (di cui la deviazione standard è la radice quadrata) tipicamente dividiamo per il numero di valori che abbiamo.
Ma se selezioniamo un campione casuale di N
elementi da una distribuzione più ampia e calcoliamo la varianza, la divisione per N
può portare a una sottostima della varianza effettiva. Per risolvere questo problema, possiamo ridurre il numero per cui dividiamo ( i gradi di libertà ) a un numero inferiore a N
(di solito N-1
). Il ddof
parametro ci consente di modificare il divisore per l'importo specificato.
Salvo diversa indicazione, NumPy calcolerà lo stimatore distorto per la varianza ( ddof=0
, dividendo per N
). Questo è ciò che vuoi se stai lavorando con l'intera distribuzione (e non un sottoinsieme di valori che sono stati scelti casualmente da una distribuzione più ampia). Se il ddof
parametro viene fornito, NumPy divide N - ddof
invece per.
Il comportamento predefinito di MATLAB std
è correggere il bias per la varianza del campione dividendo per N-1
. Questo elimina alcuni (ma probabilmente non tutti) i pregiudizi nella deviazione standard. Questo è probabilmente quello che vuoi se stai usando la funzione su un campione casuale di una distribuzione più ampia.
La bella risposta di @hbaderts fornisce ulteriori dettagli matematici.
La deviazione standard è la radice quadrata della varianza. La varianza di una variabile casuale X
è definita come
Uno stimatore per la varianza sarebbe quindi
dove indica la media del campione. Per selezionati casualmente , si può dimostrare che questo stimatore non converge alla varianza reale, ma a
Se si selezionano campioni casualmente e si stima la media e la varianza del campione, sarà necessario utilizzare uno stimatore corretto (imparziale)
che convergeranno a . Il termine di correzione è anche chiamato correzione di Bessel.
Ora, per impostazione predefinita, MATLABs std
calcola lo stimatore imparziale con il termine di correzione n-1
. NumPy tuttavia (come spiegato da @ajcr) calcola per impostazione predefinita lo stimatore distorto senza termine di correzione. Il parametro ddof
permette di impostare qualsiasi termine di correzione n-ddof
. Impostandolo a 1 si ottiene lo stesso risultato di MATLAB.
Allo stesso modo, MATLAB permette di aggiungere un secondo parametro w
, che specifica lo "schema di pesatura". L'impostazione predefinita,, w=0
risulta nel termine di correzione n-1
(stimatore imparziale), mentre per w=1
, solo n viene utilizzato come termine di correzione (stimatore distorto).
n
andare all'inizio della notazione di sommatoria, è andato all'interno della somma.
Per le persone che non sono brave con le statistiche, una guida semplicistica è:
Includi ddof=1
se stai calcolando np.std()
per un campione tratto dal tuo set di dati completo.
Assicurati ddof=0
di eseguire il calcolo np.std()
per l'intera popolazione
Il DDOF è incluso per i campioni al fine di controbilanciare il bias che può verificarsi nei numeri.
std([1 3 4 6],1)
è equivalente al valore predefinito di NumPynp.std([1,3,4,6])
. Tutto questo è spiegato abbastanza chiaramente nella documentazione per Matlab e NumPy, quindi consiglio vivamente che l'OP si assicuri di leggerli in futuro.