Tôi nghi ngờ đây là một câu hỏi khá bất thường và thăm dò, vì vậy xin vui lòng chịu đựng với tôi.
Tôi tự hỏi nếu người ta có thể áp dụng ý tưởng lấy mẫu quan trọng để lấy mẫu Gibbs. Ý tôi là: trong lấy mẫu Gibbs, chúng tôi thay đổi giá trị của một biến (hoặc khối biến) tại một thời điểm, lấy mẫu từ xác suất có điều kiện cho các biến còn lại.
Tuy nhiên, có thể không thể hoặc dễ dàng lấy mẫu từ xác suất có điều kiện chính xác. Vì vậy, thay vào đó, chúng tôi lấy mẫu từ một phân phối đề xuất và sử dụng, ví dụ, Metropolis-Hastings (MH).
Càng xa càng tốt. Nhưng đây là một con đường khác nhau: điều gì xảy ra nếu chúng ta, thay vì sử dụng MH, sử dụng cùng một ý tưởng được sử dụng trong lấy mẫu quan trọng, cụ thể là chúng ta lấy mẫu từ và giữ trọng số p / q của mẫu hiện tại?
Chi tiết hơn: giả sử chúng ta có các biến và phân phối bao thanh toán sao cho . Chúng tôi giữ xác suất đề xuất được sử dụng để lấy mẫu giá trị hiện tại của từng biến . Ở mỗi bước, chúng tôi thay đổi một tập hợp con của các biến và cập nhật (chỉ các yếu tố của và bị ảnh hưởng). Chúng tôi lấy các mẫu và trọng lượng quan trọng của chúng để tính toán bất kỳ số liệu thống kê nào chúng tôi quan tâm.
Thuật toán này có đúng không? Nếu không, lý do rõ ràng tại sao không? Theo trực giác, nó có ý nghĩa với tôi vì nó dường như đang thực hiện cùng một việc lấy mẫu quan trọng, nhưng với các mẫu phụ thuộc thay thế.
Tôi đã thực hiện điều này cho một mô hình đi bộ ngẫu nhiên Gaussian và quan sát thấy các trọng số ngày càng nhỏ hơn (nhưng không đơn điệu), vì vậy các mẫu ban đầu cuối cùng có quá nhiều tầm quan trọng và chi phối thống kê. Tôi khá chắc chắn rằng việc thực hiện không có lỗi, bởi vì ở mỗi bước tôi so sánh trọng lượng được cập nhật với một tính toán vũ lực rõ ràng của nó. Lưu ý rằng các trọng số không giảm xuống vô hạn, bởi vì chúng là trong đó cả và đều là sản phẩm có số lượng mật độ hữu hạn và mỗi mẫu được lấy từ phân phối chuẩn mà hiếm khi bằng 0.
Vì vậy, tôi đang cố gắng để hiểu tại sao các trọng số đi xuống như vậy, và liệu đây có phải là hậu quả của phương pháp này thực sự không chính xác.
Đây là một định nghĩa chính xác hơn về thuật toán, được áp dụng cho bước đi ngẫu nhiên Gaussian trên các biến . Các mã sau đây.
Mô hình chỉ đơn giản là , với sửa thành .
Trọng số của mẫu hiện tại là , trong đó là mật độ Gaussian và là các phân phối mà từ đó các giá trị hiện tại đã được lấy mẫu. Ban đầu, chúng tôi chỉ cần lấy mẫu các giá trị theo cách chuyển tiếp, vì vậy và trọng số ban đầu là .
Sau đó, ở mỗi bước tôi chọn để thay đổi. Tôi lấy mẫu một giá trị mới cho từ , vì vậy mật độ này trở thành phân phối đề xuất mới được sử dụng cho .
Để cập nhật trọng số, tôi chia nó cho mật độ và của giá trị cũ theo và và nhân với mật độ và của giá trị mới theo và . Điều này cập nhật tử số của trọng lượng. x j+ 1
Để cập nhật mẫu số , tôi nhân trọng số với đề xuất cũ (do đó loại bỏ nó khỏi mẫu số) và chia nó cho .
(Vì tôi lấy mẫu từ trung tâm bình thường trên , luôn bằng nên họ hủy bỏ và việc triển khai thực hiện không thực sự sử dụng chúng).
Giống như tôi đã đề cập trước đây, trong mã tôi so sánh tính toán trọng số gia tăng này với tính toán rõ ràng thực tế chỉ để đảm bảo.
Đây là mã để tham khảo.
println("Original sample: " + currentSample);
int flippedVariablesIndex = 1 + getRandom().nextInt(getVariables().size() - 1);
println("Flipping: " + flippedVariablesIndex);
double oldValue = getValue(currentSample, flippedVariablesIndex);
NormalDistribution normalFromBack = getNormalDistribution(getValue(currentSample, flippedVariablesIndex - 1));
double previousP = normalFromBack.density(oldValue);
double newValue = normalFromBack.sample();
currentSample.set(getVariable(flippedVariablesIndex), newValue);
double previousQ = fromVariableToQ.get(getVariable(flippedVariablesIndex));
fromVariableToQ.put(getVariable(flippedVariablesIndex), normalFromBack.density(newValue));
if (flippedVariablesIndex < length - 1) {
NormalDistribution normal = getNormalDistribution(getValue(currentSample, flippedVariablesIndex + 1));
double oldForwardPotential = normal.density(oldValue);
double newForwardPotential = normal.density(newValue);
// println("Removing old forward potential " + oldForwardPotential);
currentSample.removePotential(new DoublePotential(oldForwardPotential));
// println("Multiplying new forward potential " + newForwardPotential);
currentSample.updatePotential(new DoublePotential(newForwardPotential));
}
// println("Removing old backward potential " + previousP);
currentSample.removePotential(new DoublePotential(previousP));
// println("Multiplying (removing from divisor) old q " + previousQ);
currentSample.updatePotential(new DoublePotential(previousQ));
println("Final sample: " + currentSample);
println();
// check by comparison to brute force calculation of weight:
double productOfPs = 1.0;
for (int i = 1; i != length; i++) {
productOfPs *= getNormalDistribution(getValue(currentSample, i - 1)).density(getValue(currentSample, i));
}
double productOfQs = Util.fold(fromVariableToQ.values(), (p1, p2) -> p1*p2, 1.0);
double weight = productOfPs/productOfQs;
if (Math.abs(weight - currentSample.getPotential().doubleValue()) > 0.0000001) {
println("Error in weight calculation");
System.exit(0);
}