+6

[Data Science] Nhận diện và đối đầu với data drift trong MLOps pipeline

Có bao giờ bạn tự hỏi tại sao model machine learning có thể hoạt động cực kỳ tốt trong quá khứ, nhưng bỗng dưng lại trở nên "cùi bắp" theo thời gian không? Đó là lúc mà khái niệm data drift được ra đời trong MLOps concept, tức là dữ liệu đã bị thay đổi và không còn đúng với model cũ. Vậy thì, khi mà việc train model được thực hiện lặp đi lặp lại (trong một MLOps pipeline), bằng cách nào thì ta tự động phát hiện ra được và cảnh báo được cho các anh Data Scientist?

"Sông có lúc, data có khúc" - đúng rồi đấy, data luôn chỉ có khúc thôi, vì nó là batching/streaming mà. (j4f)

Data drift là gì nhỉ?

Cách tiếp cận đơn giản: Vạn vật luôn đổi thay và dữ liệu của ta cũng thế, trong một MLOps pipeline, mình hiểu đơn giản là quá trình lấy data mới và huấn luyện các mô hình học máy một cách tự động. Và vì bộ siêu tham số (hyper parameters) đã được tinh chỉnh để fit với một tập data duy nhất (thường các anh DS hay thực hiện trong file csv import lên notebook), nhưng data mới được cập nhật liên tục hàng năm/tháng/ngày/giờ/phút/giây, thì không có gì đảm bảo rằng tính chất toán học của tập dữ liệu mới này sẽ toàn vẹn được như cũ?

Ví dụ cho việc thay đổi:

  • Dữ liệu kinh doanh bị ảnh hưởng bởi các sự kiện đột ngột (như COVID-19,...)
  • Dữ liệu về chiều cao của thanh thiếu nên Việt nam năm 2000 với năm 2020 sẽ khác nhau, vì bây giờ các bạn được ăn uống đầy đủ hơn lúc trước, nên chiều cao cũng phát triển hơn.
  • ... Rất nhiều trường hợp khác dữ liệu bị thay đổi về các tính chất.

Và sự thay đổi tính chất đó gọi chung là... data drift.

image.png

Hiểu theo mặt thống kê, data drift đơn giản là phân phối của dữ liệu bị trượt, hoặc bị thay đổi theo thời gian, ví dụ như mô hình bạn train năm 2018 hội tụ và generalize tốt với dữ liệu 2018, không có nghĩa dữ liệu sẽ có cùng ý nghĩa thống kê với của năm 2021. Và mục tiêu của mình là phải có một hệ thống tự động nhận biết được thời điểm 2021, tức là thời điểm dữ liệu bị thay đổi tính chất, và thực hiện việc cảnh báo (alert) cho các MLOps EngineerData Scientist.

Phương pháp tối ưu để phát hiện data drift

Có rất nhiều phương pháp để phát hiện data drift, nhưng phương pháp vừa có ý nghĩa về mặt thống kê, vừa có kết quả thực tế, hiệu quả và giải thích được đó chính là sử dụng một kiểm định tên là kiểm định Kolmogorov-Smirnov (K-S Test) , có người còn gọi là Goodness-of-Fit Test.

Nghe lạ quá nhỉ? Nhưng về ý nghĩa toán học - thống kê nó không có gì cao siêu cả, chỉ đơn giản là kiểm định xem hai phân phối của hai mẫu có khác biệt tính chất với nhau không.

Ta có một metric để đo lường sự khác biệt phân phối giữa hai mẫu, biểu diễn như sau:

DKS=supxF1(x)F2(x)D_{KS} = \sup_{x} |F_{1}(x) - F_{2}(x)|

Trong đó:

  • F1(x)F_{1}(x) là hàm phân phối tích lũy của tập data trong quá khứ.
  • F2(x)F_{2}(x) là hàm phân phối tích lũy của tập data mới.

Nếu giá trị DKSD_{KS} càng lớn, càng xảy ra data drift.

Kiểm định HH dành cho hai mẫu:

{H0:Hai maˆ˜u dữ liệu được ruˊt ra từ cuˋng một phaˆn phoˆˊi.H1:Hai maˆ˜u dữ liệu khoˆng được ruˊt ra từ cuˋng một phaˆn phoˆˊi\begin{cases} H_0 :& \text{Hai mẫu dữ liệu được rút ra từ cùng một phân phối.} \\ H_1 :& \text{Hai mẫu dữ liệu không được rút ra từ cùng một phân phối} \end{cases}

Vậy, data bị drift khi ta bác bỏ H0H_0 khi pvaluep-value của kiểm định Kolmogorov-Smirnov (K-S) nhỏ hơn mức ý nghĩa đã chọn (ví dụ 0.050.05 chẳng hạn). Tính pvaluep-value liên hệ như nào với DKSD_{KS} thì mình sẽ không đi sâu ở bài viết này để tránh việc dài dòng. Giờ thì... thực hành thôi!

Sử dụng Python để detect data drift

  1. Thư viện mà mình cần dùng ở đây hết sức quen thuộc, đó là scipy, khỏi phải giới thiệu nhiều vì package này quá quen thuộc với các bạn data science rồi, cho những ai chưa biết thì đây là một thư viện chứa rất nhiều hàm thống kê của Python. Cách cài đặt đơn giản bằng pip thôi:
pip install scipy
  1. Sử dụng ks_2samp nằm trong module scipy.stats như sau:
from scipy import stats
test = stats.ks_2samp(df[column], df_new[column])
  • Ở đây mình đang thực hiện việc test ở hai dataframe là df (dữ liệu quá khứ) và df_new (dữ liệu nóng hổi vừa thu thập được).
  • Để kiểm định xem 1 feature / column có đảm bảo tính chất hay không, mình sẽ thực hiện như trên, kết quả của function ks_2samp trả về sẽ được gán vào biến test
  1. test[1] chính là pvaluep-value của kiểm định, mình đang dùng mức ý nghĩa:

α=0.05\alpha=0.05

Nếu pvalue<αp-value<\alpha, tức là sẽ bác bỏ H0H_0, đồng nghĩa với việc data bị drift.

if test[1] < 0.05:
    print("Data drift at column: ", column)
  1. Chỉ vậy thôi đó, ta có thể đóng function lại code trên để tiện dùng trong MLOps pipeline, và tiếp đến phần sau, mình sẽ ví dụ việc tích hợp detect tự động như nào nhé!

Tích hợp detect vào MLOps pipeline

Ở đây mình sẽ ví dụ như là 1 task của Airflow nhé.

  • Trong task này, mình sẽ duyệt qua từng column, nếu column vào bị drift, thì ngay lập tức mail cho data scientist, để thực hiện tune parameter nếu cần thiết, hoặc train model lại với data mới,...
  • Đồng thời cũng sẽ return True nếu gặp column drift, và return False nếu không gặp column drift nào.
from airflow.decorators import task
from scipy import stats

@task.python(
    show_return_value_in_logs=True,
)
def detect_drift() -> bool:
    # NOTE: Download new data from S3 (bước fetch df and df_new)
    
    drift_columns = []
    
    for column in df.columns:
        test = stats.ks_2samp(df[column], df_new[column])
        if test[1] < 0.05:
            drift_columns.append(column)
    
    if drift_columns:
        print("Data drift detected in columns: ", drift_columns)
        mail_to_data_scientist()
        return True
    
    return False

Những phương pháp cần làm sau khi đã phát hiện được data drift

image.png

Sau khi biết data bị drift thì người ta thường làm gì nhỉ, thật ra thì có nhiều cách lắm, nhưng xoay quanh vẫn là tìm cách để huấn luyện (train) lại mô hình (model):

  • Train mô hình với data gộp giữa cũ và mới.
  • Train mô hình với chỉ mỗi data mới.
  • Train mô hình với bộ siêu tham số mới (cần được tuning lại bởi data scientist).
  • ....
  • Và best practice thì thường là không có, mà sẽ phụ thuộc vào quyết định của các data scientist, là những người hiểu rõ nhất về tính chất của dữ liệu mà họ đang làm.

Kết luận

Đừng quên rằng trong thế giới mà data thay đổi liên tục, hãy luôn sẵn sàng để tuning model và optimize bất cứ khi nào bị réo, vì như đã nói: "sông có lúc, data có khúc".

References


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí