2012-05-03 18 views
13

Tôi quan tâm đến thuật toán đơn giản cho bộ lọc hạt được đưa ra ở đây: http://www.aiqus.com/upfiles/PFAlgo.png Có vẻ như rất đơn giản nhưng tôi không có ý tưởng về cách thực hiện nó. Bất kỳ ý tưởng nào về cách thực hiện nó (chỉ để hiểu rõ hơn cách hoạt động)?Thực hiện phương pháp monte carlo tuần tự (bộ lọc hạt)

Edit: Đây là một ví dụ đơn giản tuyệt vời mà giải thích cách hoạt động: http://www.aiqus.com/questions/39942/very-simple-particle-filters-algorithm-sequential-monte-carlo-method-implementation?page=1#39950

Tôi đã cố gắng để thực hiện nó trong C++: http://pastebin.com/M1q1HcN4 nhưng tôi lưu ý chắc chắn nếu tôi làm điều đó một cách đúng đắn . Bạn có thể vui lòng kiểm tra xem tôi có hiểu rõ không, hoặc có một số hiểu lầm theo mã của tôi không?

#include <iostream> 
#include <vector> 
#include <boost/random/mersenne_twister.hpp> 
#include <boost/random/uniform_01.hpp> 
#include <boost/random/uniform_int_distribution.hpp> 

using namespace std; 
using namespace boost; 

double uniform_generator(void); 

#define N 4 // number of particles 

#define evolutionProba_A_A 1.0/3.0 // P(X_t = A | X_t-1 = A) 
#define evolutionProba_A_B 1.0/3.0 // P(X_t = A | X_t-1 = B) 
#define evolutionProba_B_B 2.0/3.0 // P(X_t = B | X_t-1 = B) 
#define evolutionProba_B_A 2.0/3.0 // P(X_t = B | X_t-1 = A) 

#define observationProba_A_A 4.0/5.0 // P(Y_t = A | X_t = A) 
#define observationProba_A_B 1.0/5.0 // P(Y_t = A | X_t = B) 
#define observationProba_B_B 4.0/5.0 // P(Y_t = B | X_t = B) 
#define observationProba_B_A 1.0/5.0 // P(Y_t = A | X_t = A) 

/// =========================================================================== 

typedef struct distrib { float PA; float PB; } Distribution; 

typedef struct particle 
{ 
    Distribution distribution; // e.g. <0.5, 0.5> 
    char state; // e.g. 'A' or 'B' 
    float weight; // e.g. 0.8 
} 
Particle; 

/// =========================================================================== 

