# TRẠNG THÁI DỰ ÁN EHD S2S — chốt ngày 2026-09-02

Tài liệu này để **quay lại dự án sau một thời gian gián đoạn**. Nó tóm tắt toàn bộ
những gì đã làm, cái gì chạy được, cái gì đã thử và bị bác, và chỗ nào còn mở.
Nhật ký chi tiết theo trình tự thời gian nằm ở `developing.txt` (2500+ dòng);
tài liệu này là bản đồ để đọc file đó, không thay thế nó.

**Đọc theo thứ tự này nếu chỉ có 15 phút:** mục 1 → mục 4 → mục 5 → mục 8.

**Nếu bạn đang làm trên BỘ SỐ LIỆU KHÁC mà cùng bài toán: đọc thẳng mục 11.**
Mục 11 là phần **không phụ thuộc số liệu** — các bài học vẫn đúng khi đổi dữ liệu,
miền, hay mô hình nguồn. Mọi mục còn lại gắn với bộ số liệu ECMWF S2S / Việt Nam
cụ thể của dự án này.

---

## 1. Trạng thái một câu

Hệ dự báo đã **hoàn tất, đóng gói và kiểm chứng end-to-end**. Chỉ **tuần 1 (W1)
đạt trọn bộ chỉ tiêu** đề ra; W2–W6 chạm **trần tín hiệu**, không phải lỗi kỹ thuật,
và chỉ phát hành được dưới dạng trường xác suất. Ba phương án cải tiến gần nhất
(PA2, PA2b, Ope1b) đều tác động vào cùng một trục và **trục đó đã cạn**.

Không có job nào đang chạy. Không có việc nào dở dang.

---

## 2. Bài toán và dữ liệu

- **EHD (ngày nóng cực đoan)**: Tx ≥ `min(Tx90p cục bộ cửa sổ 31 ngày, 35 °C)`.
- **EHDE của một tuần tại một ô lưới** = có **ít nhất một** ngày EHD trong tuần đó.
- **Miền**: 541 ô lưới đất, lưới 0,25°, mask `Mask_VN_S2S_EC_0.25.nc`, 7 vùng khí hậu
  S1–S7 (`Vietnam7.shp`).
- **Mẫu**: 2080 lần khởi tạo = 104 init/năm × 20 năm (2003–2022), mỗi init 46 hạn ngày.
- **Chia tập theo INIT, không theo dòng**: kiểm định = `[2006, 2011, 2016, 2021]`
  (416 init), huấn luyện = 16 năm còn lại (1664 init).
- **Cửa sổ tuần**: W1 = hạn 0–10 ngày (11 ngày), W2 = 11–17, W3 = 18–24, W4 = 25–31,
  W5 = 32–38, W6 = 39–45.
- **Đầu vào**: **CHỈ control forecast** của ECMWF S2S. Không dùng trung bình tổ hợp.

### Hai quy tắc dữ liệu bất di bất dịch
1. **Chỉ control forecast.** Nạp nhầm ensemble mean thì z-score co về 0 và hệ dự báo
   thiếu một cách hệ thống **mà không báo lỗi gì cả**.
2. **Quan trắc CHỈ được làm target, không bao giờ làm đặc trưng.** Kể cả quan trắc
   tại thời điểm khởi tạo (`HISTORY_END_OFFSET = -1`).

---

## 3. Kiến trúc hệ đang chạy (PA1 = OPE1)

Mô hình **gộp toàn quốc** (một bộ cho cả 541 ô) + **ngưỡng riêng từng ô lưới**.
Không phải mạng nơ-ron không gian.

```
đặc trưng (81 cột, gộp từ 46 hạn ngày về cửa sổ tuần)
   │
   ├─ TẦNG 1: 8 họ hồi quy Sev × các mức phân vị → N thành viên bỏ phiếu
   │            p_gate = M/N;  p_gate < p1(ô) ⇒ kết luận nEHDE, DỪNG
   │            p1 chốt riêng từng ô sao cho rò rỉ ngoài mẫu ≤ 5% số sự kiện
   │
   └─ TẦNG 2: 6 họ phân loại (LogReg_L2, LogReg_EN, LGBM_clf, LGBM_clf_slow,
              HistGB_clf, ANN_16) → trung bình xác suất
              so với ngưỡng riêng từng ô = phân vị (1 − r·base_rate(ô))
              r = MỘT giá trị chung cho mỗi cửa sổ (W1: r = 0,84)
```

