Chuyển đến nội dung chính

Walk-Forward là gì?

Trong Machine Learning cổ điển, khi muốn kiểm tra độ ổn định của mô hình, chúng ta thường dùng K-Fold Cross-Validation. Chúng ta xáo trộn dữ liệu, chia làm K phần và huấn luyện. Tuy nhiên, nếu bạn áp dụng cách này cho dữ liệu chuỗi thời gian (Time Series) như dự báo thời tiết, lượng điện tiêu thụ hay lưu lượng server, bạn đang mắc một sai lầm nghiêm trọng: Data Leakage (Rò rỉ dữ liệu).

Lý do đơn giản: Bạn không thể dùng dữ liệu của "ngày mai" để dạy cho mô hình dự đoán "hôm nay".

Hôm nay, chúng ta sẽ tìm hiểu về Walk-Forward Validation (WFV)Walk-Forward Optimization (WFO) – tiêu chuẩn vàng để kiểm thử các mô hình phụ thuộc thời gian, đi kèm ví dụ thực tế sử dụng .NET 10ML.NET.


1. Walk-Forward Validation (WFV) là gì?

Hãy tưởng tượng bạn đang đứng trên dòng thời gian. Bạn chỉ biết quá khứ và muốn dự đoán tương lai gần. WFV mô phỏng chính xác quá trình này.

Thay vì xáo trộn dữ liệu ngẫu nhiên, WFV sử dụng một "cửa sổ trượt" (sliding window) hoặc "cửa sổ mở rộng" (expanding window):

  • Train: Huấn luyện trên một khoảng thời gian trong quá khứ (Ví dụ: Tháng 1 -> Tháng 3).
  • Test: Kiểm thử trên khoảng thời gian ngay sau đó (Ví dụ: Tuần đầu tháng 4).
  • Slide: Trượt cả cửa sổ Train và Test về phía trước (Ví dụ: Train từ Tháng 1 -> Tuần đầu T4, Test tuần thứ 2 T4).

Lợi ích cốt lõi:

  • Không nhìn trộm tương lai (No Look-ahead Bias): Đảm bảo mô hình chỉ học từ dữ liệu đã xảy ra.
  • Thích nghi với sự thay đổi (Adaptability): Kiểm tra xem mô hình có còn đúng khi dữ liệu thay đổi theo mùa hoặc xu hướng mới hay không.

Sliding Window

Sliding Window (cửa sổ trượt) là một kỹ thuật thường được sử dụng để xử lý các dãy liên tiếp trong mảng hoặc chuỗi một cách hiệu quả, bằng cách duy trì một "cửa sổ" chứa một phần tử liên tục của dữ liệu và di chuyển nó qua toàn bộ dãy.

Có hai dạng phổ biến của thuật toán Sliding Window:

  1. Cửa Sổ Có Kích Thước Cố Định (Fixed-Size)
  2. Cửa Sổ Có Kích Thước Linh Hoạt (Variable-Size)
Ví dụ: Tìm tổng lớn nhất của một dãy con liên tiếp có độ dài k
using System;

class GFG {

    static int maxSum(int[] arr, int n, int k){

        // n must be greater
        if (n <= k) {
            Console.WriteLine("Invalid");
            return -1;
        }

        // Compute sum of first window of size k
        int max_sum = 0;
        for (int i = 0; i < k; i++)
            max_sum += arr[i];

        // Compute sums of remaining windows by
        // removing first element of previous
        // window and adding last element of
        // current window.
        int window_sum = max_sum;
        for (int i = k; i < n; i++) {
            window_sum += arr[i] - arr[i - k];
            max_sum = Math.Max(max_sum, window_sum);
        }

        return max_sum;
    }

    public static void Main(){
        int[] arr = {5, 2, -1, 0, 3};
        int k = 3;
        int n = arr.Length;
        Console.WriteLine(maxSum(arr, n, k));
    }
}
Minh họa:
Sliding Window (k = 3)

[5   2  -1]  0   3   → Sum = 6
 5  [2  -1   0]  3   → Sum = 1
 5   2  [-1   0   3]  → Sum = 2

Expanding Window

Expanding Window (cửa sổ mở rộng) là kỹ thuật mà:
  1. Tập train không giữ kích thước cố định
  2. Mỗi lần lặp, ta giữ lại toàn bộ dữ liệu cũ
  3. Và mở rộng thêm dữ liệu mới vào tập train
Ví dụ:
Expanding Window (Train grows over time)

Walk 1:
[=====3=====][1]

Walk 2:
[=========4=========][1]

Walk 3:
[===============5===============]

2. Walk-Forward Optimization (WFO) là gì?

Nếu WFV là cách chúng ta kiểm tra mô hình, thì WFO là cách chúng ta tinh chỉnh nó.

Trong quá trình trượt cửa sổ thời gian, các tham số tốt nhất (hyperparameters) cho tháng 1 có thể không còn tốt cho tháng 6. WFO thực hiện việc tối ưu hóa lại các tham số sau mỗi lần trượt hoặc sau một khoảng thời gian nhất định.

