Mô hình hỗn hợp 2-Gaussian suy luận với MCMC và PyMC


10

Vấn đề

Tôi muốn phù hợp với các tham số mô hình của quần thể hỗn hợp 2 Gauss đơn giản. Với tất cả sự cường điệu xung quanh các phương pháp Bayes tôi muốn hiểu nếu đối với vấn đề này, suy luận Bayes là một công cụ tốt hơn các phương pháp phù hợp truyền thống.

Cho đến nay MCMC hoạt động rất kém trong ví dụ đồ chơi này, nhưng có lẽ tôi chỉ bỏ qua một cái gì đó. Vì vậy, hãy xem mã.

Công cụ

Tôi sẽ sử dụng python (2.7) + stack scipy, lmfit 0.8 và PyMC 2.3.

Một cuốn sổ để tái tạo phân tích có thể được tìm thấy ở đây

Tạo dữ liệu

Đầu tiên hãy tạo dữ liệu:

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])

Biểu đồ của sampleshình như thế này:

biểu đồ dữ liệu

một "đỉnh rộng", các thành phần khó có thể nhận ra bằng mắt.

Phương pháp cổ điển: phù hợp với biểu đồ

Trước tiên hãy thử cách tiếp cận cổ điển. Sử dụng lmfit thật dễ dàng để xác định mô hình 2 đỉnh:

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'

Cuối cùng, chúng ta phù hợp với mô hình với thuật toán đơn giản:

fit_res = model.fit(data, x=x_data, method='nelder')
print fit_res.fit_report()

Kết quả là hình ảnh sau đây (đường đứt nét màu đỏ là trung tâm được trang bị):

Kết quả phù hợp với NLS

Ngay cả khi vấn đề là khó khăn, với các giá trị và ràng buộc ban đầu thích hợp, các mô hình đã hội tụ đến một ước tính khá hợp lý.

Cách tiếp cận Bayes: MCMC

Tôi định nghĩa mô hình trong PyMC theo kiểu phân cấp. centerssigmaslà phân phối linh mục cho các siêu đường kính đại diện cho 2 trung tâm và 2 sigmas của 2 Gaussian. alphalà một phần của dân số đầu tiên và phân phối trước ở đây là Beta.

Một biến phân loại chọn giữa hai quần thể. Theo hiểu biết của tôi, biến này cần có cùng kích thước với dữ liệu ( samples).

Cuối cùng mutaulà các biến xác định xác định các tham số của phân phối Bình thường (chúng phụ thuộc vào categorybiến để chúng chuyển đổi ngẫu nhiên giữa hai giá trị cho hai quần thể).

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])

Sau đó, tôi chạy MCMC với số lần lặp khá dài (1e5, ~ 60 trên máy của tôi):

mcmc = pm.MCMC(model)
mcmc.sample(100000, 30000)

Tuy nhiên kết quả rất kỳ quặc. Ví dụ: dấu vết (phần của dân số đầu tiên) có xu hướng về 0 thay vào đó hội tụ đến 0,4 và có hiện tượng tự tương quan rất mạnh:α

Tóm tắt MCMC alpha

Ngoài ra các trung tâm của Gaussian cũng không hội tụ. Ví dụ:

Tóm tắt trung tâm MCMC_0

Như bạn thấy trong lựa chọn trước, tôi đã cố gắng "trợ giúp" thuật toán MCMC bằng cách sử dụng phân phối Beta cho phần dân số trước . Ngoài ra các phân phối trước cho các trung tâm và sigmas là khá hợp lý (tôi nghĩ).α

Vậy chuyện gì đang xảy ra ở đây? Tôi đang làm gì đó sai hay MCMC không phù hợp với vấn đề này?

Tôi hiểu rằng phương pháp MCMC sẽ chậm hơn, nhưng sự phù hợp với biểu đồ tầm thường dường như thực hiện tốt hơn rất nhiều trong việc giải quyết các quần thể.

Câu trả lời:


6

Vấn đề được gây ra bởi cách PyMC vẽ mẫu cho mô hình này. Như đã giải thích trong phần 5.8.1 của tài liệu PyMC, tất cả các yếu tố của một biến mảng được cập nhật cùng nhau. Đối với các mảng nhỏ như thế centernày không phải là một vấn đề, nhưng đối với một mảng lớn như categorynó dẫn đến tỷ lệ chấp nhận thấp. Bạn có thể thấy tỷ lệ chấp nhận thông qua

print mcmc.step_method_dict[category][0].ratio

Giải pháp được đề xuất trong tài liệu này là sử dụng một loạt các biến có giá trị vô hướng. Ngoài ra, bạn cần định cấu hình một số bản phân phối đề xuất vì các lựa chọn mặc định là xấu. Đây là mã làm việc cho tôi:

