Chuỗi thời gian 1 — Tổng quan & thành phần
Chuỗi thời gian 1 — Tổng quan & thành phần
Gần như mọi con số quan trọng trong một ngân hàng đều có nhãn thời gian: số giao dịch mỗi giờ, số dư huy động cuối ngày, lượng tiền rút ATM mỗi ngày, tải CPU của core banking mỗi phút. Khi bạn xếp những con số đó theo thứ tự thời gian, bạn có một chuỗi thời gian (time series) — và bạn bước vào một thế giới có luật chơi riêng, khác hẳn dữ liệu dạng bảng tĩnh mà series Machine Learning làm việc cùng.
Bài này mở đầu series Chuỗi thời gian & Dự báo. Mục tiêu: cho bạn một bản đồ khái niệm vững — chuỗi thời gian là gì, tại sao không được đối xử với nó như dữ liệu thường, và nó được phân rã thành những thành phần nào. Đây là nền tảng cho mọi bài sau: EDA và phân rã, mô hình cổ điển (ARIMA/ETS), đặc trưng cho ML, mô hình nâng cao, đánh giá, phát hiện bất thường, và đưa lên production.
1. Chuỗi thời gian là gì
Một chuỗi thời gian là một dãy quan sát $y_1, y_2, \dots, y_T$ được ghi theo các mốc thời gian có thứ tự, thường cách đều nhau (mỗi giờ, mỗi ngày, mỗi tháng). Điểm cốt lõi không phải là "có cột thời gian" — nhiều bảng có created_at nhưng không phải chuỗi thời gian. Điều làm nên chuỗi thời gian là chỉ số thời gian là trục phân tích chính: ta quan tâm giá trị thay đổi thế nào theo thời gian và muốn dự báo giá trị tương lai.
Phân biệt nhanh:
- Univariate (đơn biến): một chuỗi giá trị theo thời gian — ví dụ tổng khối lượng giao dịch mỗi ngày.
- Multivariate (đa biến): nhiều chuỗi song song có thể ảnh hưởng lẫn nhau — khối lượng giao dịch, số khách hoạt động, lãi suất, cùng chỉ số theo ngày.
- Panel / longitudinal: cùng một cấu trúc chuỗi lặp lại cho nhiều thực thể — ví dụ chuỗi rút tiền theo ngày cho từng máy ATM.
2. Vì sao chuỗi thời gian KHÁC dữ liệu thường
Đây là phần dễ bị hiểu sai nhất và cũng là lý do nhiều mô hình đẹp trên giấy nhưng sập khi lên thật. Ba đặc thù chính:
Thứ tự thời gian là thông tin
Trong dữ liệu tabular kinh điển, mỗi dòng thường được coi là một mẫu độc lập; đảo thứ tự các dòng không làm mất thông tin. Với chuỗi thời gian thì ngược lại: thứ tự chính là dữ liệu. Giá trị hôm nay phụ thuộc vào hôm qua. Nếu bạn xáo trộn (shuffle) các quan sát, bạn phá huỷ chính cái mà bạn định học.
Tự tương quan (autocorrelation)
Các quan sát gần nhau trong thời gian tương quan với nhau. Khối lượng giao dịch của giờ này giống giờ trước nó, và giống cùng giờ ngày hôm qua. Sự phụ thuộc này (gọi là autocorrelation — tự tương quan với chính mình ở các độ trễ lag khác nhau) vừa là tín hiệu để dự báo, vừa vi phạm giả định độc lập của phần lớn công cụ thống kê chuẩn. Nó cũng khiến các chỉ số tin cậy tính theo cách thông thường bị lệch (thường lạc quan quá mức).
Không được xáo trộn khi chia dữ liệu
Ở ML 1 — Quy trình ta chia train/test ngẫu nhiên. Với chuỗi thời gian, tuyệt đối không làm vậy. Nếu bạn để một điểm tương lai lọt vào tập train, mô hình "nhìn trộm tương lai" — một dạng data leakage đặc biệt hiểm. Cách đúng: chia theo thời gian (train là quá khứ, test là tương lai), dùng time series split / rolling origin. Chi tiết ở bài Đánh giá, nhưng nguyên tắc phải nhớ từ bây giờ: quá khứ dự báo tương lai, không bao giờ ngược lại.
Một khái niệm nền quan trọng khác là tính dừng (stationarity): một chuỗi dừng có tính chất thống kê (trung bình, phương sai) ổn định theo thời gian. Nhiều mô hình cổ điển yêu cầu tính dừng; chuỗi thực tế thường không dừng do có trend và seasonality, nên phần lớn công việc là biến đổi chuỗi về dạng gần dừng. Ta đào sâu ở bài mô hình cổ điển.
3. Bốn thành phần của một chuỗi thời gian
Cách hữu ích nhất để tư duy về chuỗi thời gian là phân rã (decomposition): xem chuỗi quan sát như tổng (hoặc tích) của các thành phần có ý nghĩa.
Trend (xu hướng)
Chiều hướng dài hạn của chuỗi — tăng, giảm hay đi ngang qua nhiều chu kỳ. Trend phản ánh động lực nền: tổng huy động của ngân hàng tăng dần theo năm, số khách dùng mobile banking tăng đều. Trend không nhất thiết là đường thẳng; nó có thể tăng chậm lại rồi bão hoà.
Seasonality (mùa vụ)
Mẫu lặp lại với chu kỳ cố định, đã biết. Đây là thành phần dễ khai thác nhất vì nó gắn với lịch:
- Trong ngày (intraday): giao dịch dồn vào giờ hành chính, đỉnh buổi trưa, gần như phẳng ban đêm.
- Trong tuần: thứHai và cuối tuần khác ngày giữa tuần; lương về cuối tháng.
- Trong tháng / năm: cao điểm cận Tết Nguyên đán, dịp lễ 30/4 – 1/5, mùa nộp thuế.
Chu kỳ của seasonality là hằng số và có thể đoán trước (đúng 24 giờ, đúng 7 ngày, đúng 12 tháng).
Cyclic (chu kỳ)
Dao động lên-xuống không có chu kỳ cố định, thường kéo dài hơn một năm và gắn với bối cảnh kinh tế vĩ mô — chu kỳ tín dụng, chu kỳ lãi suất, suy thoái/phục hồi. Khác biệt then chốt với seasonality: cyclic không neo vào lịch, độ dài mỗi chu kỳ thay đổi (3 năm, 7 năm...) nên khó dự báo hơn nhiều. Trong thực hành hằng ngày, cyclic thường bị gộp chung vào "trend" trừ khi bạn làm dự báo vĩ mô dài hạn.
Noise / Residual (nhiễu)
Phần còn lại sau khi bóc trend và seasonality — biến động ngẫu nhiên không giải thích được: một sự kiện bất ngờ, sai số đo, hành vi cá biệt. Mục tiêu của mô hình không phải là fit hết noise (đó là overfitting), mà là mô tả noise đủ tốt để định lượng độ bất định. Noise cũng chính là nơi phát hiện bất thường (anomaly detection) làm việc: một điểm lệch xa khỏi noise kỳ vọng là ứng viên bất thường.
4. Additive vs multiplicative
Có hai cách kết hợp các thành phần:
| Additive (cộng) | Multiplicative (nhân) | |
|---|---|---|
| Công thức | $y_t = T_t + S_t + e_t$ | $y_t = T_t \times S_t \times e_t$ |
| Biên độ mùa vụ | Gần như không đổi theo mức chuỗi | Lớn dần khi mức chuỗi tăng |
| Ví dụ ngân hàng | Số ATM hoạt động mỗi ngày quanh một mức ổn định | Khối lượng giao dịch: khi tổng tăng, biên độ đỉnh Tết cũng phóng to theo |
Quy tắc thực hành: nhìn biểu đồ, nếu biên độ dao động mùa vụ nở ra theo mức chuỗi thì dùng multiplicative. Một mẹo phổ biến là lấy log dữ liệu — phép log biến quan hệ nhân thành cộng ($\log(T\cdot S) = \log T + \log S$), cho phép dùng công cụ additive rồi mũ ngược về. Ta thực hành phân rã cụ thể ở bài EDA & phân rã.
5. Tần suất & resampling
Tần suất (frequency) là khoảng cách giữa các quan sát: giây, phút, giờ, ngày, tuần, tháng. Chọn tần suất sai làm hỏng mọi thứ:
- Quá mịn (per-second) → nhiều noise, chuỗi thưa (nhiều mốc không có giao dịch), tốn tính toán.
- Quá thô (theo tháng) → mất mất mùa vụ trong ngày/tuần mà bạn cần.
Resampling là đổi tần suất:
- Downsampling (gộp lên): từ giao dịch thô → tổng hợp theo giờ/ngày bằng
SUM,COUNT,AVG. Đây là bước hầu như luôn cần với dữ liệu ngân hàng — dữ liệu gốc là sự kiện (mỗi giao dịch một dòng), phải gộp thành chuỗi đều. - Upsampling (chia nhỏ): từ tháng → ngày, phải nội suy (interpolation) giá trị thiếu; hiếm dùng và cần cẩn trọng.
Điểm chí mạng khi dựng chuỗi từ sự kiện: các mốc thời gian không có giao dịch sẽ biến mất khỏi GROUP BY, tạo ra "lỗ hổng" mà mô hình hiểu nhầm là chuỗi liền mạch. Sau khi gộp, bạn phải reindex về lưới thời gian đầy đủ và điền 0 (với đếm/tổng) — thường làm ở tầng Python/pandas sau khi lấy dữ liệu ra.
6. Dựng chuỗi thời gian từ dữ liệu giao dịch (SQL chạy được)
Ba ví dụ dưới đây chạy trực tiếp trên sandbox PostgreSQL read-only, dùng bảng transactions(id, account_id, amount, kind, created_at TIMESTAMP) để biến log giao dịch thô thành chuỗi thời gian ở các tần suất khác nhau.
(a) Chuỗi theo ngày — khối lượng và tổng giá trị giao dịch. Đây là chuỗi cơ bản nhất: mỗi ngày một điểm. date_trunc('day', ...) cắt phần giờ/phút, gom mọi giao dịch trong ngày vào một mốc.
-- ▶ Chạy được
SELECT date_trunc('day', created_at) AS ngay,
COUNT(*) AS so_giao_dich,
SUM(amount) AS tong_gia_tri
FROM transactions
GROUP BY date_trunc('day', created_at)
ORDER BY ngay;
Kết quả là một chuỗi đều theo ngày — nguyên liệu để nhìn ra trend (tổng tăng dần?) và seasonality theo tuần (cuối tuần thấp hơn?).
(b) Hồ sơ mùa vụ trong ngày — theo giờ. Để thấy intraday seasonality, ta gộp theo giờ trong ngày (0–23) bất kể ngày nào, dùng EXTRACT(HOUR FROM ...). Đây không phải chuỗi thời gian tuyến tính mà là hồ sơ mùa vụ (seasonal profile) — cho biết giờ cao điểm.
-- ▶ Chạy được
SELECT EXTRACT(HOUR FROM created_at) AS gio_trong_ngay,
COUNT(*) AS so_giao_dich,
AVG(amount) AS gia_tri_tb
FROM transactions
GROUP BY EXTRACT(HOUR FROM created_at)
ORDER BY gio_trong_ngay;
Nhìn cột so_giao_dich theo giờ, bạn sẽ thấy hình chuông giờ hành chính — chính là thành phần seasonality trong ngày.
(c) Chuỗi theo kind và ngày — nhiều chuỗi song song. Tách theo loại giao dịch (kind) cho ta nhiều chuỗi để so sánh mùa vụ khác nhau giữa các loại — ví dụ rút tiền và chuyển khoản có đỉnh khác nhau.
-- ▶ Chạy được
SELECT kind,
date_trunc('day', created_at) AS ngay,
COUNT(*) AS so_giao_dich,
SUM(amount) AS tong_gia_tri
FROM transactions
GROUP BY kind, date_trunc('day', created_at)
ORDER BY kind, ngay;
Ba truy vấn này là bước đầu tiên của mọi pipeline dự báo: chuyển từ sự kiện rời rạc sang chuỗi đều. Bước tiếp theo (điền lỗ hổng, phân rã, vẽ ACF) nằm ở bài EDA & phân rã.
7. Ứng dụng trong ngân hàng
Chuỗi thời gian là công cụ nền cho nhiều bài toán vận hành và kinh doanh:
- Dự báo nhu cầu tiền mặt ATM/quầy: mỗi máy ATM là một chuỗi rút tiền theo ngày. Dự báo giúp lịch tiếp quỹ tối ưu — nạp đủ để không hết tiền dịp cao điểm (chiều thứ Sáu, cận Tết) nhưng không để tiền "chết" quá nhiều trong máy.
- Khối lượng giao dịch theo giờ/ngày: phục vụ điều phối nhân sự tổng đài, và dự báo đỉnh lễ Tết để chuẩn bị hạ tầng thanh toán.
- Thanh khoản & dòng tiền: dự báo dòng tiền vào/ra để quản trị thanh khoản, đáp ứng yêu cầu của khối Treasury.
- Tăng trưởng huy động / tín dụng: chuỗi số dư tổng theo tháng, tách trend (tăng trưởng nền) khỏi seasonality (mùa gửi tiết kiệm cuối năm) để lập kế hoạch.
- Dự báo tải hệ thống (capacity planning): TPS, số phiên đăng nhập, tải core banking theo phút/giờ — dự báo đỉnh để cấp phát tài nguyên và tránh nghẽn.
8. Forecasting vs Anomaly detection
Hai bài toán lớn trên chuỗi thời gian, dễ nhầm nhưng mục tiêu ngược nhau:
| Forecasting (dự báo) | Anomaly detection (phát hiện bất thường) | |
|---|---|---|
| Câu hỏi | Giá trị tương lai sẽ là bao nhiêu? | Giá trị hiện tại/quá khứ có bất thường không? |
| Đầu ra | Con số + khoảng tin cậy cho tương lai | Cờ đánh dấu điểm lệch bất thường |
| Ví dụ | Ngày mai rút bao nhiêu tiền ATM? | Giao dịch giờ này có đột biến gian lận? |
| Xử lý outlier | Cố gắng làm mượt / loại bỏ để dự báo tốt | Chính outlier là đối tượng cần tìm |
Cả hai chia sẻ nền tảng chung (phân rã, tính dừng, mô hình chuỗi), nên series này xây forecasting trước rồi dùng lại nền đó cho anomaly detection ở bài phát hiện bất thường. Bài giám sát giao dịch nghiệp vụ được bàn riêng ở góc độ quy tắc và rủi ro.
Lộ trình series: phân rã & EDA → mô hình cổ điển ARIMA/ETS → đặc trưng & ML → mô hình nâng cao → đánh giá → bất thường → production. Nếu bạn đến từ ML tabular, AI 3 — ML cổ điển là nền tốt để so sánh cách tư duy.
Use case thực tế
Bài toán: Phòng Ngân quỹ muốn giảm chi phí tiếp quỹ ATM. Đội vận hành đang nạp cố định 500 triệu đồng/máy mỗi 3 ngày cho 200 máy — tiền nằm chết trong máy nhiều, nhưng vẫn có máy hết tiền chiều thứ Sáu và cận Tết.
Bước 1 — Dựng chuỗi. Với mỗi máy ATM, dùng truy vấn kiểu (a) ở trên (lọc thêm theo máy) để tạo chuỗi tổng số tiền rút mỗi ngày. Với 200 máy × ~2 năm dữ liệu, đây là bài toán panel (200 chuỗi song song).
Bước 2 — Phân rã sơ bộ. Chạy truy vấn (b) theo giờ cho thấy 80% lượng rút dồn vào 8h–18h — điều này định hình lịch tiếp quỹ (nạp trước 8h sáng). Chuỗi theo ngày cho thấy trend đi ngang, seasonality tuần rõ (đỉnh thứ Sáu cao hơn thứ Ba ~35%), và đột biến cận Tết (mức trung bình ×2.5 trong 10 ngày trước Tết).
Bước 3 — Nhận diện additive hay multiplicative. Vì đỉnh Tết phóng to theo mức nền của từng máy (máy khu công nghiệp đỉnh cao hơn hẳn máy ngoại thành), mô hình multiplicative phù hợp; ta làm việc trên log(số tiền rút).
Kết quả kỳ vọng (minh hoạ): thay lịch cố định bằng lịch theo dự báo — nạp nhiều trước thứ Sáu và trước Tết, ít hơn đầu tuần. Ước tính giảm ~20% tồn quỹ trung bình trong máy đồng thời giảm sự cố hết tiền. Chi tiết mô hình dự báo ở bài mô hình cổ điển; cách đo "dự báo tốt tới đâu" ở bài đánh giá.
Ghi nhớ
- Chuỗi thời gian = dãy quan sát có thứ tự thời gian; trục thời gian là trục phân tích chính, không chỉ là một cột dữ liệu.
- Ba đặc thù bắt buộc nhớ: thứ tự là thông tin, có tự tương quan (autocorrelation), và không bao giờ xáo trộn / phải chia train-test theo thời gian (quá khứ → tương lai).
- Bốn thành phần: trend (xu hướng dài hạn), seasonality (mùa vụ chu kỳ cố định theo lịch: giờ/ngày/tuần/tháng/năm), cyclic (chu kỳ không cố định, thường vĩ mô), noise (phần ngẫu nhiên còn lại).
- Additive khi biên độ mùa vụ ổn định; multiplicative khi biên độ nở theo mức chuỗi — mẹo: lấy
logđể biến nhân thành cộng. - Dữ liệu ngân hàng gốc là sự kiện → phải resample (downsampling bằng
date_trunc+GROUP BY) thành chuỗi đều; nhớ điền lỗ hổng ở mốc không có giao dịch. - Forecasting dự báo tương lai (làm mượt outlier); anomaly detection tìm chính outlier — cùng nền tảng, mục tiêu ngược nhau.
Bài viết liên quan
Phân biệt AI/ML/DL, các kiểu học máy, quy trình ML end-to-end và thuật ngữ nền tảng.
Chất lượng dữ liệu, xử lý thiếu/ngoại lai, mã hoá, chuẩn hoá, tạo đặc trưng và tránh data leakage.
Mô hình ngôn ngữ lớn hoạt động ra sao, token, context window, tham số sinh, và kỹ thuật viết prompt.
Retrieval-Augmented Generation, vector database, tool calling, agent và MCP để xây ứng dụng LLM thực tế.