Kalapa's Credit Scoring Challenge - #17 Solution (21/01) , 0.22737 Gini Score

kalapa

#1

Giới thiệu

Dưới đây là lời giải của mình cho cuộc thi Kalapa’s Credit Scoring Challenge. Lời giải này đã đưa mình lên vị trí thứ 17 vào ngày 21/01/2020. Đây cũng là lần đầu tiên mình tham gia một cuộc thi dữ liệu dạng này nên mọi thứ mình làm đều là các bước tiếp cận cơ bản, phù hợp với các bạn mới, muốn xây dựng một baseline model.

EDA

Mình chưa dành nhiều thời gian cho visualisation, chỉ quan sát statistics của từng features và tìm ra được một vài điểm thú vị:

  • Một số numerical features có chứa các giá trị -1, nên mình dự đoán dữ liệu này đã được BTC impute missing values trước đó. Rồi thêm một bước loại bỏ để tạo missing values mới.
  • Nhiều features có số lượng missing values giống hệt nhau như FIELD_3,4,5,6 hay FIELD_16,21,22,50,51,52,53,54,55,56,57.
  • Các features FIELD_50,51,52,53 có giá trị trung bình giống nhau.
  • FIELD_50,52,53 là 3 features có các bộ giá trị min, 25th percentile, 50th percentile và 75th percentile bằng nhau.

Feature Engineering

Mình xác định có 3 dạng features cần xử lý theo các cách thức khác nhau.

1. Categorical và Boolean

cat_features = ['province', 'district', 'maCv',
                'FIELD_7', 'FIELD_8', 'FIELD_9',
                'FIELD_10', 'FIELD_13', 'FIELD_17', 
                'FIELD_24', 'FIELD_35', 'FIELD_39', 
                'FIELD_41', 'FIELD_42', 'FIELD_43', 
                'FIELD_44']

bool_features = ['FIELD_2', 'FIELD_18', 'FIELD_19', 
                 'FIELD_20', 'FIELD_23', 'FIELD_25', 
                 'FIELD_26', 'FIELD_27', 'FIELD_28', 
                 'FIELD_29', 'FIELD_30', 'FIELD_31', 
                 'FIELD_36', 'FIELD_37', 'FIELD_38', 
                 'FIELD_47', 'FIELD_48', 'FIELD_49'

2. Numerical

num_features = [col for col in all_data.columns if col not in cat_features+bool_features]

Categorical & Boolean Features

1. Missing and None values

  • NaN/na values: Đối categorical features, mình tạo một feature đếm tổng số giá trị NaN/na trên từng dòng. Sau đó mình fill toàn bộ NaN values với giá trị “Missing”.
  • None values: Tương tự như NaN/na values, mình tạo một feature tính tổng số giá trị None trên từng dòng.

2. Categorical features với nhiều hơn 10 unique values

  • Mình dùng kỹ thuật Count Encoding cho từng feature.

3. Categorical features với ít hơn 10 unique values + Boolean features

  • Mình sử dụng cả 2 kỹ thuật là Count EncodingOne-hot Encoding cho từng feature.

4. Ordinal categorical features

  • Có 5 categorical features với giá trị là text nhưng mang hàm ý thứ tự (ví dụ: Zero, One, Two, Three, A,B, C, D…) nên mình chuyển sang dạng số cho từng feature.

Kết quả là mình đã có 191 features mới sau khi thực hiện hết các kỹ thuật trên.

Numerical Features

  • age_mean: Mình tạo thêm một feature mới là age_mean, so sánh giá trị của age_source1, age_source2 với nhau, giống nhau thì giữ nguyên, khác nhau thì lấy giá trị trung bình. Loại bỏ các giá trị tuổi với nhỏ hơn 18, coi như là missing values.
  • Toàn bộ giá trị None mình mã hóa thành -2
  • Một số numerical features chứa giá trị nhiễu như ‘HT’ ‘GD’, ‘02 05 08 11’,… mình mã hóa thành -1
  • Với mỗi numerical features chứa missing values, mình tạo một boolean feature tương ứng để biểu thị việc thiếu thông tin này.
  • Cuối cùng, với mỗi feature mình impute missing values bằng cả 3 phương pháp: constant value (-1), median và mean.

Kết quả của các bước trên, mình có thêm 88 features mới.

Label Mean Features

  • Mình dùng thư viện scikit-learn để tạo các features mới là giá trị label trung bình của 500 đến 5000 nearest neighbors cho mỗi dòng.
  • Đây là những features quan trọng nhất giúp model của mình tăng đến 0.02 điểm Gini.

Modelling

  • Mình dùng LightGBM + 5-fold CV với bộ features trên, mô hinh bị overfitting nhẹ. Validation score của mình rất cao, từ 0.25-0.4 nhưng điểm số đạt được tối đa trên LB là 0.21642. gini
  • Đưa bộ features trên lên AutoML, mình đạt được điểm số 0.22449.
  • Sau khi chạy nhiều lần LightGBM với các bộ hyperparameters khác nhau, mình lựa chọn một số file kết quả có điểm Gini > 0.21, cộng thêm file kết quả từ AutoML. Tính giá trị trung bình từ các file này, Gini score của mình tăng thêm một chút, đạt 0.22737 và là kết quả tốt nhất cho đến thời điểm hiện tại của mình.

What’s next?

  • Mình sẽ tiếp tục tìm kiếm ý tưởng để tạo thêm các features mới.
  • Tune hyperparameters cho model hiện tại.
  • Xây dựng thêm models với XGBoost, Neural Networks,…
  • Thực hiện các kỹ thuật ensemble nâng cao.

Chúc các bạn thi đấu vui vẻ!


Kalapa’s Credit Scoring Challenge - #13 Solution (02/02) , 0.2729 Gini Score
#2

Trên cả tuyệt với, thay mặt cho ban tổ chức & công ty Kalapa, mình cảm ơn bạn đã chia sẻ kiến thức quý & hiếm để nhiều teams học hỏi ngay trong thời gian thi. Các bạn có cơ hội thực hành ngay & luôn được trải nghiệm cảm giác lên hạng!!! Vô cùng tuyệt với.


#3

Bài viết rất có tâm :smile:


#4

Cám ơn bạn vì đã chia sẻ, bài viết rất hữu ích.

Bạn có thể giải thích rõ hơn cách tạo “Label Mean Features” của bạn được không ? Mình đọc mà chưa hiểu cách bạn làm thế nào. Label trung bình là trung bình của cái gì ?

Cám ơn bạn.

P.S: Mình là newbie nên bạn thông cảm


#5

Label ở đây là giá trị (0, 1) của cột label mà mình đang cần predict. “Label mean” là giá trị trung bình của labels của K nearest neighbors nha bạn.

Không biết bạn đã hiểu ý mình chưa? :smiley:


#6

Ok, mình hiểu rồi, cám ơn bạn.


#7

Chào bạn. Cám ơn bạn đã chia sẻ approach của bạn, rất hữu ích cho các newbie như mình :smiley:

Mình cũng đang làm theo hướng dẫn của bạn, tuy nhiên điểm hiện tại rất thấp (0.16-0.18 trên public leader board, CV nằm từ 0.18-0.3 tùy fold). Vậy nên mình muốn hỏi bạn 1 vài câu hỏi, hi vọng bạn có thể chia sẻ :smile:

  1. Trước khi sử dụng knn features để sinh Label Mean Features thì validation score / public LB score là bao nhiêu?
  2. Với LightGBM, bạn có sử dụng categorical_feature không?(https://lightgbm.readthedocs.io/en/latest/Advanced-Topics.html#categorical-feature-support)
  3. Các Cat./Bool features thì sau khi bạn sử dụng One-hot và Count Encoding, bạn có bỏ nó ra khỏi các cột ko?
  4. Nếu được, bạn có thể cho mình biết hyper-parameter của LighGBM trong thí nghiệm này được ko? Mình có thử default parameter, lẫn tune hypter-param nhưng kết quả vẫn không khả quan hơn.

#8

Chào bạn, cảm ơn bạn đã đặt câu hỏi. Mình xin trả lời như sau:

  1. Dùng label mean features giúp mình tăng từ ~0.19 đến ~0.22 với solution này. Với solution sau thì tăng từ ~0.24 lên ~0.27.

  2. Mình không dùng categorical_feature mà tự encode categorical features trước khi đưa vào mô hình. Chắc mình sẽ thử categorical_feature và xem kết quả thay đổi ra sao.

  3. Mình có loại bỏ cat_features + bool_features sau khi encoding

  4. Đây là hyperparameters của mình clf = LGBMClassifier( nthread=4, n_estimators=10000, learning_rate=0.02, num_leaves=128, colsample_bytree=0.9497036, subsample=0.8715623, max_depth=8, reg_alpha=0.041545473, reg_lambda=0.0735294, min_split_gain=0.0222415, min_child_weight=39.3259775, silent=-1, verbose=-1)


#9

Theo mình hiểu thì dạng này là stacking, dùng các model KNN predict lấy mean để tạo ra các feature, LGBM là model cuối phải không bạn?


#10

Cái này chưa phải stacking bạn ạ. Chỉ đơn giản là tạo thêm 1 feature mới, thêm vào bộ feature cũ rồi dùng LightGBM để predict thôi.


#11

Bạn ơi, cho mình hỏi làm sao để lấy được các labels của K nearest neighbors để sau đó tính trung bình hả bạn? Cám ơn bạn :slight_smile:


#12

labels ở đây chính là giá trị của cột label mà bạn đang phải dự đoán đó ạ


#13

Bạn ơi :slight_smile: file code của bạn bị lỗi rồi. Bạn úp lên lại cho mọi người đọc được không bạn ơi. Mình cám ơn bạn nhiều