import pymc as pm
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)
alpha  = pm.Beta('alpha', alpha=2, beta=3)
category = pm.Container([pm.Categorical("category%i" % i, [alpha, 1 - alpha]) 
                         for i in range(nsamples)])
observations = pm.Container([pm.Normal('samples_model%i' % i, 
                   mu=centers[category[i]], tau=1/(sigmas[category[i]]**2), 
                   value=samples[i], observed=True) for i in range(nsamples)])
model = pm.Model([observations, category, alpha, sigmas, centers])
mcmc = pm.MCMC(model)
# initialize in a good place to reduce the number of steps required
centers.value = [mu1_true, mu2_true]
# set a custom proposal for centers, since the default is bad
mcmc.use_step_method(pm.Metropolis, centers, proposal_sd=sig1_true/np.sqrt(nsamples))
# set a custom proposal for category, since the default is bad
for i in range(nsamples):
    mcmc.use_step_method(pm.DiscreteMetropolis, category[i], proposal_distribution='Prior')
mcmc.sample(100)  # beware sampling takes much longer now
# check the acceptance rates
print mcmc.step_method_dict[category[0]][0].ratio
print mcmc.step_method_dict[centers][0].ratio
print mcmc.step_method_dict[alpha][0].ratio

Các tùy chọn proposal_sdproposal_distributionđược giải thích trong phần 5.7.1 . Đối với các trung tâm, tôi đặt đề xuất gần như khớp với độ lệch chuẩn của hậu thế, nhỏ hơn nhiều so với mặc định do lượng dữ liệu. PyMC không cố gắng điều chỉnh độ rộng của đề xuất, nhưng điều này chỉ hoạt động nếu tỷ lệ chấp nhận của bạn đủ cao để bắt đầu. Đối với category, mặc định proposal_distribution = 'Poisson'cho kết quả kém (tôi không biết tại sao lại như vậy, nhưng chắc chắn nó không giống như một đề xuất hợp lý cho biến nhị phân).


Cảm ơn, điều này thực sự hữu ích, mặc dù nó trở nên chậm gần như không thể chịu đựng được. Bạn có thể giải thích ngắn gọn về ý nghĩa của proposal_distributionproposal_sdvà tại sao sử dụng Priorlà tốt hơn cho các biến phân loại?
dùng2304916

Cảm ơn, Tom. Tôi đồng ý rằng Poisson là một lựa chọn kỳ lạ ở đây. Tôi đã mở ra một vấn đề: github.com/pymc-devs/pymc/issues/627
twiecki

2

Bạn không nên mô hình hóa với Bình thường, theo cách đó bạn đang cho phép các giá trị âm cho biến thể tiêu chuẩn. Sử dụng thay vì một cái gì đó như:σ

sigmas = pm.Exponential('sigmas', 0.1, size=2)

cập nhật:

Tôi đã đến gần các tham số ban đầu của dữ liệu bằng cách thay đổi các phần này trong mô hình của bạn:

sigmas = pm.Exponential('sigmas', 0.1, size=2)
alpha  = pm.Beta('alpha', alpha=1, beta=1)

và bằng cách gọi mcmc với một số pha loãng:

mcmc.sample(200000, 3000, 10)

các kết quả:

alpha

trung tâm

sigmas

Các hậu thế không đẹp lắm ... Trong phần 11.6 của BUGS Book, họ thảo luận về loại mô hình này và nói rằng có những vấn đề hội tụ không có giải pháp rõ ràng. Kiểm tra cũng ở đây .


Đó là một điểm tốt, tôi đang sử dụng Gamma. Tuy nhiên, dấu vết alpha luôn có xu hướng về 0 (thay vì 0,4). Tôi tự hỏi nếu có một số lỗi ngu ngốc ẩn trong ví dụ của tôi.
user2304916

Tôi đã thử Gamma (.1, .1) nhưng Exp (.1) dường như hoạt động tốt hơn. Ngoài ra, khi mức độ tự động cao, bạn có thể bao gồm một số pha loãng, ví dụ:mcmc.sample(60000, 3000, 3)
jpneto

2

Ngoài ra, không thể nhận dạng là một vấn đề lớn đối với việc sử dụng MCMC cho các mô hình hỗn hợp. Về cơ bản, nếu bạn chuyển nhãn trên phương tiện cụm và phân công cụm, khả năng không thay đổi và điều này có thể gây nhầm lẫn cho bộ lấy mẫu (giữa các chuỗi hoặc trong chuỗi). Một điều bạn có thể cố gắng giảm thiểu điều này là sử dụng Tiềm năng trong PyMC3. Một triển khai tốt về GMM với Tiềm năng là ở đây . Hậu thế cho các loại vấn đề này nói chung cũng rất đa phương thức, cũng là một vấn đề lớn. Thay vào đó, bạn có thể muốn sử dụng EM (hoặc suy luận biến thể).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.