# Chỉ số Gini (Gini Impurity): Đo độ hỗn tạp từ một trò chơi xác suất


Thuật toán cây phân loại [CART (Classification and Regression Trees)]({{< ref "decision-tree.md" >}}) thực chất là bài toán **Cô Tấm lựa đậu** được tự động hoá, vận hành nhờ sự phối hợp nhịp nhàng giữa hai vai trò: **The Doer** (người thực thi) và **The Tester** (giám khảo đánh giá).

* **Cô Tấm (The Doer — Bộ phân nhánh):** Bắt đầu với một rổ đậu lẫn lộn (tập dữ liệu), nhiệm vụ của Tấm là liên tục đề xuất phương pháp phân loại.
* **Thước đo Gini (The Tester — Giám khảo):** Mỗi khi Tấm chia thử, "máy đo Gini" sẽ quét qua hai rổ mới để định lượng độ hỗn tạp:
  * **$\text{Gini} = 0$:** Rổ **thuần khiết tuyệt đối** (chỉ còn một loại hạt) $\to$ Tấm cất rổ đó đi, nhánh này hoàn tất.
  * **$\text{Gini} > 0$:** Rổ vẫn **hỗn tạp** (còn lẫn nhiều loại hạt) $\to$ Tấm phải tiếp tục tìm tiêu chí để lựa tiếp.

"Doer" thử mọi cách chia khả dĩ, còn "Tester" kiên nhẫn chấm điểm mức độ giảm độ hỗn tạp $\Delta G$ — tức hiệu số giữa độ hỗn tạp của rổ ban đầu trừ đi độ hỗn tạp trung bình của các rổ con sau khi chia ($\Delta G = G_{\text{trước}} - G_{\text{sau}}$). Cách lựa nào mang lại $\Delta G$ lớn nhất (giúp rổ đậu sạch nhanh nhất) sẽ được chốt hạ, và chu trình cứ thế lặp lại cho đến khi các rổ đạt độ thuần khiết mong muốn (hoặc chạm ngưỡng dừng của cây).

Thước đo đứng sau chiếc máy chấm điểm ấy chính là **độ hỗn tạp Gini** (*Gini Impurity*). Bài viết này sẽ đi vào trực giác (intuition) tự nhiên để từng bước xây dựng nên công thức Gini.

<div class="interactive-pane">
<link rel="stylesheet" href="/css/gini-interactive.css?v=2">
<section class="gini-card" id="gini-doer-tester-lab" aria-labelledby="gini-doer-title">
  <div class="gini-head" style="flex-wrap: wrap; gap: 0.75rem;">
    <div>
      <p class="gini-eyebrow">MÔ PHỎNG TRỰC QUAN · DOER VS TESTER</p>
      <h3 id="gini-doer-title">Cô Tấm nhặt đậu & Giám khảo Gini</h3>
    </div>
    <div class="doer-btn-group" role="group" aria-label="3 kịch bản phân chia">
      <button type="button" class="doer-btn" data-scenario="random">1. Lựa vụng</button>
      <button type="button" class="doer-btn" data-scenario="suboptimal">2. Lựa tạm</button>
      <button type="button" class="doer-btn active" data-scenario="optimal">3. Lựa chuẩn</button>
    </div>
  </div>
  
  <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:0.55rem;">
    <span style="font-size:0.8rem; font-weight:600; color:var(--gini-muted);">Kịch bản đề xuất (The Doer):</span>
    <span id="doer-badge-cut" class="gini-badge badge-optimal">Cách lựa 3 (Tối ưu)</span>
  </div>

  <div class="gini-canvas-wrap" style="height: 245px;">
    <canvas id="gini-doer-canvas" role="img" aria-label="Mô phỏng đồ họa hạt đậu rơi từ rổ mẹ xuống hai rổ con theo các quy tắc phân chia khác nhau"></canvas>
  </div>

  <div class="gini-metrics" aria-live="polite" style="margin-top:0.7rem;">
    <div><span>Rổ trái G(L)</span><strong id="doer-left-val">0.000</strong></div>
    <div><span>Rổ phải G(R)</span><strong id="doer-right-val">0.000</strong></div>
    <div><span>Mức giảm tạp ΔG <small style="font-weight:normal; font-size:0.75em; opacity:0.85;">(G_gốc − G_sau)</small></span><strong id="doer-gain-val" style="color:var(--gini-a);">+0.500</strong></div>
  </div>

  <div id="doer-verdict" class="doer-verdict-box">
    <!-- Cập nhật tự động bởi JavaScript -->
  </div>

  <div class="gini-legend" aria-hidden="true" style="margin-top:0.6rem; justify-content:center;">
    <span><i class="class-a"></i>Đậu xanh (Lớp A)</span>
    <span><i class="bean-black"></i>Đậu đen (Lớp B)</span>
  </div>

  <p class="gini-hint">Bấm vào <b>3 nút kịch bản ở trên</b> để xem animation các hạt đậu rơi và "máy đo Gini" chấm điểm độ hỗn tạp.</p>
