FDE PulseViệc làm FDE đang mở 316Mới đăng 7 ngày qua 10Chủ đề nổi bật: Đào tạo kỹ năng FDE tại Đông Nam Á

Tờ báo của nghề Forward Deployed Engineer

Bách khoa

Vì sao hồ sơ vay bị từ chối? Dùng SHAP để giải thích, LIME để kiểm tra chéo

Model chấm điểm tín dụng chạy rất tốt cho tới khi có người hỏi “vì sao hồ sơ này bị loại”, và câu trả lời phải đúng với chính hồ sơ ấy.

Đồ hoạHồ sơ 4127: từ mức nền 0.12 lên 0.41
  1. 1Mức nền: 0.12Điểm xuất phát, tính trên tập nền 500 hồ sơ lấy từ tập train
  2. 2Nợ/thu nhập 52%: +0.14Lũy kế 0.26, là lý do từ chối số một
  3. 33 lần trả chậm: +0.11Lũy kế 0.37, đã vượt ngưỡng duyệt 0.30; LIME cũng xếp hạng hai
  4. 4Làm việc 4 tháng: +0.06Lũy kế 0.43, lý do thứ ba được cả SHAP lẫn LIME xác nhận
  5. 5Thu nhập +0.03, tín dụng −0.05Lịch sử 9 năm kéo xuống, kết quả cuối 0.41 thì bị từ chối

Mỗi feature cộng hoặc trừ một phần, và bạn phải tự kiểm tra tổng có khớp với xác suất model trả về không.

Đồ hoạ: FDE Times

Tóm tắt nhanh

  • CFPB yêu cầu lý do từ chối tín dụng phải cụ thể và chính xác, model phức tạp hay khó hiểu đến mấy cũng không được miễn.
  • Với model cây, Tree SHAP tính chính xác và nhanh, nhưng cách xử lý feature tương quan sẽ thay đổi kết quả.
  • LIME hợp để kiểm tra chéo, nhưng trên dữ liệu bảng nó có thể dao động, và cả hai phương pháp đều có thể bị qua mặt.
Chia sẻLinkedInFacebookX

Thử hình dung email từ đội quản trị rủi ro của một công ty cho vay mà bạn đang triển khai model: “Hồ sơ 4127 bị từ chối. Khách khiếu nại. Chúng tôi cần lý do cụ thể trước thứ Sáu.” Model là một XGBoost với vài chục feature, AUC đẹp, đã qua backtest. Không ai trong phòng họp trả lời được vì sao chính hồ sơ này bị loại.

Đây là một nhiệm vụ FDE rất điển hình: model đúng về mặt thống kê nhưng đứng trước một khách hàng cụ thể thì không giải thích được. Ở Mỹ, trả lời được câu hỏi này là nghĩa vụ pháp lý của bên cho vay, không phải chuyện tùy ý.

Circular 2022-03 của CFPB, ban hành ngày 26/5/2022, khẳng định yêu cầu nêu lý do từ chối theo ECOA và Regulation B áp dụng cho mọi quyết định tín dụng, dù được đưa ra bằng công nghệ gì.

CFPB còn nói rõ hơn: chủ nợ không được dùng thuật toán phức tạp nếu vì thế mà không đưa ra được lý do cụ thể và chính xác. Họ cũng không thể viện cớ rằng công nghệ mình dùng để xét hồ sơ quá phức tạp, quá khó hiểu.

Nếu bạn làm cho fintech phục vụ thị trường Mỹ, hay cho một ngân hàng đang tham khảo chuẩn này, kỹ năng ở bài này sẽ được đem ra dùng thật.

SHAP trả lời “mỗi feature đẩy hồ sơ đi bao xa”

SHAP, do Lundberg và Lee công bố năm 2017, gán cho mỗi feature một mức đóng góp vào từng dự đoán cụ thể. Cách đọc hay dùng là hình dung model có một mức nền, tạm coi là xác suất vỡ nợ trung bình trên một tập dữ liệu tham chiếu.

Từ mức nền làm điểm xuất phát, bạn xem từng feature của hồ sơ đẩy lên hay kéo xuống bao nhiêu. Nhưng đừng mặc định cách đọc đó đúng: hãy tự kiểm tra xem mức nền cộng các đóng góp có khớp với xác suất model trả về cho hồ sơ ấy không.

