Khái niệm Xác Suất (Probability Concepts)¶
Lý thuyết xác suất hình thức hóa sự không chắc chắn và cung cấp các quy tắc để lập luận trong điều kiện không chắc chắn. File này bao gồm không gian mẫu, biến cố, tiên đề xác suất, xác suất có điều kiện, tính độc lập, định lý Bayes, và các diễn giải theo tần suất (frequentist) và Bayes — khuôn khổ toán học đằng sau mọi mô hình sinh và mô hình phân biệt (generative & discriminative) trong ML.
-
Xác suất gán một con số từ 0 đến 1 cho một biến cố, đo lường khả năng nó xảy ra.
-
Xác suất 0 nghĩa là không thể, 1 nghĩa là chắc chắn, và 0.5 nghĩa là tung đồng xu.
-
Có hai diễn giải chính. Quan điểm tần suất (frequentist) cho rằng xác suất là tần suất tương đối trong dài hạn: tung một đồng xu công bằng 10.000 lần và mặt ngửa sẽ xuất hiện khoảng 50% số lần.
-
Quan điểm Bayes cho rằng xác suất là mức độ tin tưởng: bạn có thể nói có 70% khả năng trời mưa vào ngày mai, mặc dù ngày mai chỉ xảy ra một lần.
-
Cả hai diễn giải đều dùng cùng các quy tắc toán học. Sự khác biệt là về triết học, nhưng nó quan trọng trong ML. Phương pháp tần suất cho bạn ước lượng điểm. Phương pháp Bayes cho bạn phân bố đầy đủ trên các tham số.
-
Không gian mẫu (sample space) \(S\) là tập hợp tất cả các kết quả khả dĩ của một thí nghiệm. Tung đồng xu: \(S = \{H, T\}\). Gieo xúc xắc: \(S = \{1, 2, 3, 4, 5, 6\}\).
-
Một biến cố (event) là bất kỳ tập con nào của không gian mẫu. "Gieo được số chẵn" là biến cố \(A = \{2, 4, 6\}\), là một tập con của \(S\).
-
Xác suất của một biến cố khi tất cả các kết quả có khả năng như nhau chỉ đơn giản là đếm (từ file 01):
- Với ví dụ số chẵn: \(P(\text{chẵn}) = \frac{3}{6} = 0.5\).
- Phần bù (complement) của biến cố \(A\), viết là \(A'\) hoặc \(A^c\), là mọi thứ trong \(S\) không thuộc \(A\). Vì mọi kết quả hoặc thuộc \(A\) hoặc không:
-
Phần bù thường là cách dễ dàng hơn. Thay vì đếm tất cả các cách để có ít nhất một mặt ngửa trong 5 lần tung, hãy đếm một cách duy nhất để không có mặt ngửa nào và trừ đi: \(P(\text{ít nhất một mặt ngửa}) = 1 - P(\text{tất cả đều sấp}) = 1 - (0.5)^5 = 0.969\).
-
Hai biến cố xung khắc (mutually exclusive) (rời rạc) nếu chúng không thể cùng xảy ra: \(A \cap B = \emptyset\). Gieo được mặt 2 và gieo được mặt 5 trên cùng một xúc xắc là xung khắc.
-
Quy tắc cộng cho các biến cố xung khắc rất đơn giản:
- Khi các biến cố có thể chồng chéo, bạn cần quy tắc cộng tổng quát để tránh đếm trùng phần giao:
-
Điều này phản ánh nguyên lý bù-trừ từ phần đếm. Biểu đồ Venn ở trên cho thấy lý do: vùng tím (phần giao) được đếm một lần trong \(P(A)\) và một lần nữa trong \(P(B)\), vì vậy ta trừ nó đi một lần.
-
Xác suất đồng thời (joint probability) \(P(A \cap B)\) là xác suất cả \(A\) và \(B\) cùng xảy ra. Trong một bộ bài, \(P(\text{đỏ} \cap \text{già}) = \frac{2}{52}\) vì có 2 con già màu đỏ.
-
Xác suất biên (marginal probability) là xác suất của một biến cố đơn lẻ bất kể các biến cố khác. \(P(\text{đỏ}) = \frac{26}{52} = 0.5\) là xác suất biên. Nếu bạn có một phân bố đồng thời trên hai biến, xác suất biên thu được bằng cách lấy tổng (hoặc tích phân) trên biến kia.
-
Xác suất có điều kiện (conditional probability) trả lời: cho rằng \(B\) đã xảy ra, xác suất của \(A\) là bao nhiêu? Ta thu hẹp không gian mẫu từ \(S\) xuống \(B\), và hỏi phần nào của \(B\) cũng thuộc về \(A\):
-
Ví dụ: bạn rút một lá bài và ai đó nói với bạn nó màu đỏ. Xác suất nó là con già là bao nhiêu? Có 26 lá đỏ và 2 trong số đó là già, vậy \(P(\text{già} | \text{đỏ}) = \frac{2}{26} = \frac{1}{13}\). Dùng công thức: \(P(\text{già} \cap \text{đỏ}) / P(\text{đỏ}) = \frac{2/52}{26/52} = \frac{1}{13}\).
-
Hai biến cố độc lập (independent) nếu biết một biến cố xảy ra không cho bạn thông tin gì về biến cố kia. Một cách hình thức:
-
Tương đương, \(P(A | B) = P(A)\). Tung hai đồng xu riêng biệt là các biến cố độc lập. Rút hai lá bài không hoàn lại là không độc lập (lần rút đầu tiên thay đổi những gì còn lại).
-
Tính độc lập là một công cụ đơn giản hóa mạnh mẽ. Với các biến cố độc lập, xác suất đồng thời phân tích thành tích, giúp việc tính toán khả thi. Nhiều mô hình ML giả định tính độc lập giữa các đặc trưng (ví dụ: Naive Bayes) chính xác nhờ sự đơn giản hóa này.
-
Quy tắc nhân (multiplication rule) cho hai biến cố bất kỳ được sắp xếp lại từ công thức xác suất có điều kiện:
-
Với các biến cố độc lập, điều này đơn giản thành \(P(A \cap B) = P(A) \cdot P(B)\) vì xác suất có điều kiện bằng xác suất biên.
-
Định lý Bayes (Bayes' theorem) là một trong những kết quả quan trọng nhất trong xác suất và là nền tảng của ML Bayes. Nó cho phép bạn đảo ngược chiều của xác suất có điều kiện:
- Định lý được suy ra trực tiếp bằng cách viết \(P(A \cap B)\) theo hai cách: \(P(B|A) \cdot P(A) = P(A|B) \cdot P(B)\), sau đó giải cho \(P(A|B)\).
-
Mỗi thành phần có một tên gọi:
- Tiên nghiệm (Prior) \(P(A)\): niềm tin ban đầu trước khi nhìn thấy bằng chứng
- Hàm hợp lý (Likelihood) \(P(B|A)\): khả năng của bằng chứng, giả sử \(A\) đúng
- Bằng chứng (Evidence) \(P(B)\): tổng xác suất nhìn thấy bằng chứng, đóng vai trò chuẩn hóa
- Hậu nghiệm (Posterior) \(P(A|B)\): niềm tin đã cập nhật sau khi nhìn thấy bằng chứng
-
Hãy cùng giải ví dụ chẩn đoán y khoa kinh điển. Giả sử một căn bệnh ảnh hưởng đến 1% dân số. Một xét nghiệm cho căn bệnh này có độ chính xác 95%: nó xác định đúng 95% người bệnh (độ nhạy) và xác định đúng 90% người khỏe (độ đặc hiệu).
-
Bạn xét nghiệm dương tính. Xác suất bạn thực sự mắc bệnh là bao nhiêu?
-
Gọi \(D\) = mắc bệnh, \(+\) = xét nghiệm dương tính.
- Tiên nghiệm: \(P(D) = 0.01\)
- Hàm hợp lý: \(P(+ | D) = 0.95\)
- Tỷ lệ dương tính giả: \(P(+ | D') = 0.10\)
-
Ta cần \(P(+)\). Theo luật tổng xác suất:
- Bây giờ áp dụng định lý Bayes:
-
Mặc dù xét nghiệm "chính xác 95%", một kết quả dương tính chỉ cho bạn khoảng 8.8% khả năng mắc bệnh. Tiên nghiệm đóng vai trò cực kỳ quan trọng. Bởi vì căn bệnh hiếm gặp, hầu hết các kết quả dương tính đều là dương tính giả. Đây là một hiểu biết quan trọng cho bất kỳ bài toán phân lớp nào trong ML: khi các lớp mất cân bằng, độ chính xác (accuracy) một mình là gây hiểu lầm.
-
Luật tổng xác suất (law of total probability) phân hoạch không gian mẫu thành các biến cố xung khắc và đầy đủ \(B_1, B_2, \ldots, B_n\) và biểu diễn bất kỳ biến cố \(A\) nào như:
-
Đây chính xác là những gì ta đã dùng để tính \(P(+)\) trong ví dụ y khoa: ta chia dân số thành "mắc bệnh" và "không mắc bệnh."
-
Quy tắc dây chuyền của xác suất (chain rule of probability) tổng quát hóa quy tắc nhân cho bất kỳ số lượng biến cố nào:
-
Mỗi thừa số điều kiện hóa trên tất cả những gì xảy ra trước đó. Đây là xương sống của các mô hình ngôn ngữ tự hồi quy (autoregressive): xác suất của một câu là tích của xác suất mỗi từ với điều kiện trên tất cả các từ trước đó.
-
Độc lập có điều kiện (conditional independence) nghĩa là hai biến cố độc lập với nhau khi biết biến cố thứ ba. \(A\) và \(B\) độc lập có điều kiện với \(C\) nếu:
-
Các biến cố có thể phụ thuộc biên nhưng độc lập có điều kiện, hoặc ngược lại. Ví dụ, điểm thi của hai sinh viên có thể tương quan (cả hai phụ thuộc vào độ khó của bài thi), nhưng với điều kiện đã biết độ khó, điểm của họ là độc lập.
-
Độc lập có điều kiện là giả định chính đằng sau các mô hình đồ thị như mạng Bayes. Nó cho phép ta phân tích các phân bố đồng thời phức tạp thành những phần quản lý được, giúp suy luận khả thi về mặt tính toán.
Bài tập lập trình (dùng CoLab hoặc notebook)¶
-
Mô phỏng bài toán chẩn đoán y khoa. Tạo một quần thể 100.000 người, áp dụng tỷ lệ mắc bệnh và độ chính xác của xét nghiệm, và kiểm tra rằng định lý Bayes cho hậu nghiệm đúng.
import jax import jax.numpy as jnp key = jax.random.PRNGKey(42) n = 100_000 # Generate population k1, k2 = jax.random.split(key) has_disease = jax.random.bernoulli(k1, p=0.01, shape=(n,)) # Generate test results k3, k4 = jax.random.split(k2) # Sensitivity: P(+|D) = 0.95, Specificity: P(-|D') = 0.90 test_positive = jnp.where( has_disease, jax.random.bernoulli(k3, p=0.95, shape=(n,)), jax.random.bernoulli(k4, p=0.10, shape=(n,)) ) # Among those who tested positive, what fraction actually has the disease? positives = test_positive.astype(bool) true_positives = (has_disease & positives).sum() total_positives = positives.sum() print(f"Total positive tests: {total_positives}") print(f"True positives: {true_positives}") print(f"P(Disease | Positive) = {true_positives / total_positives:.4f}") print(f"Bayes' formula: {0.95 * 0.01 / 0.1085:.4f}") -
Kiểm tra quy tắc cộng bằng mô phỏng. Tạo các biến cố ngẫu nhiên A và B với xác suất và độ chồng chéo đã biết, sau đó kiểm tra \(P(A \cup B) = P(A) + P(B) - P(A \cap B)\).
import jax import jax.numpy as jnp key = jax.random.PRNGKey(0) n = 200_000 k1, k2 = jax.random.split(key) # Events: A = value < 0.4, B = value < 0.6 (overlap at < 0.4) vals_a = jax.random.uniform(k1, shape=(n,)) vals_b = jax.random.uniform(k2, shape=(n,)) A = vals_a < 0.4 B = vals_b < 0.6 p_a = A.mean() p_b = B.mean() p_a_and_b = (A & B).mean() p_a_or_b = (A | B).mean() print(f"P(A) = {p_a:.4f}") print(f"P(B) = {p_b:.4f}") print(f"P(A ∩ B) = {p_a_and_b:.4f}") print(f"P(A ∪ B) simulated = {p_a_or_b:.4f}") print(f"P(A) + P(B) - P(A∩B) = {p_a + p_b - p_a_and_b:.4f}") -
Minh họa rằng xác suất có điều kiện thay đổi với bằng chứng. Mô phỏng việc gieo hai xúc xắc và tính \(P(\text{tổng} = 7)\), sau đó \(P(\text{tổng} = 7 | \text{xúc xắc thứ nhất} = 3)\).
import jax import jax.numpy as jnp key = jax.random.PRNGKey(1) n = 500_000 k1, k2 = jax.random.split(key) d1 = jax.random.randint(k1, shape=(n,), minval=1, maxval=7) d2 = jax.random.randint(k2, shape=(n,), minval=1, maxval=7) total = d1 + d2 # Unconditional p_sum7 = (total == 7).mean() print(f"P(sum=7) = {p_sum7:.4f} (exact: {6/36:.4f})") # Conditional on first die = 3 mask = d1 == 3 p_sum7_given_d1_3 = (total[mask] == 7).mean() print(f"P(sum=7 | d1=3) = {p_sum7_given_d1_3:.4f} (exact: {1/6:.4f})") -
Cài đặt định lý Bayes như một hàm và dùng nó để cập nhật niềm tin lặp đi lặp lại. Bắt đầu với tiên nghiệm đều (uniform prior) về độ thiên lệch của đồng xu và cập nhật sau mỗi lần tung.
import jax.numpy as jnp import matplotlib.pyplot as plt def bayes_update(prior, likelihood): """Multiply prior by likelihood and normalise.""" posterior = prior * likelihood return posterior / posterior.sum() # Discretise possible bias values theta = jnp.linspace(0, 1, 200) prior = jnp.ones_like(theta) # uniform prior prior = prior / prior.sum() # Observed flips: 1=heads, 0=tails flips = [1, 1, 0, 1, 1, 1, 0, 1, 0, 1] plt.figure(figsize=(10, 5)) plt.plot(theta, prior, "--", color="#999", label="prior") for i, flip in enumerate(flips): likelihood = theta if flip == 1 else (1 - theta) prior = bayes_update(prior, likelihood) if i in [0, 2, 4, 9]: plt.plot(theta, prior, label=f"after {i+1} flips", linewidth=2) plt.xlabel("Coin bias θ") plt.ylabel("Belief (normalised)") plt.title("Bayesian updating: belief about coin bias") plt.legend() plt.grid(alpha=0.3) plt.show()