Danh mục Biến của Mô hình Dự báo

Từng biến mô hình chốt chronos2_mv_cross đang đọc: chuỗi đầu vào của Chronos-2, 50 biến lịch sử, 28 biến ngoại sinh, 3 hệ số hậu chỉnh và các biến dùng cho dự báo 12 tháng.

1.0 (Draft) ✓ Đã chốt giải pháp & mô hình dự báo

Trang này liệt kê đúng những biến mà mã nguồn đang đọc khi sinh bộ số chốt (forecast_pipeline/src/forecast_pipeline/forecast/yearly_3grains.py). Danh sách 50 biến lịch sử được lấy bằng cách chạy chính hàm features.feature_cols trên khung dữ liệu thật ngày 26/10/2026, không chép tay.

Cách đọc ký hiệu tháng. Tháng cần dự báo là $t$. Hậu tố _l0 nghĩa là giá trị của tháng $t-1$ (tháng gần nhất đã đóng sổ), _l1 là tháng $t-2$, _l11 là tháng $t-12$ (cùng kỳ năm trước). Mọi biến có hậu tố _l… đều là thông tin đã biết tại thời điểm dự báo.

1. Tổng quan các tầng biến

TầngSố biếnDùng choNguồn
Nhãn và khoá chuỗi5Thứ cần dự báo và cách định danh một chuỗiLịch sử đơn hàng
Chuỗi đầu vào của Chronos-24 chuỗi × 6 thángDự báo nền tháng M+1Lịch sử đơn hàng theo tháng và theo ngày
Biến lịch sử của tầng cây46 số + 4 phân loại (+1 khi tách kênh)Học phần sai của dự báo nềnTự tính từ lịch sử
Biến ngoại sinh28Học phần sai của dự báo nềnTự tính từ đơn ngày, panel và lịch CTKM
Hệ số hậu chỉnh3Nắn lại sau cùngTự tính từ biến ngoại sinh
Biến của dự báo 12 tháng4Kéo dài từ M+2 tới M+12Tự tính từ lịch sử

Công thức tổng của tháng M+1 (chi tiết toán học ở trang Kiến trúc Thuật toán & Mô hình Dự báo):

$$\hat{y} = \hat{y}_{\text{Chronos-2}} \times \exp\big(0{,}35 \cdot r(X)\big) \times \text{stuffing\_adj} \times \text{breadth\_adj} \times \text{promo\_adj}$$

trong đó $r(X) = 0{,}55 \cdot \text{LightGBM}(X) + 0{,}45 \cdot \text{CatBoost}(X)$, chặn trong $[-0{,}30;\ 0{,}30]$, và $X$ là 78–79 biến ở mục 4 và mục 5.


2. Nhãn và khoá chuỗi

Tên trườngÝ nghĩaGhi chú
sales_qty_cartonSản lượng theo thùng — con số được dự báoỞ khung chuỗi, cột này lấy từ cột thung của tệp lịch sử. Gồm cả hàng tặng (FOC), chưa trừ đơn huỷ
store_keyKhoá nhóm của chuỗiTuỳ cấp hạt: mã kho, mã kho con hoặc mã chuỗi. Tên cột giữ là store_key để dùng chung mã với hạt cửa hàng
product_codeMã hàng gốcMã mới TMICC đã được nối về mã cũ (26 mã). Tổng 473 mã gốc
tChỉ số tháng liên tục, năm × 12 + thángDùng để tính độ trễ, không hiển thị
t_firstTháng đầu tiên chuỗi có bánChuỗi chỉ được huấn luyện và dự báo khi t ≥ t_first + 1

Cửa sổ huấn luyện của tầng cây chỉ lấy các tháng từ 01/2026 (REGIME_SWITCH = 202601) — mốc đổi quy ước ghi nhận hàng tặng và chiết khấu.


3. Bốn chuỗi đầu vào của Chronos-2

Chronos-2 (120M tham số) nhận mỗi chuỗi dưới dạng 4 dòng × 6 tháng gần nhất (thung_l5 … thung_l0).

