Come campionare da una distribuzione normale con media e varianza note usando un linguaggio di programmazione convenzionale?


36

Non ho mai frequentato un corso di statistica, quindi spero di chiedere nel posto giusto qui.

Supponiamo di avere solo due dati che descrivono una distribuzione normale: la media e la varianza σ 2 . Voglio usare un computer per campionare casualmente da questa distribuzione in modo da rispettare queste due statistiche.μσ2

È abbastanza ovvio che posso gestire la media semplicemente normalizzando circa 0: basta aggiungere a ciascun campione prima di emettere il campione. Ma non vedo come generare a livello di codice campioni per rispettare σ 2 .μσ2

Il mio programma sarà in un linguaggio di programmazione convenzionale; Non ho accesso ad alcun pacchetto statistico.


La tua lingua ha un generatore di numeri casuali? Questo generatore proviene solo dalla distribuzione uniforme o può generare anche dalla distribuzione normale?
ttnphns,

@ttnphns: praticamente tutti i linguaggi per computer sono dotati di un generatore di numeri casuali. Sono generatori straordinariamente uniformi su qualche dominio finito.
Fixee,

Risposte:


33

Se è possibile campionare da una data distribuzione con media 0 e varianza 1, allora è possibile campionare facilmente da una trasformazione in scala di tale distribuzione, che ha media e varianza σ 2 . Se x è un campione da una media 0 e distribuzione della varianza 1, allora σ x + μ è un campione con media μ e varianza σ 2 . Quindi, tutto quello che devi fare è ridimensionare la variabile in base alla deviazione standard σ (radice quadrata della varianza) prima di aggiungere la media μ .μσ2x

σx+μ
μσ2σμ

Come si ottiene effettivamente una simulazione da una distribuzione normale con media 0 e varianza 1 è una storia diversa. È divertente e interessante sapere come implementare tali cose, ma se si utilizza un pacchetto statistico o un linguaggio di programmazione o meno, consiglierò di ottenere e utilizzare una funzione o libreria adatta per la generazione di numeri casuali. Se vuoi un consiglio su quale libreria usare potresti voler aggiungere informazioni specifiche su quale linguaggio (i) di programmazione stai usando.

Modifica: Alla luce dei commenti, di alcune altre risposte e del fatto che Fixee abbia accettato questa risposta, fornirò alcuni dettagli in più su come è possibile utilizzare trasformazioni di variabili uniformi per produrre variabili normali.

  • Un metodo, già menzionato in un commento di VitalStatistix , è il metodo Box-Muller che accetta due variabili casuali uniformi indipendenti e produce due variabili casuali normali indipendenti. Un metodo simile che evita il calcolo di due funzioni trascendenti sin e cos a spese di alcune simulazioni è stato pubblicato come risposta da francogrex .
  • Un metodo completamente generale è la trasformazione di una variabile casuale uniforme mediante la funzione di distribuzione inversa. Se è distribuito uniformemente su [ 0 , 1 ], allora Φ - 1 ( U ) ha una distribuzione normale standard. Sebbene non esista una formula analitica esplicita per Φ - 1 , può essere calcolata mediante approssimazioni numeriche accurate. L'implementazione corrente in R (ultimo controllo) utilizza questa idea. Il metodo è concettualmente molto semplice, ma richiede un'implementazione accurata di Φ - 1 , che probabilmente non è così diffusa come le (altre) funzioni trascendentaliU[0,1]
    Φ1(U)
    Φ1Φ1log , sin e cos .
  • Diverse risposte menzionano la possibilità di usare il teorema del limite centrale per approssimare la distribuzione normale come media di variabili casuali uniformi. Questo non è generalmente raccomandato. Gli argomenti presentati, come la corrispondenza della media 0 e della varianza 1, e le considerazioni a sostegno della distribuzione non sono convincenti. Nell'esercizio 2.3 in "Presentazione dei metodi Monte Carlo con R" di Christian P. Robert e George Casella questo generatore è chiamato antiquato e l'approssimazione è chiamata molto scarsa .
  • C'è un numero sconcertante di altre idee. Il capitolo 3 e, in particolare, la sezione 3.4, in "L'arte della programmazione informatica" vol. 2 di Donald E. Knuth è un riferimento classico alla generazione di numeri casuali. Brian Ripley ha scritto Generazione al computer di variabili casuali: un tutorial , che può essere utile. Si raccomanda anche il libro citato da Robert e Casella, o forse il capitolo 2 dell'altro libro, "Metodi statistici di Monte Carlo".

Alla fine della giornata, un metodo implementato correttamente non è migliore del generatore di numeri pseudo casuali uniforme usato. Personalmente, preferisco fare affidamento su librerie per scopi speciali che ritengo affidabili. Mi affido quasi sempre ai metodi implementati in R direttamente in R o tramite l'API in C / C ++. Ovviamente, questa non è una soluzione per tutti, ma non ho abbastanza familiarità con altre librerie per raccomandare alternative.


(+1) Buona risposta e consigli per il PO.
cardinale

18
-2log(U1)cos(2πU2)
-2log(U1)peccato(2πU2)

2
@Vital: non un commento non necessario; una buona. La trasformazione di Box-Muller è probabilmente la più semplice da programmare con la minima possibilità di fare inavvertitamente qualcosa di brutto. Non è il più veloce , ma è abbastanza competitivo. Detto questo, l'utilizzo di una libreria di codici consolidata è probabilmente ancora più sicuro, soprattutto perché il luogo in cui è più probabile che si verifichi un passo falso è il modo in cui vengono generati input di variabili casuali uniformi !
cardinale