</section>
<script src="/js/gini-interactive.js?v=2"></script>
</div>

---

## 1. Trực giác cốt lõi: Trò chơi đoán đậu của Cô Tấm

Để đo độ hỗn tạp của một rổ đậu, ta đặt ra trò chơi: **nhắm mắt bốc ngẫu nhiên 1 hạt và đoán tên loại đậu dựa trên tỷ lệ thực tế**. Độ hỗn tạp Gini chính là **xác suất đoán sai**.

### Phiên bản 2 loại đậu ($K=2$)

Xét rổ chỉ trộn lẫn hai loại: **Đậu Đen** (tỷ lệ $p_1$) và **Đậu Xanh** (tỷ lệ $p_2 = 1 - p_1$):

- **Xác suất đoán đúng** (2 ô xanh trên đường chéo chính): $P(\text{Đoán đúng}) = p_1^2 + p_2^2$.
- **Độ hỗn tạp Gini** (xác suất đoán sai — biến cố bù):

$$
I = 1 - (p_1^2 + p_2^2) = p_1 p_2 + p_2 p_1 = 2p_1 p_2.
$$

Nhìn vào bảng tiếp liên $2 \times 2$ ở cột bên phải, **chỉ số Gini chính là tổng xác suất của 2 ô màu cam ngoài đường chéo** (bốc nhầm Đen đoán Xanh: $p_1 p_2$, hoặc bốc Xanh đoán Đen: $p_2 p_1$). Khi rổ càng “thuần khiết” ($p_1 \to 1$ hoặc $p_1 \to 0$), 2 ô sai này co dần về $0$. Cực đại đạt được khi rổ chia đều $p_1 = p_2 = 0{,}5$, khi đó $I_{\max} = 2(0{,}5)(0{,}5) = 0{,}5$.

### Phiên bản 3 loại đậu ($K=3$)

Giả sử rổ đậu có thêm **Đậu Đỏ**: gồm 3 loại Đậu Đen ($p_1$), Đậu Xanh ($p_2$), và Đậu Đỏ ($p_3$), thỏa mãn $p_1 + p_2 + p_3 = 1$.

Lúc này, toàn bộ không gian biến cố mở rộng thành **bảng tiếp liên $3 \times 3$ gồm đúng 9 ô**:

- **3 ô trên đường chéo chính** (người chơi đoán đúng loại hạt):

$$
P(\text{Đoán đúng}) = p_1^2 + p_2^2 + p_3^2.
$$

- **6 ô ngoài đường chéo** (người chơi đoán sai — độ hỗn tạp Gini):

$$
I = 1 - (p_1^2 + p_2^2 + p_3^2) = 2(p_1 p_2 + p_1 p_3 + p_2 p_3) = \sum_{i \neq j} p_i p_j.
$$

6 ô sai sót này phân bổ thành 3 cặp đối xứng qua đường chéo chính:
- Nhầm Đen — Xanh: $p_1 p_2 + p_2 p_1 = 2p_1 p_2$.
- Nhầm Đen — Đỏ: $p_1 p_3 + p_3 p_1 = 2p_1 p_3$.
- Nhầm Xanh — Đỏ: $p_2 p_3 + p_3 p_2 = 2p_2 p_3$.

Khi cả 3 loại hạt chia đều tỷ lệ ($p_1 = p_2 = p_3 = \frac{1}{3}$), độ hỗn tạp đạt cực đại:

$$
I_{\max} = 1 - 3 \times \left(\frac{1}{3}\right)^2 = 1 - \frac{1}{3} = \frac{2}{3} \approx 0{,}667.
$$

<div class="interactive-pane">
<section class="gini-card" id="gini-contingency-lab" aria-labelledby="ct-title">
  <div class="gini-head" style="flex-wrap: wrap; gap: 0.6rem;">
    <div>
      <p class="gini-eyebrow" id="ct-title" style="font-size: 0.8rem; margin: 0;">BẢNG TIẾP LIÊN (2×2 CONTINGENCY TABLE)</p>
    </div>
    <div class="doer-btn-group" role="group" aria-label="Tỷ lệ mẫu thử nghiệm">
      <button type="button" class="ct-preset-btn active" data-p1="0.5">50 : 50</button>
      <button type="button" class="ct-preset-btn" data-p1="0.8">80 : 20</button>
      <button type="button" class="ct-preset-btn" data-p1="1.0">100 : 0</button>
    </div>
  </div>
  <label class="gini-control" for="ct-p1-slider">
    <div style="display: flex; justify-content: space-between; align-items: center; font-size: 0.78rem;">
      <span>Đậu Đen (p₁): <strong id="ct-p1-label">50% (0.50)</strong></span>
      <span>Đậu Xanh (p₂): <strong id="ct-p2-label">50% (0.50)</strong></span>
    </div>
    <input type="range" id="ct-p1-slider" min="0" max="1" step="0.01" value="0.5">
  </label>
  <div class="ct-table-wrap">
    <table class="ct-table">
      <thead>
        <tr>
          <th class="ct-th-corner"></th>
          <th class="ct-th-col">
            <div class="ct-th-header"><i class="bean-black"></i> Đoán Đen</div>
            <div class="ct-th-prob">Xác suất p₁ = <span class="ct-p1-disp">0.50</span></div>
          </th>
          <th class="ct-th-col">
            <div class="ct-th-header"><i class="class-a"></i> Đoán Xanh</div>
            <div class="ct-th-prob">Xác suất p₂ = <span class="ct-p2-disp">0.50</span></div>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th class="ct-th-row">
            <div class="ct-th-header"><i class="bean-black"></i> Bốc Đen</div>
            <div class="ct-th-prob">Tỷ lệ p₁ = <span class="ct-p1-disp">0.50</span></div>
          </th>
          <td class="ct-cell ct-cell-correct" id="ct-cell-11">
            <div class="ct-cell-top"><span class="ct-badge ct-badge-correct">✅ Đoán đúng</span></div>
            <div class="ct-cell-formula">p₁ × p₁ = p₁²</div>
            <div class="ct-cell-val" id="ct-val-11">0.250</div>
          </td>
          <td class="ct-cell ct-cell-error" id="ct-cell-12">
            <div class="ct-cell-top"><span class="ct-badge ct-badge-error">❌ Đoán sai · Gini ①</span></div>
            <div class="ct-cell-formula">p₁ × p₂</div>
            <div class="ct-cell-val ct-val-error" id="ct-val-12">0.250</div>
          </td>
        </tr>
        <tr>
          <th class="ct-th-row">
            <div class="ct-th-header"><i class="class-a"></i> Bốc Xanh</div>
            <div class="ct-th-prob">Tỷ lệ p₂ = <span class="ct-p2-disp">0.50</span></div>
          </th>
          <td class="ct-cell ct-cell-error" id="ct-cell-21">
            <div class="ct-cell-top"><span class="ct-badge ct-badge-error">❌ Đoán sai · Gini ②</span></div>
            <div class="ct-cell-formula">p₂ × p₁</div>
            <div class="ct-cell-val ct-val-error" id="ct-val-21">0.250</div>
          </td>
          <td class="ct-cell ct-cell-correct" id="ct-cell-22">
            <div class="ct-cell-top"><span class="ct-badge ct-badge-correct">✅ Đoán đúng</span></div>
            <div class="ct-cell-formula">p₂ × p₂ = p₂²</div>
            <div class="ct-cell-val" id="ct-val-22">0.250</div>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
  <div class="gini-metrics" aria-live="polite" style="margin-top: 0.75rem;">
    <div style="border-left: 3.5px solid var(--gini-a);">
      <span>Xác suất đoán đúng (Đường chéo)</span>
      <strong id="ct-sum-correct" style="color: var(--gini-a); font-size: 1.2rem;">0.500</strong>
    </div>
    <div style="border-left: 3.5px solid var(--gini-b);">
      <span>Độ hỗn tạp Gini (2 ô đoán sai)</span>
      <strong id="ct-sum-gini" style="color: var(--gini-b); font-size: 1.2rem;">0.500</strong>
    </div>
  </div>
