Modello di raccordo per due distribuzioni normali in PyMC


10

Dato che sono un ingegnere del software che cerca di imparare più statistiche, dovrai perdonarmi prima ancora di iniziare, questo è un territorio davvero nuovo ...

Ho imparato PyMC e ho lavorato su alcuni esempi davvero (davvero) semplici. Un problema per cui non riesco a lavorare (e non riesco a trovare alcun esempio correlato) è quello di adattare un modello ai dati generati da due distribuzioni normali.

Supponiamo di avere 1000 valori; 500 generati da a Normal(mean=100, stddev=20)e altri 500 generati da a Normal(mean=200, stddev=20).

Se voglio adattare un modello a loro, cioè determinare i due mezzi e la singola deviazione standard, usando PyMC. So che è qualcosa sulla falsariga di ...

mean1 = Uniform('mean1', lower=0.0, upper=200.0)
mean2 = Uniform('mean2', lower=0.0, upper=200.0)
precision = Gamma('precision', alpha=0.1, beta=0.1)

data = read_data_from_file_or_whatever()

@deterministic(plot=False)
def mean(m1=mean1, m2=mean2):
    # but what goes here?

process = Normal('process', mu=mean, tau=precision, value=data, observed=True)

cioè, il processo di generazione è normale, ma mu è uno dei due valori. Semplicemente non so come rappresentare la "decisione" tra se un valore viene m1o m2.

Forse sto solo prendendo completamente l'approccio sbagliato per modellare questo? Qualcuno può indicarmi un esempio? Riesco a leggere BUG e JAGS, quindi tutto è ok davvero.

Risposte:


11

Sei assolutamente sicuro che metà provenga da una distribuzione e l'altra metà dall'altra? Altrimenti, possiamo modellare la proporzione come una variabile casuale (che è una cosa molto bayesiana da fare).

Di seguito è quello che vorrei fare, alcuni suggerimenti sono incorporati.

from pymc import *

size = 10
p = Uniform( "p", 0 , 1) #this is the fraction that come from mean1 vs mean2

ber = Bernoulli( "ber", p = p, size = size) # produces 1 with proportion p.

precision = Gamma('precision', alpha=0.1, beta=0.1)

mean1 = Normal( "mean1", 0, 0.001 ) #better to use normals versus Uniforms (unless you are certain the value is  truncated at 0 and 200 
mean2 = Normal( "mean2", 0, 0.001 )

@deterministic
def mean( ber = ber, mean1 = mean1, mean2 = mean2):
    return ber*mean1 + (1-ber)*mean2


#generate some artificial data   
v = np.random.randint( 0, 2, size)
data = v*(10+ np.random.randn(size) ) + (1-v)*(-10 + np.random.randn(size ) )


obs = Normal( "obs", mean, precision, value = data, observed = True)

model = Model( {"p":p, "precision": precision, "mean1": mean1, "mean2":mean2, "obs":obs} )

2
Promozione senza vergogna: ho appena scritto un articolo di blog su Bayes e pyMC letteralmente 1 minuto prima di pubblicarlo, quindi vi invito a dare un'occhiata. The Awesome Power of Bayes - Part 1
Cam.Davidson.Pilon

eccezionale! questo approccio alla miscelazione dei due mezzi è esattamente quello che stavo cercando di farmi girare la testa.
mat kelcey,

Non sono sicuro di aver compreso appieno il vero vantaggio della modellazione nel dire che mean1 e mean2 sono normalmente distribuiti anziché uniformi (lo stesso vale per la precisione, ad essere onesto, sto usando Gamma da "qualcun altro"). Ho molto da imparare :)
mat kelcey,

L'uso di un uniforme, come nell'esempio originale, implica che tu sappia con assoluta certezza che la media non supera un certo valore. Questo è in qualche modo patologico. È meglio usare un normale, in quanto consente di considerare tutti i numeri reali.
Cam.Davidson.Pilon

1
La scelta della gamma ha una ragione matematica. La gamma è il priore coniugato della precisione, vedi tabella qui
Cam.Davidson.Pilon

6

Un paio di punti, legati alla discussione sopra:

  1. La scelta della normale diffusa rispetto all'uniforme è piuttosto accademica a meno che (a) non ti preoccupi della coniugazione, nel qual caso utilizzeresti la normale o (b) c'è qualche ragionevole possibilità che il vero valore possa essere al di fuori degli endpoint dell'uniforme . Con PyMC, non c'è motivo di preoccuparsi della coniugazione, a meno che non si desideri utilizzare un campionatore Gibbs.

  2. Una gamma non è in realtà un'ottima scelta per un non informativo prima di un parametro varianza / precisione. Può finire per essere più informativo che pensi. Una scelta migliore è quella di mettere un'uniforme prima della deviazione standard, quindi trasformarla in un quadrato inverso. Vedi Gelman 2006 per i dettagli.


1
ah fonnesbeck è uno dei principali sviluppatori di pymc! Puoi mostrarci un esempio di come codificare il punto 2?
Cam.Davidson.Pilon

grazie fonnesbeck e, sì per favore! ad un breve esempio del punto 2 :)
mat kelcey,

1
in effetti sto indovinando che intendi qualcosa sulla falsariga di ... gist.github.com/4404631 ?
mat kelcey,

Si, esattamente. Puoi fare la trasformazione un po 'più concisamente:tau = std_dev**-2
fonnesbeck

quale sarebbe il posto giusto per leggere da dove proviene questa relazione tra precisione e std_dev?
user979
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.