Simula una variabile di Bernoulli con probabilità usando una moneta distorta


9

Qualcuno può dirmi come simulare Bernoulli(ab) , dove a,bN , usando un gettone (tutte le volte che vuoi) con P(H)=p ?

Stavo pensando di utilizzare il campionamento del rifiuto, ma non sono riuscito a inchiodarlo.


1
È una domanda originaria di un corso o di un libro di testo? In tal caso, aggiungi il [self-study]tag e leggi la sua wiki . Nota che non è necessario presentare una richiesta di aiuto alla fine della tua domanda: sappiamo che tutti coloro che pubblicano qui sperano in aiuto!
Silverfish

1
C'è un eccellente post di @Glen_b qui da qualche parte (anche se non ricordo dove) sul perché non esiste una "moneta distorta con probabilità p ", ma so che questo è solo un problema periferico alla tua domanda!
Silverfish

2
@dsaxton La domanda dice "quante ne hai bisogno"; sarà finito con probabilità 1, ma non limitato (potresti superare qualsiasi numero fisso di lanci) ma obiettare su quella base sarebbe come dire "lanciare una moneta giusta finché non ottieni una testa" non è praticabile come metodo per generare geometriche ( 12 numeri casuali.
Glen_b -Reinstate Monica

1
@AbracaDabra È un esercizio per una lezione? In caso contrario, come si presenta?
Glen_b

1
@Glen_b: non è un esercizio della mia classe. Mi è appena venuto in mente in questa catena di pensieri ...: secondo la probabilità classica, prendi una moneta giusta, mentre aumenti il ​​numero di lanci, il rapporto di converge a metà. Quindi deve essere vero anche per quelli di parte ... Significa che una moneta converge in un determinato numero, è necessario che sia quel numero. Ora ho pensato, e se volessimo produrre un numero, ma abbiamo una moneta con un altro numero (noto o sconosciuto)? P(H)P(H)#Heads#tailsP(H)P(H)
AbracaDabra,

Risposte:


8

Poiché ci sono innumerevoli soluzioni, ne troviamo una efficiente .

L'idea alla base di questa inizia con un modo standard per implementare una variabile di Bernoulli: confrontare una variabile casuale uniforme con il parametro . Quando , restituisce ; altrimenti, restituisce .a / b U < a / b 1 0Ua/bU<a/b10

Possiamo usare -coin come un generatore di numeri casuali uniformep . Per generare un numero uniformemente entro qualsiasi intervallo , lancia la moneta. Quando è head, genera in modo ricorsivo un valore uniforme nella prima parte dell'intervallo; quando sono code, genera ricorsivamente dall'ultima parte dell'intervallo. Ad un certo punto l'intervallo target diventerà così piccolo che non importa davvero come scegli un numero da esso: è così che inizia la ricorsione. È ovvio che questa procedura genera variate uniformi (fino a qualsiasi precisione desiderata), come è facilmente dimostrato dall'induzione.UX p X 1 - p[x,y)XpX1p

Questa idea non è efficiente, ma porta a un metodo efficiente. Dato che in ogni fase traccerai un numero da un determinato intervallo , perché non controllare prima se è necessario disegnarlo? Se il tuo valore target non rientra in questo intervallo, conosci già il risultato del confronto tra il valore casuale e il target. Pertanto, questo algoritmo tende a terminare rapidamente. (Ciò potrebbe essere interpretato come la procedura di campionamento del rifiuto richiesta nella domanda.)[x,y)

Possiamo ottimizzare ulteriormente questo algoritmo. In ogni fase, in realtà abbiamo due monete che possiamo usare: rietichettando la nostra moneta possiamo farne una che è testa con possibilità . Pertanto, come precomputazione, possiamo ricorsivamente scegliere quale rietichettatura porta al numero inferiore previsto di lanci necessari per la risoluzione. (Questo calcolo può essere un passaggio costoso.)1p

Ad esempio, è inefficiente utilizzare una moneta con per emulare direttamente una variabile di Bernoulli : in media occorrono quasi dieci lanci. Ma se usiamo una moneta , allora in soli due lanci saremo sicuramente fatti e il numero atteso di lanci è solo .( 0,01 ) p = 1 - 0,0 = 0,1 1,2p=0.9(0.01)p=10.0=0.11.2

Ecco i dettagli

Partizionare qualsiasi intervallo semiaperto dato negli intervalliI=[x,y)

[x,y)=[x,x+(yx)p)[x+(yx)p,y)=s(I,H)s(I,T).

Questo definisce le due trasformazioni e che operano a intervalli semiaperti.s ( , T )s(,H)s(,T)

Per motivi di terminologia, se un insieme di numeri reali, lascia che l'espressioneI

t<I

significa che è un limite inferiore per : per tutti . Analogamente, significa è un limite superiore per .tIt<xxIt>ItI

Scrivi . (In effetti, non farà alcuna differenza se è reale anziché razionale; richiediamo solo )a/b=tt0t1

Ecco l'algoritmo per produrre una variabile con il parametro Bernoulli desiderato:Z

  1. Impostare e .n=0In=I0=[0,1)

  2. While {Lancia la moneta per produrre . Impostare Incremento .}(tIn)Xn+1In+1=S(In,Xn+1).n

  3. Se imposta . Altrimenti, impostare . Z = 1 Z = 0t>In+1Z=1Z=0


Implementazione

Per illustrare, ecco Run'implementazione dell'aloritmo come funzione draw. I suoi argomenti sono il valore target e l'intervallo , inizialmente . Utilizza la funzione ausiliaria implementando . Sebbene non sia necessario, traccia anche il numero di lanci di monete. Restituisce la variabile casuale, il conteggio dei lanci e l'ultimo intervallo ispezionato.[ x , y ) [ 0 , 1 ) st[x,y)[0,1)ss

s <- function(x, ab, p) {
  d <- diff(ab) * p
  if (x == 1) c(ab[1], ab[1] + d) else c(ab[1] + d, ab[2])
}
draw <- function(target, p) {
  between <- function(z, ab) prod(z - ab) <= 0
  ab <- c(0,1)
  n <- 0
  while(between(target, ab)) {
    n <- n+1; ab <- s(runif(1) < p, ab, p)
  }
  return(c(target > ab[2], n, ab))
}

Come esempio del suo uso e prova della sua precisione, prendi il caso e . Tracciamo valori usando l'algoritmo, riportiamo sulla media (e il suo errore standard) e indichiamo il numero medio di flip usati.p = 0,9 10 , 000t=1/100p=0.910,000

target <- 0.01
p <- 0.9
set.seed(17)
sim <- replicate(1e4, draw(target, p))

(m <- mean(sim[1, ]))                           # The mean
(m - target) / (sd(sim[1, ]) / sqrt(ncol(sim))) # A Z-score to compare to `target`
mean(sim[2, ])                                  # Average number of flips

In questa simulazione dei erano teste. Sebbene inferiore all'obiettivo di , il punteggio Z di non è significativo: questa deviazione può essere attribuita al caso. Il numero medio di salti mortali era poco --a meno di dieci. Se avessimo usato la moneta da , la media sarebbe stata di - non ancora significativamente diversa dall'obiettivo, ma in media sarebbero stati necessari solo lanci .0,01 - 0,5154 9,886 1 - p 0,0094 1.1770.00950.010.51549.8861p0.00941.177


Non posso fare a meno di vedere le somiglianze tra questa soluzione e la Soluzione 2 nella mia risposta. Considerando che presumo una moneta imparziale (PS soluzione davvero interessante al problema delle monete distorte), e faccio tutti i calcoli / confronti in base-2, fai tutti i calcoli / confronti in base 10. Quali sono i tuoi pensieri?
Cam.Davidson.Pilon

1
@cam Penso che potresti essere ingannato dai miei esempi: sebbene usino dei bei numeri nella base 10, la costruzione non ha nulla a che fare con una base particolare.
whuber

2
(+1) Risoluzione molto chiara. L'ottimizzazione si trova nel limite superiore e inferiore di poteri come e / o . Sarebbe bello trovare la dicotomia ottimale in termini di numero di Bernoullis simulati. p n ( 1 - p ) m ( n + ma/bpn(1p)m(n+mm)pn(1p)m
Xi'an,

5

Ecco una soluzione (un po 'disordinata, ma è la mia prima pugnalata). Puoi effettivamente ignorare e WLOG assume . Perché? Esiste un algoritmo intelligente per generare un lancio di moneta imparziale da due lanci di monete distorti. Quindi possiamo assumere .P(H)=pP(H)=1/2P(H)=1/2

Per generare un , posso pensare a due soluzioni (la prima non è la mia, ma la seconda è una generalizzazione):Bernoulli(ab)

Soluzione 1

Lancia la moneta imparziale volte. Se testa non è presente, ricominciare. Se teste sono presenti, di ritorno se la prima moneta è un testa a testa o no (a causa )baaP(first coin is heads | a heads in b coins)=ab

Soluzione 2

Questo può essere esteso a qualsiasi valore di . Scrivi in forma binaria. Ad esempio,Bernoulli(p)p0.1=0.0001100110011001100110011...base 2

Creeremo un nuovo numero binario usando i lanci di monete. Inizia con e aggiungi le cifre a seconda che appaia una testa (1) o una coda (0). Ad ogni lancio, confronta il tuo nuovo numero binario con la rappresentazione binaria di fino alla stessa cifra . Alla fine i due divergeranno e ritorneranno se è maggiore del tuo numero binario.0.p bin(p)

In Python:

def simulate(p):
    binary_p = float_to_binary(p)
    binary_string = '0.'
    index = 3
    while True:
        binary_string += '0' if random.random() < 0.5 else '1'
        if binary_string != binary_p[:index]:
            return binary_string < binary_p[:index]
        index += 1

Qualche prova:

np.mean([simulate(0.4) for i in range(10000)])

è circa 0.4 (non veloce comunque)


Bella risposta, ma puoi spiegare con il tuo metodo 1 come fare per irrazionale p?
AbracaDabra,

2
@AbracaDabra perché dovrebbe importare la razionalità di ? p
Glen_b -Restate Monica

@AbracaDabra: qualunque sia il valore di , la probabilità di ottenere e è la stessa, vale a dire , quindi la probabilità di ottenere uno contro l'altro è . ( 0 , 1 ) ( 1 , 0 ) p ( 1 - p ) 1 / 2p(0,1)(1,0)p(1p)1/2
Xi'an,

4

Vedo una soluzione semplice, ma senza dubbio ci sono molti modi per farlo, alcuni presumibilmente più semplici di così. Questo approccio può essere suddiviso in due passaggi:

  1. Generando da due eventi con uguale probabilità data una procedura ingiusta di lancio della moneta (la combinazione della moneta particolare e il metodo con cui viene lanciata generando una testa con probabilità ). Possiamo chiamare questi due eventi ugualmente probabili e . [Esiste un approccio semplice per questo che richiede di eseguire coppie di lanci e per produrre due risultati ugualmente probabili, con tutti gli altri risultati che portano alla generazione di una nuova coppia di rotoli per riprovare.]H T H = ( H , T ) T = ( T , H )pHTH=(H,T)T=(T,H)

  2. Ora generi una camminata casuale con due stati assorbenti usando la moneta simulata corretta. Scegliendo la distanza degli stati assorbenti dall'origine (uno sopra e uno sotto di esso), è possibile impostare la possibilità di assorbimento dicendo che lo stato assorbente superiore è un rapporto desiderato di numeri interi. In particolare, se si posiziona la barriera di assorbimento superiore su e quella inferiore su (e si avvia il processo dall'origine) e si esegue la camminata casuale fino all'assorbimento, la probabilità di assorbimento sulla barriera superiore è .- ( b - a ) aa(ba)aa+(ba)=ab

    (Ci sono alcuni calcoli da fare qui per dimostrarlo, ma puoi ottenere le probabilità abbastanza facilmente lavorando con le relazioni di ricorrenza ... oppure puoi farlo sommando serie infinite ... o ci sono altri modi.)

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.