**Chuẩn hoá**: `ec_z` = dị thường so với khí hậu học **của chính mô hình EC** tại
(biến, hạn, ngày trong năm, ô lưới). Đây là chuẩn hoá **vật lý**, chính nó cho phép
gộp 541 ô + mọi mùa vào một mô hình. Đã phản biện và **giữ nguyên** (không đổi sang
min-max 0–1: sẽ đưa chu kỳ mùa trở lại làm tín hiệu trội).

---

## 4. Kết quả chốt — 416 init kiểm định, 541 ô lưới (225 056 quyết định/cửa sổ)

| | POD | POFD | FAR | FBI | CSI | SEDI | AUC |
|---|---|---|---|---|---|---|---|
| **W1** | **0,652** | **0,102** | **0,198** | 0,814 | **0,562** | 0,724 | 0,871 |
| W2 | 0,580 | 0,205 | 0,455 | 1,065 | 0,391 | 0,521 | 0,766 |
| W3 | 0,480 | 0,205 | 0,505 | 0,971 | 0,322 | 0,399 | 0,702 |
| W4 | 0,475 | 0,228 | 0,533 | 1,018 | 0,308 | 0,358 | 0,695 |
| W5 | 0,474 | 0,238 | 0,546 | 1,042 | 0,302 | 0,341 | 0,677 |
| W6 | 0,454 | 0,238 | 0,555 | 1,019 | 0,290 | 0,315 | 0,662 |

Chỉ tiêu: POD > 0,6 · POFD < 0,2 · FAR < 0,2 · FBI ~ 1 · CSI > 0,4.
**Chỉ W1 đạt.** Ở W2–W6 **không có ngưỡng nào** trong dải r ∈ [0,02; 1,50] cho FAR < 0,2.

**Quy tắc phát hành:** W1 phát bản đồ nhị phân; W2–W6 **chỉ phát trường xác suất**
để người dùng tự chọn ngưỡng theo chi phí bỏ sót / báo động sai của mình.

---

## 5. BỐN PHÁT HIỆN QUAN TRỌNG NHẤT

Nếu quên hết mọi thứ khác thì nhớ bốn điều này.

### 5.1. Bộ chỉ tiêu tự mâu thuẫn ở FBI = 1
Khi FBI = 1 thì a+b = a+c nên b = c, do đó **FAR = 1 − POD chính xác**. Vậy bộ
{POD > 0,6; FAR < 0,2; FBI ~ 1} **tương đương {POD > 0,8; FBI ~ 1}** — tức ngầm đòi
POD > 0,8 chứ không phải 0,6. Mọi lần chạy chốt ngưỡng ở FBI = 1 đều tự khoá mình
vào FAR = 1 − POD và **không đời nào đạt FAR < 0,2**.
**Cách gỡ đã dùng:** bỏ ràng buộc FBI = 1, cho phép dự báo thiếu (FBI 0,68–0,86).

### 5.2. Trần tín hiệu ở W2–W6, tính được bằng số
Để đạt POD > 0,6 kèm FAR < 0,2 ở base rate ~0,30 thì cần **AUC ≈ 0,893**.
AUC thực có ở W2–W6 chỉ **0,66–0,77**. Đây là giới hạn của **thông tin trong dự báo
EC**, không phải của lớp mô hình hay của việc dò ngưỡng.

### 5.3. Quá tán không gian ở hạn dài — VẪN CHƯA CHỮA ĐƯỢC
Mô hình phát trạng thái "cả nước cùng bật" (>95% ô) ở W4–W6 với tần suất
**12,5–14,9%**, trong khi tự nhiên chỉ **0,5%** — **quá phát ~25 lần**.
Ngược lại "cả nước tắt" 44–45% so với 19% tự nhiên.
Mô hình **vẫn có** kỹ năng phân dị không gian thật (AUC trong-init 0,798 ở W1 giảm
còn 0,583 ở W6), nhưng phân bố diện tích thì lệch nặng.
Đã thử hai cách chữa, **cả hai đều bị bác**: xoá được suy biến nhưng làm mất kỹ năng,
W1 mất luôn chỉ tiêu FAR < 0,2.