int main() 
{ 
    vector<char> Y; // data observations 
    Y.push_back('A'); Y.push_back('B'); Y.push_back('A'); Y.push_back('A'); Y.push_back('A'); Y.push_back('B'); 
    Y.push_back('A'); Y.push_back('A'); Y.push_back('B'); Y.push_back('A'); Y.push_back('B'); Y.push_back('A'); 
    Y.push_back('A'); Y.push_back('B'); Y.push_back('B'); Y.push_back('A'); Y.push_back('A'); Y.push_back('B'); 

    vector< vector<Particle> > Xall; // vector of all particles from time 0 to t 

    /// Step (1) Initialisation 
    vector<Particle> X; // a vector of N particles 
    for(int i = 0; i < N; ++i) 
    { 
     Particle x; 

     // sample particle Xi from initial distribution 
     x.distribution.PA = 0.5; x.distribution.PB = 0.5; 
     float r = uniform_generator(); 
     if(r <= x.distribution.PA) x.state = 'A'; // r <= 0.5 
     if(x.distribution.PA < r && r <= x.distribution.PA + x.distribution.PB) x.state = 'B'; // 0.5 < r <= 1 

     X.push_back(x); 
    } 

    Xall.push_back(X); 
    X.clear(); 

    /// Observing data 
    for(int t = 1; t <= 18; ++t) 
    { 
     char y = Y[t-1]; // current observation 

     /// Step (2) Importance sampling 
     float sumWeights = 0; 
     vector<Particle> X; // a vector of N particles 
     for(int i = 0; i < N; ++i) 
     { 
      Particle x; 

      // P(X^i_t = A) = P(X^i_t = A | X^i_t-1 = A) * P(X^i_t-1 = A) + P(X^i_t = A | X^i_t-1 = B) * P(X^i_t-1 = B) 
      x.distribution.PA = evolutionProba_A_A * Xall[t-1][i].distribution.PA + evolutionProba_A_B * Xall[t-1][i].distribution.PB; 

      // P(X^i_t = B) = P(X^i_t = B | X^i_t-1 = A) * P(X^i_t-1 = A) + P(X^i_t = B | X^i_t-1 = B) * P(X^i_t-1 = B) 
      x.distribution.PB = evolutionProba_B_A * Xall[t-1][i].distribution.PA + evolutionProba_B_B * Xall[t-1][i].distribution.PB; 

      // sample the a particle from this distribution 
      float r = uniform_generator(); 
      if(r <= x.distribution.PA) x.state = 'A'; 
      if(x.distribution.PA < r && r <= x.distribution.PA + x.distribution.PB) x.state = 'B'; 

      // compute weight of this particle according to the observation y 
      if(y == 'A') 
      { 
       if(x.state == 'A') x.weight = observationProba_A_A; // P(y = A | X^i_t = A) 
       else if(x.state == 'B') x.weight = observationProba_A_B; // P(y = A | X^i_t = B) 
      } 
      else if(y == 'B') 
      { 
       if(x.state == 'A') x.weight = observationProba_B_A; // P(y = B | X^i_t = A) 
       else if(x.state == 'B') x.weight = observationProba_B_B; // P(y = B | X^i_t = B) 
      } 

      sumWeights += x.weight; 

      X.push_back(x); 
     } 

     // normalise weights 
     for(int i = 0; i < N; ++i) 
      X[i].weight /= sumWeights; 

     /// Step (3) resampling N particles according to weights 
     float PA = 0, PB = 0; 
     for(int i = 0; i < N; ++i) 
     { 
      if(X[i].state == 'A') PA += X[i].weight; 
      else if(X[i].state == 'B') PB += X[i].weight; 
     } 

     vector<Particle> reX; // new vector of particles 
     for(int i = 0; i < N; ++i) 
     { 
      Particle x; 

      x.distribution.PA = PA; 
      x.distribution.PB = PB; 

      float r = uniform_generator(); 
      if(r <= x.distribution.PA) x.state = 'A'; 
      if(x.distribution.PA < r && r <= x.distribution.PA + x.distribution.PB) x.state = 'B'; 

      reX.push_back(x); 
     } 

     Xall.push_back(reX); 
    } 

    return 0; 
} 

/// =========================================================================== 

double uniform_generator(void) 
{ 
    mt19937 gen(55); 
    static uniform_01< mt19937, double > uniform_gen(gen); 
    return uniform_gen(); 
} 
+0

Khi nào bạn có thể lọc bộ lọc này trong thế giới thực? Bạn có thể chạy thử nghiệm đối với một vấn đề với giải pháp phân tích không? Nếu bạn đã thực hiện nó một cách chính xác, bạn sẽ nhận được cùng một số. Rất khó để có được kết quả đúng với việc triển khai sai! –

+0

@AlessandroTeruzzi Đây chỉ là một ví dụ đơn giản được đưa ra [ở đây] (http://www.aiqus.com/questions/39942/very-simple-particle-filters-algorithm-sequential-monte-carlo-method-implementation/39950). Tôi đã thực hiện nó chỉ để hiểu rõ hơn về khái niệm [bộ lọc hạt được đưa ra bởi thuật toán này] (http://www.aiqus.com/upfiles/PFAlgo.png), nhưng tôi không chắc chắn nếu tôi đã triển khai nó một cách chính xác, vì Tôi không hiểu thuật toán rất rõ. Tôi không biết làm thế nào để kiểm tra nếu nó hoạt động, vì thuật toán và đầu ra của nó vẫn không rõ ràng với tôi (ngay cả khi thuật toán dường như rất đơn giản). – shn

+0

Đề nghị đầu tiên của tôi cho một thuật toán chung: không cố gắng thực hiện một cái gì đó bạn không hoàn toàn hiểu. Đầu tiên cam kết, sau đó thực hiện. Nếu không, bạn sẽ không thể nói những gì đang xảy ra. –

Trả lời

20

This online course rất dễ dàng và đơn giản để hiểu và với tôi nó giải thích các bộ lọc hạt thực sự tốt.

Nó được gọi là "Lập trình một chiếc xe robot", và nó nói về ba phương pháp địa phương hóa: bản địa hóa Monte Carlo, bộ lọc Kalman và bộ lọc hạt.

Khóa học hoàn toàn miễn phí (đã hoàn tất ngay bây giờ để bạn không thể tham gia tích cực nhưng bạn vẫn có thể xem các bài giảng), được giảng dạy bởi một giáo sư Stanford. Các "lớp học" là đáng ngạc nhiên dễ dàng cho tôi để làm theo, và họ được đi kèm với các bài tập nhỏ - một số người trong số họ chỉ hợp lý, nhưng một thỏa thuận tốt của họ lập trình. Ngoài ra, bài tập về nhà mà bạn có thể chơi cùng.

Nó thực sự làm cho bạn viết mã của riêng bạn trong python cho tất cả các bộ lọc, mà họ cũng kiểm tra cho bạn. Đến cuối khóa học, bạn nên có tất cả 3 bộ lọc được triển khai trong python.

Nhiệt liệt khuyên bạn nên kiểm tra.

+0

Ok, tôi sẽ kiểm tra. Nhưng kể từ khi tôi chỉ quan tâm đến các bộ lọc hạt (có lẽ cũng là hai bộ lọc khác), tôi nên kiểm tra tất cả các khóa học của tất cả các đơn vị từ đầu? – shn

+0

Nếu bạn quan tâm đến tất cả các bộ lọc, bạn chắc chắn nên kiểm tra toàn bộ khóa học. Nhưng ngay cả khi bạn không, tôi khuyên bạn nên đi qua các khóa học khác - nó sẽ cung cấp cho bạn một cái nhìn tổng quan chung về phương pháp bản địa hóa và bạn sẽ dễ dàng hiểu được từng bộ lọc phù hợp nhất ở đâu. Tôi nghĩ rằng 1 bài giảng thường có thể được thực hiện trong khoảng 4 giờ - có thể làm điều đó trong 1 hoặc 2 ngày nếu bạn muốn dễ dàng;) – penelope

+0

Nhân tiện, tôi sẽ không sử dụng các bộ lọc hạt cho robot (bản địa hóa, vv), tôi sẽ sử dụng nó cho một vấn đề khác liên quan đến phân cụm trực tuyến dữ liệu tuần tự. – shn

3
+0

Họ bằng cách nào đó không phải là những gì tôi mong đợi. Có anyway để thực hiện một trong những đơn giản trình bày trong trang 9 của www.cs.ubc.ca/~ arnaud/doucet_defreitas_gordon_smcbookintro.ps? – shn

+0

Chắc chắn, có nhiều cách :) Các liên kết khác với mong đợi của bạn như thế nào? Bạn đang bị treo ở đâu? Tôi tin rằng thuật toán trên p. 11. khá đơn giản. – Throwback1986

+0

Vâng, tôi muốn thực hiện các bộ lọc hạt được biết đến từ scrach chỉ để hiểu nó. Tôi đã chỉnh sửa bài đăng đầu tiên của mình để thêm một triển khai C++ đơn giản của một ví dụ đơn giản được giải thích tại đây: http://www.aiqus.com/questions/39942/very-simple-particle-filters-algorithm-sequential-monte-carlo- triển khai phương pháp? page = 1 # 39950 Bạn có thể kiểm tra xem tôi có hiểu rõ hay không, hoặc có một số hiểu lầm? – shn