Придатна модель для двох нормальних розподілів в PyMC


10

Оскільки я інженер програмного забезпечення, який намагається дізнатися більше статистики, вам доведеться пробачити мене ще до того, як я навіть розпочну, це серйозна територія нового походження ...

Я вивчав PyMC і працюю через кілька справді (дійсно) простих прикладів. Одна з проблем, яку я не можу взяти на роботу (і не можу знайти жодних пов’язаних прикладів) - це пристосування моделі до даних, згенерованих за допомогою двох звичайних розподілів.

Скажіть, у мене 1000 значень; 500 згенеровано з a Normal(mean=100, stddev=20)і ще 500 згенеровано з a Normal(mean=200, stddev=20).

Якщо я хочу приєднати до них модель, тобто визначити два засоби та єдине стандартне відхилення, використовуючи PyMC. Я знаю, що це щось уздовж ...

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)

тобто процес генерації є нормальним, але mu - одне з двох значень. Я просто не знаю, як представити "рішення" між тим, величина походить від m1або m2.

Можливо, я просто повністю приймаю неправильний підхід до моделювання цього? Хтось може вказати мені на приклад? Я можу читати помилки та джеги, так що все дійсно добре.

Відповіді:


11

Ви абсолютно впевнені, що половина прийшла з одного розподілу, а друга половина з іншого? Якщо ні, ми можемо моделювати пропорцію як випадкову величину (що дуже важливо зробити).

Далі - що я б робив, деякі поради вбудовані.

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
Безсоромне просування: Я щойно писав статтю в блозі про Бейса та pyMC буквально за 1 хвилину до того, як ви опублікували це, тому я запрошую вас перевірити це. Дивовижна сила Байєса - частина 1
Cam.Davidson.Pilon

приголомшливий! такий підхід до змішування двох засобів - це саме те, що я намагався обійти головою.
мат келчі

Не впевнений, що я повністю розумію справжню перевагу моделювання: сказати mean1 & mean2, як правило, розподіляється замість Uniform (Те саме стосується точності, якщо бути чесним, я використовую Gamma з тих пір, як "це зробив хтось інший"). У мене є чому навчитися :)
mat kelcey

Використання Уніформи, як у вашому оригінальному прикладі, означає, що ви знаєте з абсолютною впевненістю, що середнє значення не перевищує деякого значення. Це дещо патологічно. Краще використовувати звичайне, оскільки воно дозволяє враховувати всі реальні числа.
Cam.Davidson.Pilon

1
Вибір гами має математичну причину. Гамма - це кон'югат перед точністю, див. Таблицю тут
Cam.Davidson.Pilon

6

Кілька пунктів, пов’язаних із обговоренням вище:

  1. Вибір дифузного нормального проти рівномірного є досить академічним, якщо (а) ви не турбуєтесь про спорідненість; у такому випадку ви б використали нормальне або (б) є певний розумний шанс, що справжнє значення може бути поза кінцевими точками уніформи . З PyMC немає ніяких причин турбуватися про кон'югацію, якщо ви спеціально не хочете використовувати пробовідбірник Гіббса.

  2. Гамма насправді не є чудовим вибором для неінформативності до параметра дисперсії / точності. Це може виявитися більш інформативним, як ви думаєте. Кращий вибір - поставити рівномірне попереднє на стандартне відхилення, а потім перетворити його на обернений квадрат. Докладніше див. У Gelman 2006 .


1
ах fonnesbeck - один з основних розробників pymc! Чи можете ви показати нам приклад того, як кодувати пункт 2?
Cam.Davidson.Pilon

дякую fonnesbeck і, так, будь ласка! до швидкого, наприклад, з точки 2 :)
матч kelcey

1
насправді я здогадуюсь, що ти щось маєш на увазі ... gist.github.com/4404631 ?
мат kelcey

Так, саме. Ви можете зробити перетворення трохи більш стисло:tau = std_dev**-2
fonnesbeck

про що було б правильно прочитати про те, звідки походить це співвідношення між точністю та std_dev?
user979
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.