@Vital: Grazie, questo è quello che stavo cercando. Se vuoi convertire il tuo commento in una risposta, sarei felice di votarlo.
Fixee,

1
@VitalStatistix, è un bel commento, e sembra che questo fosse ciò che l'OP stava cercando. Perché non trasformarlo in una risposta e forse elaborarlo un po 'sull'idea generale di usare trasformazioni di variabili casuali uniformi. Ho esitato a farlo per il motivo che Cardinale menziona principalmente perché non so se il generatore uniforme predefinito di qualsiasi lingua sia un buon generatore.
NRH,

10

Questo è davvero un commento sulla risposta di Michael Lew e sul commento di Fixee, ma viene pubblicato come risposta perché non ho la reputazione su questo sito per commentare.

[0,1]61

E[i=112Xi]=i=112E[Xi]=12×12=6
var[i=112Xi]=i=112var[Xi]=12×112=1.
i=112Xi610/12i=112Xi6[6,6]6

5

Oltre alla risposta di NRH, se non hai ancora mezzi per generare campioni casuali da una "distribuzione normale standard" N (0,1), di seguito è un modo buono e semplice (dal momento che dici che non hai una statistica pacchetto, le seguenti funzioni dovrebbero essere disponibili nella maggior parte dei linguaggi di programmazione standard).

1. Generare u e v come due numeri casuali distribuiti uniformemente nell'intervallo da -1 a 1 di
u = 2 r1 - 1ev = 2 r2 - 1

2.calcola w = u^2 + v^2se w> 1 torna a 1

3. restituire u * z e y = v * z con z= sqrt(-2ln(w)/w) un codice di esempio sarebbe simile al seguente:

u = 2 * random() - 1;
v = 2 * random() - 1;
w = pow(u, 2) + pow(v, 2);
if (w < 1) {
    z = sqrt((-2 * log(w)) / w);
    x = u * z;
    y = v * z;
    }

quindi utilizzare ciò che MHR ha suggerito sopra per ottenere i deviati casuali da N(mu, sigma^2).


Quando ho pubblicato la mia risposta sopra non ho notato che @vitalStatistix ti ha dato l'algoritmo Box-Muller Transform. Anche quello che do sopra è altrettanto buono suppongo.
francogrex,

2
Potresti spiegare il motivo della generazione di variate normali dalla distribuzione uniforme (diversa da una prospettiva algoritmica) e non solo dall'utilizzare direttamente il pdf di una distribuzione gaussiana / normale? O è totalmente sbagliato?
Arun,

4
@Arun Un motivo: il metodo polare di Marsaglia è utile quando hai solo un RNG che genera deviazioni uniformi.
chl

1
@Arun è il modo più semplice. Puoi anche generare direttamente dal pdf usando ad esempio il metodo "rifiuto di accettazione". Ho pubblicato per te un semplice esempio sul mio sito (perché non c'è abbastanza spazio nella casella dei commenti qui).
francogrex,

4

La distribuzione normale emerge quando si sommano molti valori casuali di distribuzione simile (simili tra loro, intendo). Se si sommano dieci o più valori casuali distribuiti uniformemente, la somma viene distribuita quasi normalmente. (Aggiungi più di dieci se vuoi che sia ancora più normale, ma dieci sono sufficienti per quasi tutti gli scopi.)

Supponi che i tuoi valori casuali uniformi siano distribuiti uniformemente tra 0 e 1. La somma sarà quindi compresa tra 0 e 10. Sottrai 5 dalla somma e la media della distribuzione risultante sarà 0. Ora dividi il risultato per la deviazione standard di la distribuzione (quasi) normale e moltiplicare il risultato per la deviazione standard desiderata. Sfortunatamente non sono sicuro di quale sia la deviazione standard della somma di dieci deviati casuali uniformi, ma se siamo fortunati qualcuno ci dirà in un commento!

Preferisco parlare con gli studenti della distribuzione normale in questi termini perché l'utilità dell'assunzione di una distribuzione normale in molti sistemi deriva interamente dalla proprietà che le somme di molte influenze casuali portano a una distribuzione normale.


Qui stai usando il limite centrale Thm (che un gruppo di variabili casuali iid si somma a una normale variabile casuale). Non l'ho considerato perché pensavo che sarebbe stato troppo lento, ma dici che 10 è sufficiente ?! Questo è meglio che calcolare un log e un sin / cos e un sqrt!
Fixee,

Inoltre, la media dell'uniforme rv su [0,1] è 0,5 con varianza 1/12. Se sommi 10 di questi ottieni una media di 5 e una varianza di 10/12 = 5/6.
Fixee

1
Da un punto di vista pedagogico questo metodo fornisce una discussione e una dimostrazione utili e utili. Tuttavia, scoraggerei fortemente chiunque dall'utilizzare questo approccio in pratica.
cardinale il

1
@Fixee: devi essere sicuro ed equilibrare il calcolo di log, peccato, cose la radice quadrata contro la generazione di ulteriori variate casuali uniformi. Ad esempio, le CPU Intel hanno tutte e quattro queste funzioni come operazioni integrate eseguite nell'hardware. La radice quadrata è un'operazione "aritmetica" fondamentale secondo gli standard IEEE 754.
cardinale il

1
@Michael: Dichiarare che fornisce la "giusta" distribuzione è un po 'allungato, soprattutto perché la distribuzione approssimativa ha un supporto compatto e, in molte applicazioni, ci si preoccupa dell'efficienza con cui i variati possono essere generati. :) Il punto è che ci sono molte opzioni molto migliori disponibili. Ma penso ancora che fornisca qualcosa di utile pedagogicamente.
cardinale il
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.