### 5.4. Gradient kỹ năng Bắc–Nam từ W3 trở đi
SEDI theo vùng:

| Vùng | W1 | W2 | W3 | W4 | W5 | W6 |
|---|---|---|---|---|---|---|
| S1 Tây Bắc | 0,697 | 0,433 | 0,248 | 0,169 | 0,195 | 0,255 |
| S2 Đông Bắc | 0,736 | 0,464 | 0,346 | 0,277 | 0,243 | 0,220 |
| S3 ĐB Bắc Bộ | 0,731 | 0,433 | 0,259 | 0,310 | 0,260 | 0,279 |
| S4 Bắc Trung Bộ | 0,747 | 0,512 | 0,317 | 0,324 | 0,317 | 0,306 |
| S5 Nam Trung Bộ | 0,681 | 0,540 | 0,424 | 0,386 | 0,388 | 0,350 |
| **S6 Tây Nguyên** | 0,739 | **0,613** | **0,552** | **0,483** | **0,493** | **0,440** |
| S7 Nam Bộ | 0,706 | 0,556 | 0,481 | 0,442 | 0,389 | 0,338 |

Ở W1 mọi vùng gần như bằng nhau (536/541 ô có SEDI > 0,5). Từ W3 miền Nam giữ kỹ
năng **gấp đôi** miền Bắc; ở W4 chênh 2,9 lần (S6 0,483 vs S1 0,169).
**Diễn giải vật lý:** miền Nam nằm sâu trong đới nhiệt đới, chịu chi phối của dao
động chậm quy mô lớn (dự báo được ở hạn dài); miền Bắc chịu hoàn lưu ngoại nhiệt đới
(không khí lạnh, rãnh gió tây) vốn mất khả năng dự báo sau ~2 tuần.
**Hệ quả:** nên phát hành hạn dài cho S5/S6/S7 trước; với S1/S2 thì hạn dài gần như
vô giá trị. Số ô có SEDI > 0,5: 536 (W1) → 298 → 123 → 73 → 60 → **21** (W6).

---

## 6. ĐÃ THỬ VÀ BỊ BÁC — đừng làm lại

| # | Phương án | Kết quả | Vì sao |
|---|---|---|---|
| 1 | **Biến ngoài: MJO, ENSO/Niño3.4** (AH2–AH9) | ÂM | Niño3.4 là **nhãn năm trá hình** — cây học thuộc năm. Độ lợi không tăng theo hạn như phải có nếu MJO mang tín hiệu thật. |
| 2 | **Thêm biến quy mô lớn toàn quốc** ngoài EOF H500/T850 | KHÔNG LÀM | Sai *kiểu* thông tin: bài toán thiếu phân dị **không gian**, thêm biến toàn quốc chỉ làm nặng thêm quá tán 5.3. |
| 3 | **Ràng buộc diện tích** để chữa quá tán (2 cách) | BÁC | Xoá được suy biến nhưng mất kỹ năng; W1 mất chỉ tiêu FAR < 0,2. |
| 4 | **Target "≥ k ngày EHD"** thay cho "≥ 1 ngày" | BÁC | Kỹ năng cao hơn nhưng không giải được bài toán đặt ra. |
| 5 | **Chốt r riêng từng vùng** | XẤU ĐI | Kém hơn r chung toàn quốc. |
| 6 | **Mở rộng tầng 1 lên 252 thành viên** | ÂM | Cổng không tốt lên. Ở W2–W6 cổng chỉ đóng được 5,9–13,7% số mẫu ⇒ **không tồn tại khối nEHDE tách bạch** để lấy ra (đây là lý do EXP3 không đi xa được). |
| 7 | **Chốt ngưỡng bằng max-CSI** | SAI PHƯƠNG PHÁP | CSI thiên lệch về phía dự báo thừa; điểm max-CSI của W2–W6 đều nằm ở **biên trên** của lưới r. |
| 8 | **8 họ mô hình khác nhau** để chữa suy biến M/N | KHÔNG CHỮA ĐƯỢC | Suy biến nằm ở tín hiệu, không ở lớp mô hình. |
| 9 | **PA2 — tập con đặc trưng cho từng họ tầng 2** | ÂM | `L_all` (cả 81 cột) là thành viên logistic **tốt nhất ở mọi cửa sổ**; không tập con nào vượt nó ở bất kỳ đâu. Nhóm theo **vật lý không hơn nhóm ngẫu nhiên**. Cắt bớt đặc trưng = mất thông tin. |
| 10 | **PA2b — trọng số ensemble phụ thuộc hạn** | HỖN HỢP, BÁC | +0,029 tổng SEDI nhưng **thua có ý nghĩa ở W5**. |
| 11 | **Ope1b — trộn 50/50 PA1 với PA2b** | DƯƠNG NHƯNG VÔ NGHĨA THỰC TẾ | Xem mục 7. |

### Phát hiện phụ của PA2 — đáng giá hơn chính PA2
Từ **W3 trở đi, MỘT hồi quy logistic L2 trên toàn bộ 81 cột ngang hoặc hơn cả
ensemble 6 họ** (AUC W4: 0,6682 vs 0,6634; W5: 0,6666 vs 0,6597). Lý do: các họ cây
tụt nhanh theo hạn và kéo trung bình xuống (LGBM_clf ở W6 chỉ 0,6260; ANN_16 0,5901).
Cây chỉ thực sự đóng góp ở W1–W2. Chính phát hiện này đẻ ra PA2b rồi Ope1b.

### Vì sao "chọn biến" của Van Straaten KHÔNG chuyển được sang bài toán này
Họ có **260 ứng viên nhiều biến dư thừa và cỡ mẫu nhỏ** ⇒ chọn tham lam tiến giữ lại
2–4 predictor là đáng. Ta có **81 đặc trưng đã chắt lọc và 900 224 hàng huấn luyện**
⇒ ở cỡ mẫu này phạt L2 đã làm xong việc điều hoà, cắt tay thêm chỉ là mất thông tin.
Đây là lý do **cơ chế**, nên nhiều khả năng áp cho cả chọn tham lam tiến, không riêng
các tập con đã thử. Ý tưởng còn chuyển được của bài báo là **hệ số nhân lên `p_raw`**
(mục 10), không phải phần chọn biến.

---

## 7. Ope1b — kết cục của trục "tổ hợp tầng 2"

**Ý tưởng (của người dùng, và nó thắng đề xuất của Claude):** thay vì *chọn* gói
theo từng cửa sổ (dính lỗi chọn-trên-tập-kiểm-định), trộn PA1 với PA2b 50/50 bằng
**một quy tắc a-priori áp đều mọi cửa sổ**. Cài đặt = gán lại trọng số cho chính
6 họ tầng 2 cũ (`operational_train.py --s2-weights`).

Bootstrap **khối năm** (bắt buộc dùng cách này — bootstrap theo init che mất
regression ở W5), dSEDI so với PA1: **W4 +0,013 [+0,007; +0,018]** và
**W6 +0,016 [+0,005; +0,026]** thắng có ý nghĩa; W2/W3/W5 hoà; W1 trùng khít bit.
**Không thua có ý nghĩa ở đâu.**

**Nhưng quy ra quyết định thực** (`src/disagree.py`, 225 056 ô-init/cửa sổ):

| W | số ô KHÁC | % | Ope1b đúng | PA1 đúng | lợi ròng | độ chính xác |
|---|---|---|---|---|---|---|
| W1 | 0 | 0,00 | — | — | trùng khít | +0,00 điểm % |
| W2 | 3 845 | 1,71 | 1 934 | 1 911 | +23 | +0,01 |
| W3 | 4 307 | 1,91 | 2 086 | 2 221 | −135 | −0,06 |
| W4 | 6 103 | 2,71 | 3 424 | 2 679 | +745 | +0,33 |
| W5 | 6 940 | 3,08 | 3 477 | 3 463 | +14 | +0,01 |
| W6 | 6 886 | 3,06 | 4 048 | 2 838 | +1 210 | **+0,54** |

Hai gói giống hệt nhau ở **97–98% số quyết định**. Ở W2/W3/W5 tỉ lệ đúng ~50/50
(**khác nhau ngẫu nhiên**); chỉ W4 (56/44) và W6 (59/41) lệch có hướng.
Trên init thật 2026-08-29: **0 vùng đổi kết luận**, 17/3246 ô đổi quyết định.

**KẾT LUẬN:** độ lợi **là thật** (ba cách đo độc lập cùng hướng) nhưng **nhỏ tới mức
không ai vận hành nhận ra** — ý nghĩa thống kê đến từ cỡ mẫu 225 nghìn, không từ độ
lớn hiệu ứng. **Ope1b CHƯA ĐƯỢC CHỐT**; `outputs/operational/` vẫn là PA1.

**Hệ quả cho hướng đi:** ba lần thử liên tiếp trên cùng trục "tổ hợp tầng 2" (PA2 âm
→ PA2b hỗn hợp → Ope1b +0,5 điểm %) cho độ lợi nhỏ dần và cùng cỡ nhiễu.
**Đó là trần của trục, không phải chưa tìm đúng cấu hình. Đừng tinh chỉnh tầng 2 nữa.**

---

## 8. Bản đồ file — bắt đầu lại từ đâu

### Thư mục
| Đường dẫn | Nội dung |
|---|---|
| `~/Progs/claude/HW/` | thư mục làm việc (KHÔNG phải git repo) |
| `outputs/` → `/work/projects/G09/QG.25.196/claude/outputs` | mọi kết quả (symlink sang /work) |
| `outputs/operational/` | **gói nghiệp vụ PA1 đang phát hành** + `RUNBOOK.md` |
| `outputs/operational_ope1b/` | gói ứng viên Ope1b (1,3 GB) — chưa chốt |
| `outputs/operational_pa2b/` | gói PA2b (1,3 GB) — đã bác, giữ để đối chiếu |
| `outputs/AI_Inp/` | khối memmap đặc trưng + target (9,4 GB) |
| `outputs/AI_Results/` | kết quả thí nghiệm (33 GB) |
| `outputs/Cube/`, `Cli/`, `EOF/` | dữ liệu trung gian: khối EC, khí hậu học, EOF |

### Mã then chốt (50 file trong `src/`, đây là những file thật sự cần)
| File | Việc |
|---|---|
| `ehd_common.py` | hằng số, Grid, mask, VALID_YEARS, WEEKS — **đọc đầu tiên** |
| `ehd_metrics.py` | contingency + POD/FAR/CSI/EDI/SEDI |
| `ai_data.py` | `Store` — truy cập khối memmap |
| `phase1_arch.py` | kiến trúc hai tầng, `p_of()` |
| `operational_train.py` | đóng băng tham số ra gói (`--s2-weights`) |
| `operational_forecast.py` | chạy dự báo từ gói (`--pack`, `--from-ecall`) |
| `final_verify.py` | chấm điểm chính thức |
| `make_forecast_html.py` | bản tin (`--verify-json`, `--pack-label`, `--valid-fcs`) |
| `make_ai_html.py` | báo cáo thí nghiệm |
| `compare_fcs.py` | so hai gói trên **một** init |
| `disagree.py` | so hai gói trên **toàn tập kiểm định**, có phân xử đúng/sai |

### Báo cáo HTML
- `ehd_forecast.html` — bản tin PA1, init 2026-08-29 (**đang phát hành**)
- `ehd_forecast_ope1b.html` — bản tin Ope1b cùng init (đối chiếu)
- `ehd_ai_results.html` — báo cáo thí nghiệm AI
- `ehd_verification.html` — kiểm định EC gốc

---

## 9. Chạy lại thế nào

```bash
# môi trường
source $(conda info --base)/etc/profile.d/conda.sh && conda activate ehd
export LD_LIBRARY_PATH=/home/tanpv/.conda/envs/ehd/lib:$LD_LIBRARY_PATH
export PYTHONPATH=src          # BẮT BUỘC để mở được .joblib (class phải ở cấp module)

# dự báo một init thật (đường thời gian thực)
python src/operational_forecast.py --init 2026-08-29 \
    --from-ecall /home/tanpv/Data/QG.25.196/EC_RT_Proc/Combined/2026/EC_all_2026-08-29.nc \
    --wide-root /home/tanpv/Data/QG.25.196/EC_RT \
    --pack outputs/operational --windows W1 W2 W3 W4 W5 W6 \
    --out outputs/operational/forecast_YYYYMMDD.nc

# chấm điểm lại toàn bộ tập kiểm định
python src/final_verify.py                    # xem submit_finalverify.slurm

# dựng bản tin
python src/make_forecast_html.py --fcs <file.nc> --valid-fcs <valid.nc> \
    --verify-json outputs/AI_Results/final_verify.json \
    --pack-label "outputs/operational/" --init YYYY-MM-DD --out ehd_forecast.html
```

**HPC:** `login.meteo.edu.vn`, SLURM `workq`, 11 node × 20 core. Job nặng nộp qua
SLURM, lệnh cần internet chạy trên login node. Các file `submit_*.slurm` trong thư
mục làm việc là mẫu sẵn cho từng loại việc.

### Ba cái bẫy đã mắc, sẽ mắc lại nếu quên
1. **`/tmp` là node-local.** File job ghi vào `/tmp` sẽ biến mất khỏi login node.
   Ghi vào `outputs/` hoặc `$HOME`.
2. **Bố cục memmap `AI_Inp`: trục BIẾN đứng TRƯỚC trục ô lưới** —
   `reshape(2080, NLT, 3, npt)`. Reshape nhầm **không báo lỗi** mà cho ra số sai
   trông rất hợp lý.
3. **Class phải ở cấp module** thì `.joblib` mới unpickle được; thiếu
   `PYTHONPATH=src` sẽ báo `ModuleNotFoundError: phase1_arch`.

---

## 10. Hướng còn mở

Trục "tổ hợp tầng 2" đã cạn (mục 7). Hai hướng còn chưa đụng tới, xếp theo mức
đáng làm:

1. **Neo vào `p_raw` của chính ECMWF.** Theo Van Straaten và cs. (2023): mạng nơ-ron
   giải thích được **hiệu chỉnh xác suất S2S của chính mô hình động lực bằng một hệ
   số nhân**, thay vì học lại từ đầu. Mạng rất nhỏ (4 nút) thắng mạng sâu ở cỡ mẫu
   này. Hiện tại hệ **chưa hề dùng** xác suất thô của EC làm mốc neo.
2. **Tấn công thẳng chứng quá tán không gian** (mục 5.3). Nó sống sót qua **mọi**
   phương án tầng 2 đã thử. Hai cách chữa bằng ràng buộc diện tích đã bị bác, nhưng
   chưa thử cách nào dùng **chiều thành phần tổ hợp** của EC — vốn là nguồn thông tin
   về độ bất định không gian mà hệ hiện tại vứt bỏ hoàn toàn (chỉ dùng control).

**Lưu ý về hướng 2:** ràng buộc dữ liệu hiện tại là "chỉ control forecast" (mục 2).
Nếu muốn dùng chiều tổ hợp thì đây là **thay đổi ràng buộc nền**, cần quyết định
tường minh chứ không phải một tinh chỉnh.

### Một câu hỏi còn BỎ NGỎ, chưa ai trả lời
Bốn năm kiểm định `[2006, 2011, 2016, 2021]` có base rate tuần **0,400 (W1) / ~0,306
(W2–W6)**, trong khi cả 20 năm là **0,437 / 0,334** — tức **tập kiểm định MÁT HƠN khí
hậu chung**. Van Straaten và cs. nhấn mạnh phải huấn luyện trên **toàn dải `p_raw`**
thì mới học được hiệu chỉnh bền vững, và khuyến nghị chia tập **cân bằng nóng/bình
thường/lạnh** chứ không theo thứ tự thời gian. **Chưa đo được mức lệch này ảnh hưởng
bao nhiêu tới các con số đã báo cáo.** Nếu quay lại dự án, đây là việc rẻ tiền nên
làm sớm — nó ảnh hưởng tới cách đọc MỌI kết quả ở mục 4.


---

## 11. BÀI HỌC CHUYỂN ĐƯỢC SANG BỘ SỐ LIỆU KHÁC

Phần này **không phụ thuộc bộ số liệu**. Nếu làm lại cùng bài toán (dự báo S2S sự
kiện nhị phân dạng "có/không xảy ra trong cửa sổ hạn") trên dữ liệu khác, miền khác,
hay mô hình nguồn khác, thì những điều dưới đây vẫn đúng và **đã trả giá để biết**.

### 11.1. Bẫy toán học trong chính bộ chỉ tiêu — kiểm tra ĐẦU TIÊN
Ở **FBI = 1** thì `a+b = a+c` nên `b = c`, do đó **FAR = 1 − POD chính xác**.
Vậy {POD > 0,6; FAR < 0,2; FBI ~ 1} **tương đương** {POD > 0,8; FBI ~ 1}.
Bất kỳ quy trình nào chốt ngưỡng ở FBI = 1 đều **tự khoá vào FAR = 1 − POD**.
→ Trước khi chạy bất cứ mô hình nào, hãy kiểm tra bộ chỉ tiêu có tự mâu thuẫn không.
→ Cách gỡ: bỏ ràng buộc FBI = 1, cho phép dự báo thiếu (FBI < 1) để đổi độ bắt lấy
   độ chính xác. Quét tỷ lệ phát báo `r` (bội của base rate) thay vì cố định FBI.

### 11.2. Phép tính TRẦN TÍN HIỆU — làm sớm, tiết kiệm hàng tuần
Với base rate đã biết, tính **AUC tối thiểu cần có** để đạt cặp (POD, FAR) mục tiêu.
Ở đây: cần AUC ≈ 0,893 cho POD > 0,6 kèm FAR < 0,2 tại base rate ~0,30; AUC thực có
chỉ 0,66–0,77 ⇒ **không ngưỡng nào đạt được, và không mô hình nào cứu được**.
→ Nếu AUC thực còn xa mức cần, dừng việc dò ngưỡng và đổi *nguồn thông tin*,
   đừng đổi *lớp mô hình*.

### 11.3. Chỉ số đánh giá
- **Bắt buộc có EDI và SEDI** trong mọi bảng. CSI và ETS **phụ thuộc base rate**,
  nên **không so sánh được** giữa các vùng hay giữa các hạn dự báo.
- **Chốt ngưỡng bằng max-CSI là SAI** ở bài toán sự kiện hiếm: CSI thiên lệch về phía
  dự báo thừa. Dấu hiệu nhận biết: điểm max-CSI nằm ở **biên trên** của lưới ngưỡng,
  tức CSI vẫn còn tăng nếu dự báo thừa thêm nữa.

### 11.4. Đơn vị mẫu và cách chia tập
- **Đơn vị mẫu là LẦN KHỞI TẠO**, không phải từng dòng dữ liệu. Chia train/valid
  **theo init**; chia theo dòng sẽ rò rỉ vì các hạn cùng một init tương quan mạnh.
- **Không gộp chung mọi hạn ngày** vào một mô hình. Gộp về **cửa sổ tuần**, target =
  "có ít nhất một ngày sự kiện trong tuần".
- **Ngưỡng phải chốt NGOÀI MẪU.** Dùng chính mô hình đầy đủ sinh xác suất rồi lấy
  phân vị làm ngưỡng ⇒ ngưỡng quá tự tin, vận hành sẽ hỏng. Đây là lỗi đã mắc thật.
- **Bootstrap theo KHỐI NĂM, không theo init.** Bootstrap theo init **che mất** một
  regression có thật (ở đây là W5). Các init trong cùng một năm không độc lập.

### 11.5. Quy tắc dữ liệu
- **Chỉ dùng control forecast** (hoặc: biết rõ mình đang dùng gì). Nạp nhầm trung
  bình tổ hợp thì z-score **co về 0** và hệ dự báo thiếu có hệ thống, **không báo lỗi**.
- **Quan trắc CHỈ làm target, không bao giờ làm đặc trưng** — kể cả quan trắc tại
  thời điểm khởi tạo.
- **Chuẩn hoá bằng khí hậu học của CHÍNH mô hình nguồn** theo (biến, hạn, ngày trong
  năm, ô lưới). Đây là chuẩn hoá *vật lý* và chính nó cho phép gộp nhiều ô lưới +
  nhiều mùa vào một mô hình. **Đừng thay bằng min-max 0–1**: giá trị 0,7 sẽ mang
  nghĩa khác nhau giữa tháng 1 và tháng 6, giữa vùng này và vùng kia ⇒ đưa chu kỳ mùa
  trở lại làm tín hiệu trội.

