Masalah
Saya ingin menyesuaikan parameter model populasi campuran 2-Gaussian sederhana. Mengingat semua hype di sekitar metode Bayesian saya ingin mengerti jika untuk masalah ini kesimpulan Bayesian adalah alat yang lebih baik daripada metode pemasangan tradisional.
Sejauh ini MCMC berkinerja sangat buruk dalam contoh mainan ini, tapi mungkin saya hanya mengabaikan sesuatu. Jadi mari kita lihat kodenya.
Alat-alatnya
Saya akan menggunakan python (2.7) + tumpukan scipy, lmfit 0.8 dan PyMC 2.3.
Buku catatan untuk mereproduksi analisis dapat ditemukan di sini
Hasilkan data
Pertama mari kita hasilkan data:
from scipy.stats import distributions
# Sample parameters
nsamples = 1000
mu1_true = 0.3
mu2_true = 0.55
sig1_true = 0.08
sig2_true = 0.12
a_true = 0.4
# Samples generation
np.random.seed(3) # for repeatability
s1 = distributions.norm.rvs(mu1_true, sig1_true, size=round(a_true*nsamples))
s2 = distributions.norm.rvs(mu2_true, sig2_true, size=round((1-a_true)*nsamples))
samples = np.hstack([s1, s2])
Histogram samples
terlihat seperti ini:
"puncak luas", komponen-komponennya sulit dikenali oleh mata.
Pendekatan klasik: sesuai dengan histogram
Mari kita coba pendekatan klasiknya terlebih dahulu. Menggunakan lmfit mudah untuk mendefinisikan model 2-puncak:
import lmfit
peak1 = lmfit.models.GaussianModel(prefix='p1_')
peak2 = lmfit.models.GaussianModel(prefix='p2_')
model = peak1 + peak2
model.set_param_hint('p1_center', value=0.2, min=-1, max=2)
model.set_param_hint('p2_center', value=0.5, min=-1, max=2)
model.set_param_hint('p1_sigma', value=0.1, min=0.01, max=0.3)
model.set_param_hint('p2_sigma', value=0.1, min=0.01, max=0.3)
model.set_param_hint('p1_amplitude', value=1, min=0.0, max=1)
model.set_param_hint('p2_amplitude', expr='1 - p1_amplitude')
name = '2-gaussians'
Akhirnya kami menyesuaikan model dengan algoritma simpleks:
fit_res = model.fit(data, x=x_data, method='nelder')
print fit_res.fit_report()
Hasilnya adalah gambar berikut (garis putus-putus merah dilengkapi dengan pusat):
Sekalipun masalahnya agak sulit, dengan nilai awal dan kendala yang tepat, model-model tersebut bertemu dengan estimasi yang cukup masuk akal.
Pendekatan Bayesian: MCMC
Saya mendefinisikan model dalam PyMC secara hierarkis. centers
dan sigmas
adalah distribusi prior untuk hyperparameter yang mewakili 2 pusat dan 2 sigma dari 2 Gaussians. alpha
adalah fraksi dari populasi pertama dan distribusi sebelumnya di sini adalah Beta.
Variabel kategorikal memilih antara dua populasi. Ini adalah pemahaman saya bahwa variabel ini harus berukuran sama dengan data ( samples
).
Akhirnya mu
dan tau
merupakan variabel deterministik yang menentukan parameter dari distribusi Normal (mereka bergantung pada category
variabel sehingga mereka secara acak beralih antara dua nilai untuk dua populasi).
sigmas = pm.Normal('sigmas', mu=0.1, tau=1000, size=2)
centers = pm.Normal('centers', [0.3, 0.7], [1/(0.1)**2, 1/(0.1)**2], size=2)
#centers = pm.Uniform('centers', 0, 1, size=2)
alpha = pm.Beta('alpha', alpha=2, beta=3)
category = pm.Categorical("category", [alpha, 1 - alpha], size=nsamples)
@pm.deterministic
def mu(category=category, centers=centers):
return centers[category]
@pm.deterministic
def tau(category=category, sigmas=sigmas):
return 1/(sigmas[category]**2)
observations = pm.Normal('samples_model', mu=mu, tau=tau, value=samples, observed=True)
model = pm.Model([observations, mu, tau, category, alpha, sigmas, centers])
Kemudian saya menjalankan MCMC dengan jumlah iterasi yang cukup lama (1e5, ~ 60s pada mesin saya):
mcmc = pm.MCMC(model)
mcmc.sample(100000, 30000)
Namun hasilnya sangat aneh. Misalnya trace (fraksi populasi pertama) cenderung 0 untuk konvergen ke 0,4 dan memiliki autokorelasi yang sangat kuat:
Juga pusat-pusat Gaussians tidak bertemu juga. Sebagai contoh:
Seperti yang Anda lihat dalam pilihan sebelumnya, saya mencoba "membantu" algoritma MCMC menggunakan distribusi Beta untuk fraksi populasi sebelumnya . Juga distribusi sebelumnya untuk pusat dan sigma cukup masuk akal (saya pikir).
Jadi apa yang terjadi di sini? Apakah saya melakukan sesuatu yang salah atau MCMC tidak cocok untuk masalah ini?
Saya mengerti bahwa metode MCMC akan lebih lambat, tetapi kecocokan histogram sepele tampaknya berkinerja jauh lebih baik dalam menyelesaikan populasi.
proposal_distribution
danproposal_sd
dan mengapa menggunakanPrior
lebih baik untuk variabel kategori?