</section>
<p class="gini-caption"><i><b>Bảng 1.</b> Bảng tiếp liên 2×2 phân rã trò chơi bốc đậu ngẫu nhiên. Chỉ số Gini bằng đúng tổng 2 ô ngoài đường chéo chính (bốc nhầm đậu).</i></p>
</div>

---

## 2. Công thức tổng quát cho bài toán $K$ lớp

Mở rộng từ ma trận tiếp liên cho $K$ lớp với tỷ lệ $(p_1, \ldots, p_K)$ thỏa mãn $\sum_{k=1}^K p_k = 1$, tổng xác suất đoán đúng trên đường chéo chính là $\sum_{k=1}^K p_k^2$. Độ hỗn tạp Gini chính là phần bù — tổng xác suất đoán sai ở các ô ngoài đường chéo:

$$
G(t) = 1 - \sum_{k=1}^K p_k^2 = \sum_{k=1}^K p_k(1 - p_k) = \sum_{i \neq j} p_i p_j.
$$

Nói cách khác, **Gini chính là xác suất để hai phần tử rút ngẫu nhiên độc lập (có hoàn lại) từ nút $t$ mang hai nhãn khác nhau**. Nút càng gần trạng thái thuần khiết (pure node), xác suất rút trúng hai nhãn khác nhau càng tiệm cận về $0$.

### Giá trị cực đại của Gini theo số lớp $K$

Khi toàn bộ $K$ lớp xuất hiện với tỷ lệ đồng đều chằn chặn ($p_k = \frac{1}{K}, \forall k$), độ bất định đạt đỉnh:

$$
G_{\max} = 1 - \sum_{k=1}^K \left(\frac{1}{K}\right)^2 = 1 - K \cdot \frac{1}{K^2} = 1 - \frac{1}{K} = \frac{K - 1}{K}.
$$

- Với $K = 2$: $G_{\max} = \frac{1}{2} = 0{,}500$.
- Với $K = 3$: $G_{\max} = \frac{2}{3} \approx 0{,}667$.
- Khi $K \to \infty$: $G_{\max} \to 1$.

### Ba yêu cầu chuẩn mực của một thước đo độ hỗn tạp

Một hàm đo độ hỗn tạp $I(t) = f(p_1, \ldots, p_K)$ hợp lý trong cây quyết định cần đáp ứng ba yêu cầu chuẩn mực:

1. **Thuần khiết tuyệt đối (Độ hỗn tạp bằng 0):** Nếu nút chỉ chứa duy nhất một lớp (tồn tại một lớp $k$ có $p_k = 1$ và mọi $p_{j \neq k} = 0$), không còn bất kỳ sự mơ hồ nào về nhãn, độ hỗn tạp phải đạt cực tiểu: $I(t) = 0$.
2. **Hỗn tạp cực đại:** Nếu tất cả các lớp xuất hiện với tỷ lệ đồng đều chằn chặn ($p_1 = p_2 = \cdots = p_K = \frac{1}{K}$), độ hỗn tạp đạt mức cao nhất, $I(t)$ phải đạt giá trị cực đại $G_{\max} = \frac{K - 1}{K}$.
3. **Tính đối xứng:** Thứ tự đánh chỉ số các lớp không làm thay đổi bản chất của độ hỗn tạp: $f(\ldots, p_i, \ldots, p_j, \ldots) = f(\ldots, p_j, \ldots, p_i, \ldots)$.