ChuỗiÝ nghĩaCách tính
y_rateTốc độ bán trên một ngày giao dịch hiệu dụngthung_lk / W(tháng), với $W$ là trọng số ngày giao dịch ở mục 7
h1_rateTốc độ bán nửa đầu tháng (ngày 1–15)Từ đơn theo ngày, theo mã hàng, chia cho trọng số ngày giao dịch của nửa đầu tháng
h2_rateTốc độ bán nửa cuối tháng (ngày 16–31)Như trên, cho nửa cuối tháng
peer_rateTốc độ bán đồng hành của cùng mã hàng trên toàn quốc (hoặc của ngành hàng)Giúp chuỗi nhỏ mượn tín hiệu xu hướng của chuỗi lớn

Trước Chronos-2, lõi mùa vụ hai chế độ (frontier._dual_regime_core) dựng mức nền từ chính các độ trễ này cùng tỷ số cùng kỳ năm trước (thung_l11) và tỷ lệ ngày hết hàng theo mã hàng (stockout_days / stock_tracked_days của panel).


4. Biến lịch sử của tầng cây — 50 biến

Sinh bởi model_lab/src/model_lab/data/features.py (build_features, feature_cols). Ở các bảng dưới, “nhóm” là đơn vị của chuỗi (kho, kho con hoặc chuỗi) tuỳ cấp hạt.

4.1. Sản lượng trễ của chính chuỗi — 14 biến

Tên trườngÝ nghĩa
thung_l0, thung_l1, thung_l2, thung_l3, thung_l4, thung_l5Sản lượng (thùng) của chuỗi ở tháng $t-1$ … $t-6$
thung_l11Sản lượng cùng kỳ năm trước ($t-12$)
donvi_l0 … donvi_l5, donvi_l11Sản lượng theo đơn vị gốc ở cùng các tháng. Ở khung chuỗi, giá trị trùng với thung_l… vì khung chỉ có cột thùng — giữ để dùng chung mã với hạt cửa hàng

Tháng không có dòng (nhóm không mua) được điền 0. Tháng nằm trong danh sách loại trừ EXCLUDED_MONTHS để trống — hiện danh sách này rỗng.

4.2. Bối cảnh của nhóm và của mã hàng — 12 biến

Tên trườngÝ nghĩa
ch_thung_l0, ch_thung_l1, ch_thung_l2Tổng thùng của cả nhóm (mọi mã hàng) ở $t-1$, $t-2$, $t-3$
ch_so_sku_l0, ch_so_sku_l1, ch_so_sku_l2Số mã hàng có bán trong nhóm
ma_thung_l0, ma_thung_l1, ma_thung_l2Tổng thùng của mã hàng trên mọi nhóm
ma_so_ch_l0, ma_so_ch_l1, ma_so_ch_l2Số nhóm có bán mã hàng

4.3. Biến dẫn xuất từ sản lượng trễ — 13 biến

Tên trườngÝ nghĩaCông thức
tb3Trung bình 3 thángmean(thung_l0..l2)
tb6Trung bình 6 thángmean(thung_l0..l5)
trung_vi3Trung vị 3 thángmedian(thung_l0..l2)
do_lech6Độ lệch chuẩn 6 thángstd(thung_l0..l5)
so_thang_co_mua_6Số tháng có bán trong 6 thángĐếm thung_lk > 0
so_thang_do_duoc_6Số tháng đo được trong 6 thángĐếm thung_lk không trống
xu_huongChênh lệch tháng gần nhấtthung_l0 − thung_l1
thang_tu_lan_mua_cuoiSố tháng kể từ lần bán gần nhất0 nếu $t-1$ có bán; 6 nếu cả 6 tháng không bán
adiKhoảng cách trung bình giữa hai lần muaso_thang_do_duoc_6 / so_thang_co_mua_6
cvHệ số biến độngdo_lech6 / tb6
ty_trong_trong_chTỷ trọng của mã trong nhómthung_l0 / ch_thung_l0
ty_trong_trong_maTỷ trọng của nhóm trong mãthung_l0 / ma_thung_l0
nhip_ma_hangNhịp tăng của mã hàng toàn quốcma_thung_l0 / ma_thung_l1

4.4. Lịch và thuộc tính mã hàng — 7 biến số, 4–5 biến phân loại

Tên trườngLoạiÝ nghĩaLấy ở tháng nào
calendar_daysSốSố ngày trong thángTháng đích $t$ — biết trước
working_daysSốSố ngày không phải thứ Bảy, Chủ nhậtTháng đích. Chưa trừ ngày lễ
weekend_daysSốSố ngày thứ Bảy, Chủ nhậtTháng đích
thang_trong_namSốTháng 1–12Tháng đích
shelf_lifeSốHạn sử dụng của mã hàngThuộc tính tĩnh
net_weightSốKhối lượng tịnhThuộc tính tĩnh
qty_per_cartonSốSố đơn vị trong một thùngThuộc tính tĩnh
brand_idPhân loạiThương hiệuThuộc tính tĩnh
category_idPhân loạiNgành hàngThuộc tính tĩnh
supplier_idPhân loạiNhà cung cấpThuộc tính tĩnh
uomPhân loạiĐơn vị tínhThuộc tính tĩnh
kenh_l1Phân loạiKênh cấp 1Chỉ có khi chuỗi được tách theo kênh

Biến phân loại được mã hoá thành số nguyên theo tần suất: giữ 250 giá trị hay gặp nhất, phần còn lại (kể cả giá trị mới chưa từng gặp) gộp vào một mã chung.


5. 28 biến ngoại sinh

Sinh bởi build_exogenous_tables và attach_multivariate_features trong yearly_3grains.py. Mọi biến đều lấy ở tháng $t-1$ (riêng các biến tăng trưởng so sánh $t-1$ với $t-2$). Cột “Khi trống” là giá trị thay cho ô trống của dữ liệu gốc trước khi tính; dấu “—” nghĩa là để trống, và khi đưa vào cây mọi ô trống còn lại đều thành 0.

Ba nguồn của nhóm này:

  • Đơn theo ngày (daily_all_*.parquet) gộp theo mã hàng và tháng, ở hai mức: toàn quốc (tiền tố sku_) và theo nhóm của chuỗi (tiền tố grp_). Ở hạt cửa hàng, biến grp_ lấy bằng biến sku_.
  • Panel cửa hàng × mã hàng × tháng (panel_all_*.parquet) gộp theo mã hàng toàn quốc.
  • Lịch CTKM (trade_promotions_full.parquet, chỉ dòng promotion_status = 'HIEU_LUC'), trải theo từng tháng nằm trong khoảng promotion_start_year_month … promotion_end_year_month (tháng của cửa sổ áp dụng cho người tiêu dùng).

5.1. Độ phủ điểm bán và nhịp đơn trong tháng — 13 biến

#Tên trườngÝ nghĩaCông thứcKhi trống
1grp_nstores_l0Số cửa hàng có đơn của mã trong nhómĐếm store_code khác nhau—
2grp_odays_l0Số ngày có đơn của mã trong nhómĐếm ngày khác nhau—
3grp_h1_share_l0Tỷ trọng bán nửa đầu thángthùng ngày 1–15 / (tổng + 10)—
4grp_last7_share_l0Tỷ trọng bán cuối thángthùng từ ngày 24 / (tổng + 10)—
5grp_cps_l0Thùng trên một cửa hàngtổng thùng / max(số cửa hàng, 1)—
6sku_nstores_l0Như #1, toàn quốc—
7sku_odays_l0Như #2, toàn quốc—
8sku_h1_share_l0Như #3, toàn quốc—
9sku_last7_share_l0Như #4, toàn quốc—
10mv_grp_store_growthTăng trưởng số cửa hàng của nhóm(grp_nstores_l0 + 2) / (grp_nstores_l1 + 2)0
11mv_sku_store_growthTăng trưởng số cửa hàng toàn quốc(sku_nstores_l0 + 5) / (sku_nstores_l1 + 5)0
12mv_grp_last7_spikeMức dồn đơn cuối tháng tăng thêmgrp_last7_share_l0 − grp_last7_share_l10,25
13mv_sku_last7_spikeNhư #12, toàn quốc0,25

“Cuối tháng” ở biến #4 tính từ ngày 24, nên dài 5–8 ngày tuỳ tháng chứ không cố định 7 ngày.

5.2. Giá, chiết khấu, hàng tặng và khuyến mãi — 8 biến

#Tên trườngÝ nghĩaCông thứcKhi trống
14sku_disc_l0Tỷ lệ chiết khấu bình quânmean(discount_rate)0
15sku_promo_app_l0Tỷ lệ dòng đơn có áp CTKMmean(promo_applied_ratio)0
16sku_foc_l0Tỷ lệ dòng hàng tặngΣ so_dong_foc / (Σ order_count + 1)—
17mv_disc_delta_l0Chiết khấu tăng hay giảmsku_disc_l0 − sku_disc_l10
18mv_price_mom_l0Doanh thu trên thùng tăng hay giảm(rpc_l0 + 1000) / (rpc_l1 + 1000), với rpc = Σ net_revenue / (Σ sales_qty_carton + 1)300.000
19tp_count_l0Số dòng CTKM hiệu lực trong thángĐếm dòng CTKM. Hạt chuỗi: theo chuỗi × mã; hạt khác: theo mã toàn quốc—
20tp_max_disc_l0Mức giảm sâu nhấtmax(promotion_discount_pct)0
21tp_days_l0Số ngày chạy dài nhấtmax(promotion_days)15

Ở hạt chuỗi, CTKM được khớp theo chain_code của tệp CTKM với store_brand_code của cửa hàng; dòng CTKM không ghi chuỗi được gán ALL_MT. Hai bộ mã chuỗi này không hoàn toàn trùng nhau, nên một phần CTKM không gắn được vào chuỗi nào.

5.3. Tồn kho, viếng thăm, tủ đông, thời tiết và nhịp sản lượng — 7 biến

#Tên trườngÝ nghĩaCông thứcKhi trống
22sku_oos_l0Tỷ lệ ngày hết hàngΣ stockout_days / (Σ stock_tracked_days + 1)—
23sku_visit_l0Tỷ lệ tuân thủ tuyến viếng thămmean(visit_compliance_rate)0
24sku_freezer_l0Số tủ đông bình quân tại điểm bánmean(freezer_count)1
25sku_tmax_l0Nhiệt độ cao nhất bình quânmean(avg_tmax)30
26sku_rain_l0Số ngày mưa bình quânmean(rain_days)10
27mv_l0_to_tb3Tháng gần nhất so với trung bình 3 tháng(thung_l0 + 1) / (tb3 + 1)0
28mv_yoy_to_l0Cùng kỳ năm trước so với tháng gần nhất(thung_l11 + 5) / (thung_l0 + 5)0

Ba điểm cần biết khi đọc nhóm biến ngoại sinh:

  1. Khuyến mãi chỉ có ở tháng trước. Các biến tp_…_l0 mô tả CTKM của tháng $t-1$. Lịch CTKM của chính tháng đang dự báo chưa đi vào mô hình.
  2. Thời tiết cũng là của tháng trước. sku_tmax_l0, sku_rain_l0 là thời tiết tháng $t-1$, không phải dự báo thời tiết của tháng $t$.
  3. sku_rpc_l0 không phải biến của mô hình. Nó chỉ là số trung gian để tính mv_price_mom_l0.

6. Ba hệ số hậu chỉnh

Áp sau khi đã có kết quả của tầng cây.

Hệ sốÝ nghĩaCông thứcTrạng thái
stuffing_adjKhử đỉnh dồn đơn cuối thángNếu mv_grp_last7_spike > 0,08 thì clip(1 − 0,35 × (spike − 0,05); 0,82; 1,0), ngược lại bằng 1Đang tác động
breadth_adjĐiều chỉnh theo độ phủ điểm bánclip(mv_grp_store_growth ^ 0,15; 0,90; 1,10)Đang tác động
promo_adjĐiều chỉnh theo thay đổi CTKM ở tháng đíchclip(1 + 0,0025 × mv_tp_disc_delta_t; 0,94; 1,08)Luôn bằng 1. Biến mv_tp_disc_delta_t chưa được tạo ở bất kỳ đâu trong mã. Đây là chỗ để nối lịch CTKM tương lai khi có dữ liệu người nhập

Sau ba hệ số, tổng dự báo được kéo về 0,85 × tổng Chronos-2 + 0,15 × tổng sau chỉnh, với hệ số kéo chặn trong $[0{,}92;\ 1{,}08]$.


7. Biến lịch: trọng số ngày giao dịch

Dùng ở cả Chronos-2, lõi mùa vụ và dự báo 12 tháng (model_lab/src/model_lab/models/frontier.py).

TênGiá trịGhi chú
DOW_WEIGHTSThứ Hai 1,25 · thứ Ba 1,08 · thứ Tư 0,95 · thứ Năm 0,98 · thứ Sáu 0,94 · thứ Bảy 0,60 · Chủ nhật 0,12Trọng số theo thứ trong tuần, phản ánh nhịp đặt hàng trên DMS
PUBLIC_HOLIDAYS_MD01/01, 30/04, 01/05, 01/09, 02/09Ngày lễ nhận trọng số 0,08. Chưa có Tết Âm lịch và Giỗ Tổ Hùng Vương vì hai ngày này đổi theo năm dương lịch và kho dữ liệu chưa có bảng ngày lễ
W(tháng)Tổng trọng số các ngày trong thángTách thành w1 (ngày 1–15) và w2 (ngày 16–31) cho h1_rate, h2_rate

8. Biến của dự báo 12 tháng (M+2 … M+12)

Từ tháng thứ hai trở đi, hệ thống không chạy lại tầng cây và 28 biến ngoại sinh. Số mỗi tháng được kéo dài từ số M+1 (compute_12m_sku_warehouse_trajectory):

$$f_{m} = f_{\text{M+1}} \times \text{seas}_{m} \times \frac{W(m)}{W(\text{M+1})} \times \big(0{,}80 + 0{,}20 \times \text{chr\_step}_m\big)$$
BiếnÝ nghĩaNguồn
f_M+1Dự báo tháng M+1 của mô hình chốt, theo kho × mãMục 1
seas_mChỉ số mùa vụ của mã hàng ở tháng $m$ so với tháng M+1. Chỉ số riêng của mã (chặn trong $[0{,}35;\ 2{,}80]$) được co về chỉ số toàn công ty theo trọng số sku_mean_daily / (sku_mean_daily + 15) — mã bán ít thì gần như dùng chỉ số toàn công tyLịch sử thùng trên ngày giao dịch 04/2025 – 09/2026. Ở chỉ số toàn công ty, tháng có đủ hai năm thì năm 2026 nặng 0,65, năm 2025 nặng 0,35
W(m)Trọng số ngày giao dịchMục 7
chr_step_mHình dạng đường đi theo Chronos-Bolt-Small, (chr_h + 2) / (chr_h1 + 2) chặn trong $[0{,}65;\ 1{,}45]$Lịch sử kho × mã

Tổng mỗi tháng sau đó được kéo về một mục tiêu toàn công ty tính cùng công thức trên ở mức tổng.


9. Có trong dữ liệu nhưng mô hình chốt chưa đọc

Các trường dưới đây có sẵn trong panel và đã được hệ thống tự lấy, nhưng bộ số chốt hiện không dùng. Ghi ra để không ai tưởng mô hình đã tính tới chúng.

Tên trườngÝ nghĩaVì sao chưa dùng
avg_tmin, total_rainfallNhiệt độ thấp nhất, tổng lượng mưaChưa đưa vào nhóm ngoại sinh
avg_tmax, rain_days của tháng đíchThời tiết tháng cần dự báoBảng thời tiết chỉ dự báo khoảng 16 ngày tới; với tháng đã qua thì mang số đo thật, dùng sẽ rò thông tin tương lai vào kiểm chứng
is_on_promo, promo_days, promo_depthCờ và độ sâu CTKM ở tháng đíchChỉ dùng ở bàn thử model_lab, chưa nối vào bộ số chốt
visit_days, has_visit_dataSố ngày viếng thăm, cờ có dữ liệu viếng thămĐã dùng tỷ lệ tuân thủ visit_compliance_rate thay thế
account_statusTrạng thái tài khoản cửa hàngBảng cửa hàng chỉ giữ trạng thái hiện tại, áp ngược cho lịch sử là sai
city_name, pjp_route, store_system, store_group_code, channel_code, is_legal_entityThuộc tính cửa hàngChỉ có nghĩa ở hạt cửa hàng; bộ số chốt dự báo ở hạt kho, kho con, chuỗi
canceled_qty, avg_days_to_delivery, effective_unit_priceĐơn huỷ, ngày giao, đơn giá thựcChưa đưa vào nhóm ngoại sinh