[Kalapa Credit Challenge] Giải nhất đồng đội (with code)

machine-learning
data-science
kalapa

#1

Xin chào mọi người,

Mình xin cảm ơn Kalapa đã tổ chức và tài trợ cho cuộc thi này. Mình cũng xin gửi lời cảm ơn tới ban tổ chức và những bạn đã chia sẻ ý tưởng và cùng nhau thảo luận trong cuộc thi này. Mình cũng xin đặc biệt gửi lời cảm ơn đến anh Nguyen Chi Dung, người đã chia sẻ cách giải và giải thích chi tiết về WOE/IV.

Nhóm mình ban đầu chỉ là dân kinh tế mới học xong cơ bản về Python tham gia cuộc thi này với mục tiêu ban đầu là cái áo của ban tổ chức. Phải nói là nhóm mình rất may mắn khi đạt được giải nhất đồng đội ở rank 8.

Do team mình bắt đầu thực sự tham gia cuộc thi này khá muộn, nên nhóm tập trung vào phát triển trên ý tưởng của các đội đi trước. Tương tự như các đội khác, nhóm mình chia công việc thành 3 mảng chính: Data Preprocessing, Feature Engineering và Modeling.

Link Source code:

Data Preprocessing

Phần này, nhóm tiếp cận giống các đội khác, các phần xử lý bao gồm:

  • Map lại dữ liệu tỉnh thành
  • Map lại các dữ liệu boolean tuy nhiên ở dạng string
  • Đồng nhất kiểu biểu diễn missing values
  • Loại bỏ các giá trị ngoại lai trong các trường
  • Gộp 2 biến tuổi lại làm một, các tuổi <18 thì cho về nan.

Feature Engineering

Phần lớn thời gian nhóm mình sử dụng cho bước này. Nhóm cũng tìm cách tận dụng các trường dữ liệu khá đặc biệt gồm FIELD_7 và FIELD_3, do bọn mình chạy Feature important và dựa vào kết quả chạy AutoML thấy đây là 2 field có mức độ quan trọng cao nhất.

Với FIELD 7, nhìn bằng mắt có thể coi đây là dữ liệu dạng list. Vì thế, nhóm tiến hành ép kiểu dữ liệu cột này về list và thực hiện gen ra 1 số features như:

  • FIELD_7_LEN: Số lượng phần tử trong FIELD_7
  • Lựa chọn ra top 20 giá trị xuất hiện nhiều nhất trong các list tại cột FIELD 7, sinh ra các trường FIELD_7_value tương ứng để đếm số lượng value xuất hiện trong list

Tuy nhiên, sau khi thực hiện modeling cũng như submit kết quả lên cuộc thi thì team thấy chỉ có giá trị FIELD_7_LEN giúp cải thiện điểm trên bảng xếp hạng.

Với FIELD_3, qua quá trình data analysis, nhóm phát hiện ra điều khá đặc biệt về trường dữ liệu này dựa vào biểu đồ sau:

(Hình 1: Giá trị FIELD_3)

Nhìn kỹ có thể thấy các cụm giá trị của FIELD_3 này có khoảng cách khá đều nhau. Cụ thể, khoảng cách tâm của mỗi nhóm cách nhau chừng 365 ~ 1 năm.

(Hình 2: Phân bố giá trị residual của FIELD_3)

Từ đó, nhóm suy luận đây có thể là 1 giá trị có liên quan đến thời gian, có thể là trả nợ, hay đáo hạn, etc. Trong các sản phẩm tín dụng, các khoản loan thường được đưa về các mốc thời gian 6 tháng; 1 năm; 2 năm; etc. Việc trả gốc/lãi muộn so với mốc thời gian này sẽ dẫn đến việc đánh giá phân loại nhóm nợ (nhóm 1 đến nhóm 5) và từ đó xác định được tiềm lực tài chính và hành động tương ứng với các nhóm khách hàng. Trong khi đó việc trả trước cũng được đánh giá là một loại rủi ro cần quan tâm - prepayment risk. Các giá trị của FIELD_3 này dao động xung quanh các bội số của 365, vì thế có thể phần dư ra so với bội số (có thể là số ngày quá hạn|số ngày trả trước) sẽ đóng vai trò quan trọng trong việc xác định điểm tín dụng, vì thế với FIELD 3, nhóm sinh ra thêm các feature gồm:

  • FIELD_3_365: số lượng bội của 365 mà FIELD_3 gần nhất
  • FIELD_3_RESIDUAL: Phần bù của FIELD_3 so với bội mà nó gần nhất

Sau khi sinh được bộ feature mới, team sử dụng luôn phần WoE/IV transformation chia sẻ bởi anh Nguyen Chi Dung (https://rpubs.com/chidungkt/571838) để transform dữ liệu.

Modeling

Trong phần này, nhóm mình cũng thử nghiệm nhiều model như Random Forest, LightGBM, hay xài các công cụ automl của H2O và Google Cloud trên bộ dữ liệu đã được transform bằng WoE.

Tuy nhiên, trong quá trình tối ưu thì kết quả tập valid rất cao ~0.7x nhưng khi submit lên cuộc thi thì kết quả chỉ cỡ ~0.2x. Mất 1 thời gian cũng hơi nản vì suy nghĩ distribution của tập valid và tập test đang khác hẳn nhau, nhưng đọc kỹ lại thì thấy WoE transformation sử dụng thông tin của nhãn để transform dữ liệu, vì vậy nhãn của tập valid đã bị leak ra tập train nên dẫn tới hiện tượng này. Sau đó nhóm cũng sửa sai bằng cách chia tập train-valid trước khi thực hiện WoE transformation và tiến hành tối ưu model. Thời điểm này cũng khá bận với lười nên team đẩy trực tiếp data vào H2O AutoML để tối ưu model. Nhưng không hiểu sao kết quả tập valid lúc này vẫn không khả quan lắm chỉ cỡ 0.2x, chưa vượt qua được kết quả Random Forest nên cuối cùng nhóm sử dụng luôn Random Forest làm kết quả submit cuối cùng.

Conclusion

Kết quả cuối cùng của nhóm mình không overfit quá nhiều với điểm public: 0.28612, private: 0.2652.

Trên đây là phần xử lý của nhóm mình, hy vọng bài chia sẻ giúp mọi người hiểu hơn về cách làm của nhóm.


#2

thanks, bài viết rất hữu ích!


#3

Hay quá ạ. Bài viết có góc nhìn của dân kinh tế nữa nên khá thú vị ạ :smiley: