Bỏ qua

Phương Pháp Bayes và Mô Hình Tuần Tự (Bayesian Methods and Sequential Models)

Phương pháp Bayes kết hợp niềm tin tiên nghiệm với dữ liệu quan sát để tạo ra phân bố hậu nghiệm trên các tham số mô hình. File này bao gồm ước lượng hợp lý cực đại (MLE), ước lượng hậu nghiệm cực đại (MAP), tiên nghiệm liên hợp, suy luận Bayes, mô hình Markov ẩn (HMM), và thuật toán EM — các kỹ thuật đằng sau bộ lọc spam, mô hình ngôn ngữ, và ML có nhận thức về độ không chắc chắn.

  • Cho đến giờ ta đã mô tả các phân bố và cách tính xác suất. Bây giờ ta giải quyết câu hỏi cốt lõi của ML: với dữ liệu quan sát được, làm thế nào để tìm các tham số tốt nhất cho mô hình của chúng ta?

  • Ước lượng hợp lý cực đại (MLE) trả lời trực tiếp câu hỏi này. Chọn các giá trị tham số làm cho dữ liệu quan sát được có xác suất cao nhất.

  • Một cách hình thức, với dữ liệu \(D = \{x_1, x_2, \ldots, x_n\}\) và một mô hình với tham số \(\theta\), hàm hợp lý (likelihood function) là:

\[L(\theta | D) = P(D | \theta) = \prod_{i=1}^{n} P(x_i | \theta)\]
  • Tích giả định các điểm dữ liệu độc lập và cùng phân bố (i.i.d.). Ước lượng MLE là:
\[\hat{\theta}_{\text{MLE}} = \arg\max_\theta L(\theta | D)\]
  • Trong thực tế, ta cực đại hóa log-hợp lý (log-likelihood) thay thế, vì log biến tích thành tổng và ngăn chặn tràn số dưới:
\[\ell(\theta) = \log L(\theta | D) = \sum_{i=1}^{n} \log P(x_i | \theta)\]
  • \(\log\) đơn điệu tăng, \(\theta\) làm cực đại \(\ell(\theta)\) cũng làm cực đại \(L(\theta)\).

  • Ví dụ tung đồng xu: bạn tung đồng xu 10 lần và được 7 mặt ngửa. Ước lượng MLE cho độ thiên lệch \(p\) (xác suất mặt ngửa) của đồng xu là bao nhiêu?

  • Mỗi lần tung là Bernoulli(\(p\)), vậy hàm hợp lý của 7 mặt ngửa trong 10 lần tung là:

\[L(p) = \binom{10}{7} p^7 (1-p)^3\]
  • Lấy log và đạo hàm: \(\frac{d\ell}{dp} = \frac{7}{p} - \frac{3}{1-p} = 0\), cho ta \(\hat{p}_{\text{MLE}} = 7/10 = 0.7\).

  • MLE trực quan và đơn giản. Nếu bạn được 7 mặt ngửa trong 10 lần tung, độ thiên lệch có khả năng nhất là 0.7. Nhưng hãy lưu ý vấn đề: nếu bạn được 10 mặt ngửa trong 10 lần tung, MLE nói \(\hat{p} = 1\), nghĩa là đồng xu sẽ luôn ra mặt ngửa. Điều này có vẻ quá tự tin với chỉ 10 lần quan sát.

  • Ước lượng hậu nghiệm cực đại (MAP) khắc phục điều này bằng cách thêm niềm tin tiên nghiệm. Thay vì chỉ cực đại hóa hàm hợp lý, MAP cực đại hóa hậu nghiệm:

\[\hat{\theta}_{\text{MAP}} = \arg\max_\theta P(\theta | D) = \arg\max_\theta P(D | \theta) \cdot P(\theta)\]
  • Ta bỏ \(P(D)\) khỏi mẫu số vì nó không phụ thuộc vào \(\theta\) và không ảnh hưởng đến argmax.

  • Tiên nghiệm \(P(\theta)\) mã hóa những gì ta tin về \(\theta\) trước khi nhìn thấy dữ liệu. Nếu ta dùng tiên nghiệm Beta(2, 2) cho độ thiên lệch của đồng xu (biểu thị niềm tin nhẹ rằng đồng xu gần như công bằng), ước lượng MAP không còn đơn giản là tỷ lệ mặt ngửa. Nó bị kéo về phía 0.5.

MLE tìm đỉnh của hàm hợp lý; MAP tìm đỉnh của hàm hợp lý nhân với tiên nghiệm

  • Với tiên nghiệm Beta(\(\alpha\), \(\beta\)) và quan sát \(h\) mặt ngửa và \(t\) mặt sấp, hậu nghiệm là Beta(\(\alpha + h\), \(\beta + t\)), và ước lượng MAP là:
\[\hat{p}_{\text{MAP}} = \frac{\alpha + h - 1}{\alpha + \beta + h + t - 2}\]
  • Với ví dụ của ta với tiên nghiệm Beta(2,2), 7 mặt ngửa, 3 mặt sấp: \(\hat{p}_{\text{MAP}} = \frac{2 + 7 - 1}{2 + 2 + 10 - 2} = \frac{8}{12} = 0.667\).

  • Hãy để ý ước lượng MAP (0.667) bị kéo về phía 0.5 so với MLE (0.7). Tiên nghiệm đóng vai trò chính quy hóa. Trong ML, chính quy hóa L2 (suy giảm trọng số) chính xác tương đương với MAP với tiên nghiệm Gauss trên các trọng số.

  • Suy luận Bayes đầy đủ (Full Bayesian inference) đi xa hơn MAP. Thay vì tìm một \(\theta\) tốt nhất duy nhất, nó duy trì toàn bộ phân bố hậu nghiệm \(P(\theta | D)\). Điều này cho bạn không chỉ một ước lượng điểm mà còn một thước đo về độ không chắc chắn.

  • Với đồng xu thiên lệch và tiên nghiệm Beta(2,2), 7 mặt ngửa, 3 mặt sấp, hậu nghiệm đầy đủ là Beta(9, 5). Kỳ vọng của phân bố này là \(9/14 \approx 0.643\), và độ trải rộng của nó cho ta biết mức độ tự tin. Với nhiều dữ liệu hơn, hậu nghiệm thu hẹp lại.

  • Ba cách tiếp cận tạo thành một phổ:

    • MLE: không có tiên nghiệm, chỉ dữ liệu. Nhanh, nhưng có thể quá khớp với ít dữ liệu.
    • MAP: ước lượng điểm với chính quy hóa từ tiên nghiệm. Tăng độ mạnh mẽ.
    • Bayes đầy đủ: toàn bộ phân bố hậu nghiệm. Nhiều thông tin nhất, nhưng thường đắt về mặt tính toán.
  • Xích Markov (Markov chains) mô hình hóa các chuỗi mà trạng thái tiếp theo chỉ phụ thuộc vào trạng thái hiện tại, không phụ thuộc vào lịch sử. Tính "không nhớ" này được gọi là tính Markov (Markov property):

\[P(X_{t+1} | X_t, X_{t-1}, \ldots, X_1) = P(X_{t+1} | X_t)\]
  • Hãy hình dung về thời tiết. Thời tiết ngày mai phụ thuộc vào thời tiết hôm nay, nhưng không phụ thuộc vào tuần trước (một sự đơn giản hóa, nhưng hữu ích một cách đáng ngạc nhiên).

  • Một xích Markov có một tập trạng thái hữu hạn và một ma trận chuyển tiếp (transition matrix) \(T\) trong đó phần tử \(T_{ij}\) cho xác suất chuyển từ trạng thái \(i\) sang trạng thái \(j\). Mỗi hàng có tổng bằng 1.

Xích Markov thời tiết với các trạng thái Rainy, Sunny, Cloudy và xác suất chuyển tiếp

  • Với ví dụ thời tiết trên, ma trận chuyển tiếp là:
\[ T = \begin{pmatrix} 0.3 & 0.4 & 0.3 \\ 0.2 & 0.5 & 0.3 \\ 0.4 & 0.3 & 0.3 \end{pmatrix} \]
  • Nếu hôm nay trời mưa (vector trạng thái \(\mathbf{s}_0 = [1, 0, 0]\)), phân bố xác suất cho thời tiết ngày mai là \(\mathbf{s}_1 = \mathbf{s}_0 T = [0.3, 0.4, 0.3]\). Hai ngày nữa: \(\mathbf{s}_2 = \mathbf{s}_0 T^2\). Điều này dùng phép nhân ma trận từ Chương 1.

  • Nhiều xích Markov hội tụ về một phân bố dừng (stationary distribution) \(\pi\) sao cho \(\pi T = \pi\). Bất kể bạn bắt đầu từ đâu, sau đủ nhiều bước, xích sẽ ổn định ở \(\pi\). Tính chất này là nền tảng của MCMC (Markov Chain Monte Carlo), một kỹ thuật lấy mẫu được sử dụng rộng rãi trong ML Bayes.

  • Mô hình Markov ẩn (HMM) mở rộng xích Markov bằng cách thêm một lớp gián tiếp. Các trạng thái thực sự bị ẩn (không quan sát được), và tại mỗi bước thời gian, trạng thái ẩn phát ra một tín hiệu quan sát được.

Cấu trúc HMM: các trạng thái ẩn ở trên được kết nối bởi các chuyển tiếp, các quan sát ở dưới được kết nối bởi các phát xạ

  • Một HMM có ba thành phần:

    • Xác suất chuyển tiếp (Transition probabilities) \(P(z_t | z_{t-1})\): cách các trạng thái ẩn tiến hóa (xích Markov)
    • Xác suất phát xạ (Emission probabilities) \(P(x_t | z_t)\): mỗi trạng thái ẩn tạo ra quan sát nào
    • Phân bố khởi tạo (Initial distribution) \(P(z_1)\): xác suất trạng thái ẩn ban đầu
  • Ví dụ về ô dù: giả sử bạn không thể thấy trực tiếp thời tiết nhưng bạn có thể quan sát bạn mình có mang ô hay không. Các trạng thái ẩn là {Rainy, Sunny} và quan sát là {Umbrella, No umbrella}.

  • Xác suất chuyển tiếp: \(P(\text{Rainy}|\text{Rainy}) = 0.7\), \(P(\text{Sunny}|\text{Rainy}) = 0.3\), \(P(\text{Rainy}|\text{Sunny}) = 0.4\), \(P(\text{Sunny}|\text{Sunny}) = 0.6\).

  • Xác suất phát xạ: \(P(\text{Umbrella}|\text{Rainy}) = 0.9\), \(P(\text{No umbrella}|\text{Rainy}) = 0.1\), \(P(\text{Umbrella}|\text{Sunny}) = 0.2\), \(P(\text{No umbrella}|\text{Sunny}) = 0.8\).

  • Các câu hỏi chính cho HMM là:

    • Giải mã (Decoding): với các quan sát đã cho, dãy trạng thái ẩn nào có khả năng nhất? Được giải bằng thuật toán Viterbi.
    • Đánh giá (Evaluation): xác suất của một dãy quan sát là bao nhiêu? Được giải bằng thuật toán Forward.
    • Học (Learning): với các quan sát đã cho, tham số mô hình tốt nhất là gì? Được giải bằng thuật toán Baum-Welch (một trường hợp của Expectation-Maximisation).
  • Trình bày chi tiết Viterbi: giả sử bạn quan sát [Umbrella, Umbrella, No umbrella] và muốn tìm dãy thời tiết có khả năng nhất.

  • Bắt đầu với xác suất khởi tạo. Giả sử \(P(R) = 0.5\), \(P(S) = 0.5\).

  • Ngày 1 (quan sát Umbrella):

    • \(V_1(R) = P(R) \cdot P(U|R) = 0.5 \times 0.9 = 0.45\)
    • \(V_1(S) = P(S) \cdot P(U|S) = 0.5 \times 0.2 = 0.10\)
  • Ngày 2 (quan sát Umbrella):

    • \(V_2(R) = \max(V_1(R) \cdot P(R|R), V_1(S) \cdot P(R|S)) \cdot P(U|R)\)
    • \(= \max(0.45 \times 0.7, 0.10 \times 0.4) \times 0.9 = \max(0.315, 0.04) \times 0.9 = 0.2835\)
    • \(V_2(S) = \max(V_1(R) \cdot P(S|R), V_1(S) \cdot P(S|S)) \cdot P(U|S)\)
    • \(= \max(0.45 \times 0.3, 0.10 \times 0.6) \times 0.2 = \max(0.135, 0.06) \times 0.2 = 0.027\)
  • Ngày 3 (quan sát No umbrella):

    • \(V_3(R) = \max(0.2835 \times 0.7, 0.027 \times 0.4) \times 0.1 = 0.1985 \times 0.1 = 0.01985\)
    • \(V_3(S) = \max(0.2835 \times 0.3, 0.027 \times 0.6) \times 0.8 = 0.08505 \times 0.8 = 0.06804\)
  • Giá trị lớn nhất của Ngày 3 là ở Sunny. Truy ngược: Ngày 3 = Sunny (từ R), Ngày 2 = Rainy (từ R), Ngày 1 = Rainy. Dãy có khả năng nhất: Rainy, Rainy, Sunny.

  • Thuật toán Forward-Backward tính xác suất ở mỗi trạng thái ẩn tại mỗi bước thời gian, với điều kiện trên toàn bộ dãy quan sát. Lượt forward tính \(P(z_t, x_{1:t})\) và lượt backward tính \(P(x_{t+1:T} | z_t)\). Nhân chúng lại cho xác suất trạng thái đã làm mượt.

  • Thuật toán Baum-Welch học các tham số HMM từ dữ liệu khi các trạng thái ẩn không được quan sát. Nó là một thuật toán Expectation-Maximisation (EM): bước E dùng forward-backward để ước lượng trạng thái ẩn nào đã tạo ra các quan sát, và bước M cập nhật các xác suất chuyển tiếp và phát xạ.

  • HMM từng chiếm ưu thế trong nhận dạng giọng nói (trạng thái âm vị ẩn phát ra tín hiệu âm thanh) và tin sinh học (trạng thái gen ẩn phát ra các cặp base DNA). Mặc dù học sâu đã phần lớn thay thế HMM trong các lĩnh vực này, các ý tưởng về trạng thái ẩn, phát xạ, và suy luận tuần tự vẫn là trung tâm của các mô hình chuỗi.

  • Trường Ngẫu nhiên Có điều kiện (CRF) cải tiến HMM bằng cách loại bỏ giả định độc lập trên các phát xạ. Trong HMM, quan sát tại thời điểm \(t\) chỉ phụ thuộc vào trạng thái ẩn tại thời điểm \(t\). CRF cho phép nhãn tại vị trí \(t\) phụ thuộc vào toàn bộ chuỗi đầu vào.

  • CRF tuyến tính (linear-chain CRF) mô hình hóa xác suất có điều kiện của một dãy nhãn \(\mathbf{y}\) với điều kiện trên dãy đầu vào \(\mathbf{x}\):

\[P(\mathbf{y} | \mathbf{x}) = \frac{1}{Z(\mathbf{x})} \exp\!\left(\sum_t \left[\sum_k \lambda_k f_k(y_t, y_{t-1}, \mathbf{x}, t)\right]\right)\]
  • Ở đây \(f_k\) là các hàm đặc trưng (có thể nhìn vào bất kỳ phần nào của đầu vào), \(\lambda_k\) là các trọng số học được, và \(Z(\mathbf{x})\) là hằng số chuẩn hóa.

  • CRF là các mô hình phân biệt (discriminative) (chúng mô hình hóa \(P(\mathbf{y}|\mathbf{x})\) trực tiếp) trong khi HMM là các mô hình sinh (generative) (chúng mô hình hóa \(P(\mathbf{x}, \mathbf{y})\)). Sự khác biệt này cũng giống như hồi quy logistic (discriminative) so với Naive Bayes (generative).

  • Trong NLP hiện đại, các tầng CRF thường được thêm lên trên các mạng nơ-ron (BiLSTM-CRF, BERT-CRF) cho các tác vụ như nhận dạng thực thể có tên (NER) và gán nhãn từ loại (POS tagging), nơi việc nắm bắt các phụ thuộc giữa các nhãn là quan trọng.

Bài tập lập trình (dùng CoLab hoặc notebook)

  1. Cài đặt MLE và MAP cho thí nghiệm tung đồng xu. Quan sát ước lượng MAP thay đổi thế nào với các tiên nghiệm khác nhau và lượng dữ liệu khác nhau.

    import jax.numpy as jnp
    import matplotlib.pyplot as plt
    
    # Data: observed coin flips
    heads, tails = 7, 3
    
    # MLE
    p_mle = heads / (heads + tails)
    print(f"MLE: {p_mle:.4f}")
    
    # MAP with Beta prior
    for alpha, beta in [(1,1), (2,2), (5,5), (10,10)]:
        p_map = (alpha + heads - 1) / (alpha + beta + heads + tails - 2)
        print(f"MAP (Beta({alpha},{beta})): {p_map:.4f}")
    
    # Visualise posterior for Beta(2,2) prior
    theta = jnp.linspace(0.01, 0.99, 200)
    # Posterior is Beta(alpha+heads, beta+tails)
    a_post, b_post = 2 + heads, 2 + tails
    posterior = theta**(a_post-1) * (1-theta)**(b_post-1)
    posterior = posterior / jnp.trapezoid(posterior, theta)
    
    plt.figure(figsize=(8, 4))
    plt.plot(theta, posterior, color="#e74c3c", linewidth=2, label=f"Posterior Beta({a_post},{b_post})")
    plt.axvline(p_mle, color="#3498db", linestyle="--", label=f"MLE = {p_mle:.2f}")
    plt.axvline((a_post-1)/(a_post+b_post-2), color="#e74c3c", linestyle="--", label=f"MAP = {(a_post-1)/(a_post+b_post-2):.3f}")
    plt.xlabel("θ (coin bias)")
    plt.ylabel("Density")
    plt.title("Posterior distribution after 7H, 3T with Beta(2,2) prior")
    plt.legend()
    plt.grid(alpha=0.3)
    plt.show()
    

  2. Xây dựng một xích Markov cho mô hình thời tiết và mô phỏng nó. Tính phân bố dừng bằng cả mô phỏng và bằng cách giải \(\pi T = \pi\).

    import jax
    import jax.numpy as jnp
    
    # Transition matrix: R, S, C
    T = jnp.array([
        [0.3, 0.4, 0.3],
        [0.2, 0.5, 0.3],
        [0.4, 0.3, 0.3]
    ])
    states = ["Rainy", "Sunny", "Cloudy"]
    
    # Simulate 100,000 steps
    key = jax.random.PRNGKey(42)
    n_steps = 100_000
    state = 0  # start rainy
    counts = jnp.zeros(3)
    
    for i in range(n_steps):
        key, subkey = jax.random.split(key)
        state = jax.random.choice(subkey, 3, p=T[state])
        counts = counts.at[state].add(1)
    
    sim_stationary = counts / n_steps
    print("Simulated stationary distribution:")
    for s, p in zip(states, sim_stationary):
        print(f"  {s}: {p:.4f}")
    
    # Analytical: find left eigenvector with eigenvalue 1
    eigenvalues, eigenvectors = jnp.linalg.eig(T.T)
    idx = jnp.argmin(jnp.abs(eigenvalues - 1.0))
    pi = jnp.real(eigenvectors[:, idx])
    pi = pi / pi.sum()
    print("\nAnalytical stationary distribution:")
    for s, p in zip(states, pi):
        print(f"  {s}: {p:.4f}")
    

  3. Cài đặt thuật toán Viterbi cho HMM ô dù và giải mã một dãy quan sát.

    import jax.numpy as jnp
    
    # HMM parameters
    states = ["Rainy", "Sunny"]
    obs_names = ["Umbrella", "No umbrella"]
    
    trans = jnp.array([[0.7, 0.3],   # R->R, R->S
                        [0.4, 0.6]])  # S->R, S->S
    
    emit = jnp.array([[0.9, 0.1],    # R->U, R->noU
                       [0.2, 0.8]])   # S->U, S->noU
    
    init = jnp.array([0.5, 0.5])
    
    # Observations: U=0, noU=1
    observations = [0, 0, 1]  # Umbrella, Umbrella, No umbrella
    
    def viterbi(obs, init, trans, emit):
        n_states = len(init)
        T = len(obs)
        V = jnp.zeros((T, n_states))
        path = jnp.zeros((T, n_states), dtype=int)
    
        # Initialisation
        V = V.at[0].set(init * emit[:, obs[0]])
    
        # Recursion
        for t in range(1, T):
            for j in range(n_states):
                probs = V[t-1] * trans[:, j]
                V = V.at[t, j].set(jnp.max(probs) * emit[j, obs[t]])
                path = path.at[t, j].set(jnp.argmax(probs))
    
        # Backtrack
        best = [int(jnp.argmax(V[-1]))]
        for t in range(T-1, 0, -1):
            best.insert(0, int(path[t, best[0]]))
        return best, V
    
    decoded, scores = viterbi(observations, init, trans, emit)
    print("Observations:", [obs_names[o] for o in observations])
    print("Decoded:     ", [states[s] for s in decoded])
    

  4. Trực quan hóa cách hậu nghiệm tiến hóa khi bạn quan sát thêm nhiều lần tung đồng xu. Bắt đầu với tiên nghiệm Beta(1,1) (đều) và cập nhật sau mỗi lần tung.

    import jax
    import jax.numpy as jnp
    import matplotlib.pyplot as plt
    
    theta = jnp.linspace(0.01, 0.99, 300)
    key = jax.random.PRNGKey(7)
    
    # True bias = 0.65
    flips = jax.random.bernoulli(key, p=0.65, shape=(50,))
    
    plt.figure(figsize=(10, 5))
    a, b = 1, 1  # Beta(1,1) = uniform
    
    for n_obs in [0, 1, 5, 10, 25, 50]:
        h = int(flips[:n_obs].sum())
        t = n_obs - h
        a_post = a + h
        b_post = b + t
        y = theta**(a_post-1) * (1-theta)**(b_post-1)
        y = y / jnp.trapezoid(y, theta)
        plt.plot(theta, y, linewidth=2, label=f"n={n_obs} (h={h})")
    
    plt.axvline(0.65, color="black", linestyle=":", alpha=0.5, label="true p=0.65")
    plt.xlabel("θ")
    plt.ylabel("Density")
    plt.title("Bayesian updating: posterior narrows with more data")
    plt.legend()
    plt.grid(alpha=0.3)
    plt.show()