Khi phép cộng khớp, bạn có một lời giải thích mà đội rủi ro tự dò lại được từng con số, và đó là thứ cần cho lý do từ chối.

Với model cây như XGBoost hay LightGBM, shap.TreeExplainer dùng Tree SHAP, theo tài liệu của thư viện là một phương pháp nhanh và chính xác cho model cây và tổ hợp cây.

Bạn không phải xấp xỉ, cũng không phải chờ hàng giờ.

LIME, của Ribeiro, Singh và Guestrin từ năm 2016, đi đường khác. Nó tạo ra nhiều biến thể của hồ sơ bằng cách xáo trộn giá trị, hỏi model gốc dự đoán cho từng biến thể, rồi fit một model đơn giản trên tập dữ liệu mới này.

Mẫu nào càng gần hồ sơ gốc thì càng được tính trọng số cao. LIME hỗ trợ classifier trên dữ liệu bảng, gồm cả cột số lẫn cột phân loại, nên hợp với dữ liệu tín dụng.

Làm trọn ca 4127

Đoạn code dưới đây tính SHAP ở thang xác suất với chế độ interventional. Theo tài liệu SHAP, chế độ này cần một tập dữ liệu nền, nên ta lấy mẫu 500 hồ sơ từ tập train.

import shap
from lime.lime_tabular import LimeTabularExplainer

background = X_train.sample(500, random_state=0)
explainer = shap.TreeExplainer(
    model,
    data=background,
    feature_perturbation="interventional",
    model_output="probability",
)
x = X_test.loc[[4127]]
sv = explainer(x)
print(sv.base_values[0], sv.values[0].sum())

Giả sử kết quả cho mức nền 0.12, tổng các đóng góp là +0.29, và khi so với predict_proba thì xác suất vỡ nợ model trả về đúng là 0.41, cao hơn ngưỡng duyệt 0.30 mà công ty đặt ra.

Tách theo feature: tỷ lệ nợ trên thu nhập 52% góp +0.14; ba lần trả chậm trong 12 tháng góp +0.11; mới làm công việc hiện tại 4 tháng góp +0.06; thu nhập góp +0.03; còn lịch sử tín dụng 9 năm kéo xuống −0.05.

Cộng lại: 0.14 + 0.11 + 0.06 + 0.03 − 0.05 = 0.29.

Phép cộng này là thứ đầu tiên bạn kiểm tra. Nếu base_values + values.sum() không khớp với model.predict_proba, hãy xem lại mình đang giải thích output nào, chẳng hạn log-odds thay vì xác suất, trước khi đọc tiếp bất cứ con số nào.

Tiếp theo chạy LIME trên cùng hồ sơ để đối chiếu:

lime_exp = LimeTabularExplainer(
    X_train.values,
    feature_names=list(X_train.columns),
    class_names=["tra_du", "vo_no"],
    mode="classification",
    random_state=0,
)
e = lime_exp.explain_instance(
    x.values[0], model.predict_proba, num_features=5
)
print(e.as_list())
# [('dti > 0.45', 0.21), ('late_payments_12m > 2', 0.17),
#  ('employment_months <= 6', 0.08), ('credit_age_years > 8', -0.06),
#  ('income <= 9000', 0.02)]

So thứ hạng và dấu, đừng so độ lớn

Output của SHAP và output của LIME vừa in ra đo bằng hai thước khác nhau. Trong ví dụ này, các giá trị SHAP đã được kiểm tra là cộng lại khớp đúng khoảng cách từ mức nền 0.12 tới dự đoán 0.41.

Trọng số LIME là hệ số của một model tuyến tính cục bộ fit trên các điều kiện như “dti > 0.45”, nên cộng chúng lại chẳng ra con số nào có ý nghĩa.

Vì thế khi đối chiếu, chỉ so hai thứ: feature nào đứng đầu và feature đó đẩy theo chiều nào.

Feature SHAP (hạng, giá trị) LIME (hạng, trọng số) Khớp?
Nợ trên thu nhập 1, +0.14 1, +0.21 Có
Trả chậm 12 tháng 2, +0.11 2, +0.17 Có
Thời gian làm việc 3, +0.06 3, +0.08 Có
Tuổi lịch sử tín dụng kéo xuống, −0.05 kéo xuống, −0.06 Có