Công thức Gini $G(t) = 1 - \sum_{k=1}^K p_k^2$ bắt nguồn từ trò chơi xác suất tự nhiên này thỏa mãn trọn vẹn cả ba điều kiện tiên đề nêu trên mà không cần bất kỳ giả định khiên cưỡng nào.

---

## 3. Trường hợp hai lớp ($K=2$) & Đồ thị Parabol

Xét bài toán phân loại nhị phân phổ biến với hai lớp $A$ và $B$. Đặt tỷ lệ lớp $A$ là $p$, khi đó tỷ lệ lớp $B$ là $1 - p$. Công thức Gini trở thành:

$$
G(p) = 1 - p^2 - (1 - p)^2 = 2p(1 - p).
$$

Khảo sát hàm số $G(p) = 2p - 2p^2$ trên đoạn $[0, 1]$:

- Tại $p = 0$ (100% lớp B) hoặc $p = 1$ (100% lớp A): $G(0) = G(1) = 0$.
- Đạo hàm bậc nhất: $G'(p) = 2 - 4p = 0 \iff p = 0{,}5$.
- Giá trị cực đại: $G(0{,}5) = 2(0{,}5)(0{,}5) = 0{,}5$.
- Đạo hàm bậc hai: $G''(p) = -4 < 0$, chứng minh $G(p)$ là một **hàm lõm nghiêm ngặt** (*strictly concave*).

Theo [**Bất đẳng thức Jensen**]({{< ref "/posts/math/analysis/jensen-inequality.md" >}}), tính lõm nghiêm ngặt đảm bảo rằng độ hỗn tạp của phân phối gộp không bao giờ nhỏ hơn trung bình có trọng số của các phân phối thành phần: $G(\sum w_j p_j) \ge \sum w_j G(p_j)$. Đây là đặc tính toán học cốt lõi bảo đảm rằng việc phân chia dữ liệu thành các nhóm con thuần hơn sẽ không bao giờ làm tăng độ hỗn tạp kỳ vọng.

<div class="interactive-pane">
<link rel="stylesheet" href="/css/gini-interactive.css?v=1">
<section class="gini-card" id="gini-curve-lab" aria-labelledby="gini-curve-title">
  <div class="gini-head">
    <div>
      <p class="gini-eyebrow">THÍ NGHIỆM 1 · TRỰC QUAN XÁC SUẤT</p>
      <h3 id="gini-curve-title">Hộp bi xác suất và đồ thị độ hỗn tạp</h3>
    </div>
    <button type="button" class="gini-button" data-action="sim-guess">Bốc thử 100 lần</button>
  </div>
  <label class="gini-control" for="gini-p-slider">
    <span>Tỷ lệ lớp A (p) <output id="gini-p-value" for="gini-p-slider">50% (0.50)</output></span>
    <input type="range" id="gini-p-slider" min="0" max="1" step="0.01" value="0.5">
  </label>
  <div class="gini-metrics" aria-live="polite">
    <div><span>Gini Impurity G(p)</span><strong id="gini-val">0.500</strong></div>
    <div><span>Xác suất cùng màu</span><strong id="gini-same-val">50.0%</strong></div>
    <div><span>Entropy H(p)</span><strong id="gini-entropy-val">1.000</strong></div>
    <div><span>Sai số đa số E(p)</span><strong id="gini-error-val">50.0%</strong></div>
  </div>
  <div class="gini-canvas-wrap">
    <canvas id="gini-curve-canvas" role="img" aria-label="Mô phỏng hộp bi và đồ thị so sánh Gini, Entropy và Sai số phân loại"></canvas>
  </div>
  <div class="gini-legend" aria-hidden="true">
    <span><i class="class-a"></i>Lớp A (xanh)</span>
    <span><i class="class-b"></i>Lớp B (cam)</span>
    <span><i class="curve-gini"></i>Gini 2p(1-p)</span>
    <span><i class="curve-entropy"></i>Entropy H(p)/2</span>
    <span><i class="curve-error"></i>Sai số 1-max(p,1-p)</span>
  </div>
  <p class="gini-hint">Kéo thanh trượt để đổi tỷ lệ hai lớp. Bấm "Bốc thử 100 lần" để kiểm chứng tần suất phân loại sai thực nghiệm tiến sát công thức $G(p)$.</p>
</section>
<p class="gini-caption"><i><b>Hình 1.</b> Bên trái là 36 quả bi trong hộp theo tỷ lệ $p$; bên phải là đường cong parabol đối xứng của chỉ số Gini so với Entropy và Sai số phân loại.</i></p>
</div>

> **Gini vs. Sai số phân loại (Misclassification Error):**  
> Dù cùng đo độ hỗn tạp của nút nhị phân (với tỷ lệ lớp đa số $p$), chúng đảm nhận hai vai trò hoàn toàn khác nhau:
> - **Sai số phân loại ($E = 1 - p$):** Dùng để đánh giá độ chính xác hoặc cắt tỉa cành (pruning), nhưng ít nhạy cảm với sự thay đổi xác suất nên hiếm khi dùng để chọn điểm chia.
> - **Chỉ số Gini ($G = 2p(1 - p)$):** Đo độ phân tán và giảm rất nhanh khi nút thuần hơn. Độ nhạy này biến Gini thành tiêu chí mặc định để **quyết định chia nhánh** (splitting).
>
> Về mặt toán học, Gini luôn chặn trên sai số phân loại ($G \ge E$), và cả hai cùng bằng $0$ khi nút đạt độ thuần khiết tuyệt đối ($p = 0$ hoặc $p = 1$).

*(Để đối chiếu chi tiết giữa ba thước đo độ hỗn tạp thông dụng và xem chứng minh toán học của bất đẳng thức chặn trên $E(t) \le G(t)$, bạn có thể đọc bài viết riêng: [So sánh ba thước đo độ hỗn tạp: Gini, Entropy và Sai số phân loại]({{< ref "gini-entropy-misclassification-error.md" >}}).)*

---

## 4. Tóm tắt

| Khái niệm | Ý nghĩa cốt lõi |
| :--- | :--- |
| **Bản chất xác suất** | Xác suất phân loại sai khi rút ngẫu nhiên một quan sát và gán nhãn ngẫu nhiên theo phân phối của nút: $G(t) = 1 - \sum p_k^2$. |
| **Dạng hai lớp** | Parabol úp đối xứng: $G(p) = 2p(1-p)$, cực đại tại $p = 0{,}5$ với giá trị $0{,}5$. |
| **Tính lõm & Jensen** | $G''(p) < 0$, bảo đảm việc phân chia dữ liệu thành các nhóm con không bao giờ làm tăng độ hỗn tạp kỳ vọng. |
| **Chặn trên sai số** | Luôn chặn trên sai số đa số: $E(t) \le G(t)$, cả hai cùng triệt tiêu về $0$ tại nút thuần khiết (pure node). |
| **Ưu thế trong CART** | Nhạy hơn sai số phân loại đa số ở hai biên và tính toán nhanh hơn Entropy vì tránh được hàm logarit. |

Độ hỗn tạp Gini đóng vai trò là tiêu chí định lượng đơn giản để đánh giá chất lượng phân tách tại mỗi nút. Dựa trên tiêu chí này, thuật toán liên tục phân chia không gian đặc trưng để xây dựng [Cây quyết định (Decision Tree)]({{< ref "decision-tree.md" >}}), đồng thời làm cơ sở cho các mô hình kết hợp như [Random Forest]({{< ref "random-forest.md" >}}).

---

### Tài liệu tham khảo

- Leo Breiman, Jerome H. Friedman, Richard A. Olshen, Charles J. Stone (1984), [*Classification and Regression Trees*](https://www.routledge.com/Classification-and-Regression-Trees/Breiman-Friedman-Stone-Olshen/p/book/9780412048418), Wadsworth & Brooks/Cole Advanced Books & Software.
- Trevor Hastie, Robert Tibshirani, Jerome Friedman (2009), [*The Elements of Statistical Learning: Data Mining, Inference, and Prediction*](https://hastie.su.domains/ElemStatLearn/), 2nd Edition, Springer (Chương 9.2: Tree-Based Methods).

