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 samples
hình như thế này:
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ị):
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. centers
và sigmas
là 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. alpha
là 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 mu
và tau
là 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 category
biế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:
Ngoài ra các trung tâm của Gaussian cũng không hội tụ. Ví dụ:
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ể.
proposal_distribution
vàproposal_sd
và tại sao sử dụngPrior
là tốt hơn cho các biến phân loại?