Các đại lượng Thống kê¶
Các đại lượng thống kê tóm tắt dữ liệu bằng các con số đơn lẻ nắm bắt độ phân tán, vị trí, hình dạng và mối liên hệ. Tài liệu này bao quát phương sai, độ lệch chuẩn, tứ phân vị, độ lệch, kurtosis, hiệp phương sai, tương quan và z-score — bộ công cụ cho phân tích dữ liệu khám phá và kỹ thuật đặc trưng trong học máy.
-
Ở tài liệu trước, ta đã giới thiệu các moment như một họ các thống kê tóm tắt. Tại đây ta phân tích các công cụ thực tế xuất phát từ chúng: các đại lượng về độ phân tán, vị trí, hình dạng và mối liên hệ.
-
Độ phân tán (dispersion) trả lời câu hỏi: dữ liệu dàn trải ra sao? Hai lớp học có thể có cùng điểm kiểm tra trung bình, nhưng độ phân tán rất khác nhau.
-
Phân bố hẹp (xanh) có phương sai thấp: hầu hết các giá trị tập trung chặt quanh trung bình. Phân bố rộng (đỏ) có phương sai cao: các giá trị phân tán xa hơn.
-
Phương sai (variance) là khoảng cách bình phương trung bình từ trung bình. Ta bình phương để tránh các độ lệch dương và âm triệt tiêu lẫn nhau.
- Khi làm việc với một mẫu (không phải toàn bộ tổng thể), ta chia cho \(N - 1\) thay vì \(N\). Sự hiệu chỉnh này (gọi là hiệu chỉnh Bessel) tính đến việc một mẫu có xu hướng đánh giá thấp độ biến thiên thực:
-
Độ lệch chuẩn (standard deviation) là căn bậc hai của phương sai: \(\sigma = \sqrt{\sigma^2}\). Nó đưa đại lượng trở về đơn vị gốc. Nếu dữ liệu tính bằng cm, phương sai là cm\(^2\), nhưng độ lệch chuẩn lại trở về cm.
-
Độ lệch tuyệt đối trung bình (MAD) (Mean Absolute Deviation) là một giải pháp thay thế đơn giản hơn. Thay vì bình phương, lấy giá trị tuyệt đối của mỗi độ lệch:
-
MAD mạnh mẽ hơn đối với các ngoại lệ so với phương sai vì nó không khuếch đại các độ lệch lớn bằng cách bình phương chúng. Tuy nhiên, phương sai thuận tiện hơn về mặt toán học (nó phân rã đẹp trong các chứng minh và tối ưu hóa ML).
-
Vị trí (position) trả lời một câu hỏi khác: một giá trị cụ thể nằm ở đâu so với phần còn lại của dữ liệu?
-
Các tứ phân vị (quartiles) chia dữ liệu đã sắp xếp thành bốn phần bằng nhau. Q1 (phân vị thứ 25) là giá trị mà dưới nó có 25% dữ liệu rơi vào. Q2 là trung vị (phân vị thứ 50). Q3 là phân vị thứ 75.
-
Khoảng tứ phân vị (IQR) (Interquartile Range) là \(Q3 - Q1\). Nó nắm bắt độ phân tán của 50% dữ liệu ở giữa, bỏ qua các giá trị cực đoan.
-
Biểu đồ hộp (box plot) là một trong những trực quan hóa hữu ích nhất trong thống kê. Hộp trải từ Q1 đến Q3, đường bên trong là trung vị, các đường xương râu mở rộng đến các giá trị ngoại lệ xa nhất, và các chấm ngoài xương râu là các ngoại lệ.
-
Các phân vị (percentiles) khái quát hóa tứ phân vị. Phân vị thứ \(p\) là giá trị mà dưới nó có \(p\%\) các quan sát rơi vào. Q1 là phân vị thứ 25, trung vị là thứ 50, và Q3 là thứ 75.
-
Z-score cho bạn biết một giá trị cách trung bình bao nhiêu độ lệch chuẩn:
-
Z-score bằng 2 nghĩa là giá trị đó ở trên trung bình 2 độ lệch chuẩn. Z-score \(-1.5\) nghĩa là nó ở dưới trung bình 1.5 độ lệch chuẩn. Phép biến đổi này còn được gọi là chuẩn hóa (standardisation) và được dùng nhiều trong ML để chia tỉ lệ đặc trưng, vì nó biến đổi mọi phân bố thành trung bình 0 và độ lệch chuẩn 1.
-
Hình dạng (shape) mô tả cấu trúc hình học của một phân bố vượt ra ngoài tâm và độ rộng của nó.
-
Độ lệch (Skewness) (moment thứ 3 đã chuẩn hóa từ tài liệu trước) đo độ bất đối xứng. Một phân bố đối xứng hoàn hảo như đường cong chuẩn có độ lệch bằng không. Độ lệch dương nghĩa là đuôi phải dài hơn (vd. phân bố thu nhập). Độ lệch âm nghĩa là đuôi trái dài hơn (vd. tuổi về hưu).
- Kurtosis (moment thứ 4 đã chuẩn hóa) đo độ nặng của đuôi. Phân bố chuẩn có kurtosis bằng 3. Các phân bố với đuôi nặng hơn (dễ có ngoại lệ hơn) có kurtosis lớn hơn 3.
- Tương quan (correlation) đo sức mạnh và hướng của mối quan hệ giữa hai biến. Nó trả lời: khi một biến tăng, biến kia có xu hướng tăng, giảm, hay không làm gì?
- Tương quan Pearson (\(r\)) đo mối liên hệ tuyến tính. Nó dao động từ \(-1\) (âm hoàn hảo) qua \(0\) (không) đến \(+1\) (dương hoàn hảo).
-
Nếu bạn nhớ tích vô hướng từ Chương 1, tương quan Pearson về cơ bản là độ tương tự cosine giữa các phiên bản đã định tâm trung bình của \(\mathbf{x}\) và \(\mathbf{y}\).
-
Tương quan Spearman (\(\rho\)) đo mối liên hệ đơn điệu (monotonic). Thay vì dùng giá trị thô, nó xếp hạng chúng trước rồi tính tương quan Pearson trên các hạng. Điều này làm nó mạnh mẽ với các ngoại lệ và hoạt động ngay cả khi mối quan hệ phi tuyến, miễn là nó luôn tăng hoặc luôn giảm.
-
Trung bình nhân (geometric mean) là trung bình thích hợp khi các giá trị nhân với nhau, như tốc độ tăng trưởng. Nếu khoản đầu tư của bạn tăng 10%, rồi 20%, rồi 30%, nhân tử tăng trưởng trung bình không phải là trung bình cộng của các tỷ lệ đó. Thay vào đó:
-
Với các tốc độ tăng trưởng cụ thể, hãy chuyển đổi phần trăm thành nhân tử trước (1.10, 1.20, 1.30), tính trung bình nhân, sau đó trừ 1.
-
Trung bình trượt hàm mũ (EMA) (Exponential Moving Average) cho trọng số cao hơn cho các quan sát gần đây. Không giống trung bình trượt đơn giản nơi mọi điểm trong cửa sổ có trọng số bằng nhau, EMA suy giảm theo hàm mũ:
-
Hệ số làm mượt \(\alpha\) (giữa 0 và 1) kiểm soát tốc độ các quan sát cũ mất ảnh hưởng. \(\alpha\) càng cao nghĩa là nhạy hơn với thay đổi gần đây, \(\alpha\) càng thấp nghĩa là mượt hơn. Trong ML, EMA được dùng trong các bộ tối ưu như Adam và trong các thống kê chạy của chuẩn hóa batch.
-
Phát hiện ngoại lệ (outlier detection) xác định các điểm dữ liệu khác thường xa so với phần còn lại. Hai phương pháp phổ biến:
- Phương pháp IQR: một điểm là ngoại lệ nếu nó nằm dưới \(Q1 - 1.5 \times \text{IQR}\) hoặc trên \(Q3 + 1.5 \times \text{IQR}\)
- Phương pháp Z-score: một điểm là ngoại lệ nếu \(|z| > 3\) (hơn 3 độ lệch chuẩn so với trung bình)
-
Phương pháp IQR mạnh mẽ hơn vì nó không giả định phân bố chuẩn. Phương pháp z-score hoạt động tốt khi dữ liệu xấp xỉ chuẩn nhưng có thể thất bại khi phân bố bị lệch nặng.
Bài tập lập trình (dùng CoLab hoặc notebook)¶
-
Tính phương sai, độ lệch chuẩn, và MAD cho một tập dữ liệu và so sánh chúng. Quan sát điều gì xảy ra khi bạn thêm một ngoại lệ cực đoan.
import jax.numpy as jnp data = jnp.array([4, 8, 6, 5, 3, 7, 9, 5, 6, 7], dtype=jnp.float32) mean = jnp.mean(data) variance = jnp.var(data) std = jnp.std(data) mad = jnp.mean(jnp.abs(data - mean)) print("Original data:") print(f" Variance: {variance:.3f}, Std: {std:.3f}, MAD: {mad:.3f}") # Add an outlier and recompute data_outlier = jnp.append(data, 100.0) mean2 = jnp.mean(data_outlier) print(f"\nWith outlier (100):") print(f" Variance: {jnp.var(data_outlier):.3f}, Std: {jnp.std(data_outlier):.3f}, MAD: {jnp.mean(jnp.abs(data_outlier - mean2)):.3f}") -
Tính tương quan Pearson và Spearman giữa hai biến. Thử nghiệm với các mối quan hệ khác nhau.
import jax import jax.numpy as jnp # Perfect linear relationship x = jnp.array([1, 2, 3, 4, 5, 6, 7, 8], dtype=jnp.float32) y = 2 * x + 1 # try changing this! def pearson(a, b): a_c = a - jnp.mean(a) b_c = b - jnp.mean(b) return jnp.sum(a_c * b_c) / (jnp.sqrt(jnp.sum(a_c**2)) * jnp.sqrt(jnp.sum(b_c**2))) def spearman(a, b): rank_a = jnp.argsort(jnp.argsort(a)).astype(jnp.float32) rank_b = jnp.argsort(jnp.argsort(b)).astype(jnp.float32) return pearson(rank_a, rank_b) print(f"Pearson r: {pearson(x, y):.4f}") print(f"Spearman ρ: {spearman(x, y):.4f}") -
Cài đặt phát hiện ngoại lệ bằng cả phương pháp IQR và z-score, sau đó so sánh kết quả trên dữ liệu lệch.
import jax.numpy as jnp data = jnp.array([2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 50], dtype=jnp.float32) # IQR method q1, q3 = jnp.percentile(data, 25), jnp.percentile(data, 75) iqr = q3 - q1 lower, upper = q1 - 1.5 * iqr, q3 + 1.5 * iqr iqr_outliers = data[(data < lower) | (data > upper)] print(f"IQR bounds: [{lower:.1f}, {upper:.1f}]") print(f"IQR outliers: {iqr_outliers}") # Z-score method z_scores = (data - jnp.mean(data)) / jnp.std(data) z_outliers = data[jnp.abs(z_scores) > 3] print(f"\nZ-scores: {z_scores}") print(f"Z-score outliers (|z| > 3): {z_outliers}") -
Tính toán và vẽ Trung bình trượt hàm mũ với các hệ số làm mượt khác nhau trên dữ liệu nhiễu.
import jax.numpy as jnp import matplotlib.pyplot as plt # Generate noisy data key = __import__("jax").random.PRNGKey(0) noise = __import__("jax").random.normal(key, shape=(50,)) signal = jnp.linspace(0, 5, 50) + noise def ema(data, alpha): result = jnp.zeros_like(data) result = result.at[0].set(data[0]) for t in range(1, len(data)): result = result.at[t].set(alpha * data[t] + (1 - alpha) * result[t - 1]) return result plt.figure(figsize=(10, 4)) plt.plot(signal, "o", alpha=0.3, label="raw data", color="#999") for alpha, color in [(0.1, "#e74c3c"), (0.3, "#3498db"), (0.7, "#27ae60")]: plt.plot(ema(signal, alpha), label=f"α={alpha}", color=color, linewidth=2) plt.legend() plt.title("EMA with different smoothing factors") plt.show()