Với ca 4127, ba lý do đầu khớp cả thứ hạng lẫn dấu. Lúc đó bạn có thể viết cho khách: tỷ lệ nợ trên thu nhập cao, có lịch sử trả chậm gần đây, thời gian làm công việc hiện tại còn ngắn. Ba câu cụ thể, mỗi câu gắn với một con số trong hồ sơ.

Năm bước để làm ở khách hàng

Đầu tiên, hỏi xem đội rủi ro muốn giải thích ở thang nào và ngưỡng duyệt là bao nhiêu, vì một lý do chỉ có nghĩa khi đặt cạnh ngưỡng. Sau đó chạy SHAP và kiểm tra phép cộng có khớp với output thật của model không. Kế tiếp, chạy LIME với vài random seed khác nhau rồi so thứ hạng và dấu với SHAP.

Bước thứ tư hay bị bỏ qua nhất: kiểm chứng trên chính model. Thử hạ tỷ lệ nợ trên thu nhập của hồ sơ 4127 xuống mức trung vị rồi gọi lại predict_proba.

Xác suất phải giảm rõ rệt; nếu không giảm, lý do số một của bạn chưa chính xác như CFPB đòi hỏi. Cuối cùng, ánh xạ tên feature sang câu chữ khách đọc hiểu được, và cho đội pháp chế duyệt bảng ánh xạ này một lần thay vì duyệt từng thư.

Ba cái bẫy khiến lý do sai mà trông vẫn đúng

Bẫy đầu tiên là feature tương quan. Tài liệu SHAP nhắc rằng giá trị SHAP dựa trên kỳ vọng có điều kiện, nên bạn phải chọn cách xử lý các feature phụ thuộc nhau, như thu nhập và số tiền vay.

Chế độ interventional cần tập nền; chế độ tree_path_dependent không cần, vì nó lấy số mẫu train đi qua mỗi lá làm phân phối nền. Hai chế độ có thể chia đóng góp khác nhau, nên hãy chốt một chế độ và ghi lại lý do chọn.

Bẫy kế tiếp là sự dao động của LIME. Theo cuốn Interpretable Machine Learning của Christoph Molnar, chọn vùng lân cận vẫn là bài toán chưa có lời giải khi dùng LIME với dữ liệu bảng. Vì vậy đừng dùng một lần chạy LIME làm bằng chứng; nếu top 3 thay đổi theo seed, nó chỉ là tín hiệu tham khảo.

Cái bẫy cuối nghiêm trọng hơn. Một nghiên cứu năm 2019 cho thấy các kỹ thuật giải thích dựa trên xáo trộn đầu vào như LIME và SHAP có thể bị một model được thiết kế đối nghịch đánh lừa, và các tác giả kết luận chúng không đáng tin.

Đó là lý do bước kiểm chứng bằng cách đổi dữ liệu thật ở trên là bắt buộc, không phải tùy chọn.

Thể hiện kỹ năng này trong CV thế nào

Khi đọc JD của fintech hay ngân hàng, hãy để ý các cụm như “model explainability”, “reason codes”, “adverse action”. Trong CV, đừng chỉ ghi “dùng SHAP”.

Hãy viết điều bạn đã giao: một pipeline sinh lý do từ chối cho từng hồ sơ, có kiểm tra phép cộng, đối chiếu với LIME và kiểm chứng bằng counterfactual.

Nếu ứng tuyển vào mảng tín dụng, hãy chuẩn bị kể lại từng bước đó qua một hồ sơ cụ thể, kèm những con số bạn đã kiểm tra.

Lần tới có email hỏi “vì sao hồ sơ này bị loại”, bạn không cần mở slide về độ chính xác của model nữa. Chỉ cần gửi phép cộng từ 0.12 lên 0.41, kèm bằng chứng rằng mỗi số hạng trong đó đều đã được kiểm chứng.

7 nguồn
Đọc tiếp trên lộ trình · Chặng 4: Khách hàngDemo prototype AI cho khách hàng: cho thấy cái đã chạy mà không hứa quá tayNgay sau buổi demo, khách có thể hỏi "tháng sau chạy được chưa". Mười giây trả lời của bạn sẽ quyết định không khí của mấy tháng làm việc sau đó.