### 11.6. Về mô hình — cái gì đáng và cái gì không
- **Chọn/cắt bớt đặc trưng KHÔNG đáng khi n lớn.** Ở 900k hàng, phạt L2 đã làm xong
  việc điều hoà; cắt đặc trưng chỉ là mất thông tin. (Bằng chứng ngược từ tài liệu
  tham khảo chỉ áp dụng cho chế độ **mẫu nhỏ + nhiều biến dư thừa**.)
- **Trọng số ensemble nên phụ thuộc HẠN:** cây (LGBM/HistGB) tốt ở hạn ngắn nhưng
  **tụt nhanh theo hạn**; hồi quy logistic giữ được ở hạn dài. Từ một mốc hạn nào đó,
  **một logistic L2 trên toàn bộ đặc trưng ngang hoặc hơn cả ensemble nhiều họ**.
- **Mạng nơ-ron sâu không mua được gì** ở cỡ mẫu này; mạng rất nhỏ (1 lớp ẩn, ~4 nút)
  đã đủ, và thường thua hồi quy có phạt.
- **Cẩn thận biến "chỉ số khí hậu" quy mô năm** (kiểu Niño3.4): mô hình cây sẽ dùng
  nó như một **nhãn năm trá hình** và học thuộc năm. Dấu hiệu kiểm tra: nếu biến mang
  tín hiệu thật thì **độ lợi phải tăng theo hạn dự báo**; không tăng ⇒ đang rò rỉ.
- **Thêm biến quy mô toàn miền không chữa được bài toán thiếu phân dị KHÔNG GIAN.**
  Phải hỏi: mình đang thiếu *kiểu* thông tin nào?

### 11.7. Chẩn đoán phải làm mà dễ quên
- **So phân bố DIỆN TÍCH dự báo với diện tích quan trắc**, không chỉ so điểm số.
  Một mô hình có thể có kỹ năng phân dị không gian **thật** mà vẫn phát "cả miền cùng
  bật" nhiều gấp hàng chục lần tự nhiên. Điểm số tổng hợp **không lộ ra** lỗi này.
- **Đo kỹ năng theo VÙNG và theo HẠN riêng**, đừng chỉ báo số toàn miền. Ở đây nó lộ
  ra gradient Bắc–Nam gấp 2–3 lần, dẫn thẳng tới khuyến nghị phát hành khác nhau
  theo vùng.
- **Gói đã đóng băng phải tái tạo đúng số liệu nghiên cứu đến 3 chữ số.** Nếu lệch,
  chuỗi đóng gói đang làm sai lệch ở đâu đó. Đây là phép thử rẻ và bắt được lỗi thật.
- **Quy độ lợi thống kê ra SỐ QUYẾT ĐỊNH THỰC.** "+0,015 SEDI có ý nghĩa ở p<0,01"
  nghe to, nhưng quy ra có thể chỉ là **+0,5 điểm % độ chính xác** và 0 quyết định
  cấp vùng thay đổi. Với n hàng trăm nghìn, **ý nghĩa thống kê đến từ cỡ mẫu chứ
  không từ độ lớn hiệu ứng**. Luôn báo cáo cả hai.

### 11.8. Dấu hiệu nhận biết "trục này đã cạn"
Ba lần thử liên tiếp trên **cùng một trục** cho độ lợi **nhỏ dần và cùng cỡ nhiễu**
⇒ đó là **trần của trục**, không phải chưa tìm đúng cấu hình. Đổi trục, đừng tinh
chỉnh tiếp. (Ở đây: PA2 âm → PA2b hỗn hợp → Ope1b +0,5 điểm %.)

### 11.9. Ba cái bẫy kỹ thuật trên HPC
1. **`/tmp` là node-local** — file job ghi vào `/tmp` biến mất khỏi login node.
2. **Thứ tự trục trong memmap**: reshape nhầm **không báo lỗi** mà cho ra số sai
   *trông rất hợp lý*. Ghi rõ bố cục trục ở đầu file và kiểm lại bằng một giá trị đã
   biết.
3. **Class phải ở cấp module** thì pickle/joblib mới nạp lại được ở tiến trình khác.