Quy trình WFO:

  1. Lấy một cửa sổ dữ liệu.
  2. Chạy WFV trên cửa sổ đó với nhiều bộ tham số khác nhau.
  3. Chọn bộ tham số tốt nhất.
  4. Áp dụng bộ tham số đó để dự đoán cho giai đoạn tiếp theo ("Out of Sample").
  5. Lặp lại.

3. Ví dụ thực hành: Dự báo tiêu thụ năng lượng (Smart Grid)

Chúng ta sẽ xây dựng một ứng dụng Console đơn giản bằng .NET 10ML.NET. Bài toán: Dự đoán lượng điện tiêu thụ dựa trên dữ liệu quá khứ.

using Microsoft.ML;
using Microsoft.ML.Data;

public class EnergyData
{
    public float TimeIndex { get; set; }
    public float Consumption { get; set; }
}

public class EnergyPrediction
{
    [ColumnName("Score")]
    public float PredictedConsumption { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var mlContext = new MLContext(seed: 1);
        var allData = GenerateData(1000);

        int trainWindowSize = 200;
        int testWindowSize = 50;
        int stepSize = 50;
        
        var metricsHistory = new List<double>();

        for (int i = 0; (i + trainWindowSize + testWindowSize) < allData.Count; i += stepSize)
        {
            var trainData = allData.GetRange(i, trainWindowSize);
            var testData = allData.GetRange(i + trainWindowSize, testWindowSize);

            IDataView trainView = mlContext.Data.LoadFromEnumerable(trainData);
            IDataView testView = mlContext.Data.LoadFromEnumerable(testData);

            var pipeline = mlContext.Transforms.Concatenate("Features", "TimeIndex")
                .Append(mlContext.Regression.Trainers.Sdca(labelColumnName: "Consumption", maximumNumberOfIterations: 100));

            var model = pipeline.Fit(trainView);
            var predictions = model.Transform(testView);
            var metrics = mlContext.Regression.Evaluate(predictions, labelColumnName: "Consumption");

            metricsHistory.Add(metrics.RootMeanSquaredError);
            Console.WriteLine($"Walk at {i}: RMSE = {metrics.RootMeanSquaredError:F4}");
        }

        Console.WriteLine($"\nAverage RMSE: {metricsHistory.Average():F4}");
    }

    static List<EnergyData> GenerateData(int count)
    {
        var data = new List<EnergyData>();
        var rand = new Random(0);
        for (int i = 0; i < count; i++)
        {
            float val = 10 + 5 * (float)Math.Sin(i / 20.0) + (float)(rand.NextDouble() * 2.0 - 1.0);
            data.Add(new EnergyData { TimeIndex = i, Consumption = val });
        }
        return data;
    }
}

Sử dụng Walk-Forward Validation giúp bạn tránh được cái bẫy "mô hình tốt trên giấy nhưng tệ khi thực tế". Nếu bạn đang làm việc với dữ liệu cảm biến, năng lượng, hoặc bất kỳ hệ thống IoT nào, hãy ngừng dùng K-Fold ngẫu nhiên và bắt đầu "Walk-Forward" ngay hôm nay.

Tham khảo

Sliding Window Technique

Nhận xét

Bài đăng phổ biến từ blog này

[ASP.NET MVC] Authentication và Authorize

Một trong những vấn đề bảo mật cơ bản nhất là đảm bảo những người dùng hợp lệ truy cập vào hệ thống. ASP.NET đưa ra 2 khái niệm: Authentication và Authorize Authentication xác nhận bạn là ai. Ví dụ: Bạn có thể đăng nhập vào hệ thống bằng username và password hoặc bằng ssh. Authorization xác nhận những gì bạn có thể làm. Ví dụ: Bạn được phép truy cập vào website, đăng thông tin lên diễn đàn nhưng bạn không được phép truy cập vào trang mod và admin.

ASP.NET MVC: Cơ bản về Validation

Validation (chứng thực) là một tính năng quan trọng trong ASP.NET MVC và được phát triển trong một thời gian dài. Validation vắng mặt trong phiên bản đầu tiên của asp.net mvc và thật khó để tích hợp 1 framework validation của một bên thứ 3 vì không có khả năng mở rộng. ASP.NET MVC2 đã hỗ trợ framework validation do Microsoft phát triển, tên là Data Annotations. Và trong phiên bản 3, framework validation đã hỗ trợ tốt hơn việc xác thực phía máy khách, và đây là một xu hướng của việc phát triển ứng dụng web ngày nay.

Tổng hợp một số kiến thức lập trình về Amibroker

Giới thiệu về Amibroker Amibroker theo developer Tomasz Janeczko được xây dựng dựa trên ngôn ngữ C. Vì vậy bộ code Amibroker Formula Language sử dụng có syntax khá tương đồng với C, ví dụ như câu lệnh #include để import hay cách gói các object, hàm trong các block {} và kết thúc câu lệnh bằng dấu “;”. AFL trong Amibroker là ngôn ngữ xử lý mảng (an array processing language). Nó hoạt động dựa trên các mảng (các dòng/vector) số liệu, khá giống với cách hoạt động của spreadsheet trên excel.