Bài tập lớn môn Big Data: dự đoán khoản vay Lending Club sẽ được trả đủ hay bị xóa nợ trên 2,26 triệu bản ghi bằng PySpark (Spark SQL + MLlib), từ EDA, mã hóa đặc trưng, cân bằng lớp đến so sánh Logistic Regression, Random Forest, Decision Tree theo ROC AUC và PR AUC.
Hoàng Quang Huy – Trường Đại học Sư phạm Kỹ thuật Hưng Yên. Toàn bộ code nằm trong BTL_BigDATA.ipynb.
| Hạng mục | Nội dung |
|---|---|
| Dữ liệu | Lending Club (datasetlending.csv): 2.260.701 dòng |
| Nhãn | loan_status → target: Fully Paid = 0 (1.018.715), Charged Off = 1 (247.260); bỏ các trạng thái khác |
| Đặc trưng | 21 cột sau xử lý (số + chỉ số/one-hot) → VectorAssembler → MinMaxScaler |
| Cân bằng lớp | Undersampling lớp 0 (30%) và Oversampling lớp 1 (lấy mẫu có hoàn lại) |
| Chia tập | 80% train / 10% validation / 10% test (randomSplit, seed 42) |
| Mô hình | LogisticRegression, RandomForestClassifier, DecisionTreeClassifier (Spark MLlib) |
| Kết quả tốt nhất | Random Forest: ROC AUC test 0,926–0,928, PR AUC test 0,892–0,905 |
- Nạp dữ liệu bằng
SparkSession.read.csv, xem schema, thống kê và đếm giá trị thiếu theo từng cột. - EDA & xử lý từng cột bằng
groupBy().count()và biểu đồ (chuyển sang Pandas để vẽ):purpose: gộp các mục có < 300 bản ghi thànhother, rồi one-hot encode.term: trích số tháng bằngregexp_extract→ số nguyên.verification_status: mã hóa nhị phân (đã xác minh / chưa xác minh).grade:StringIndexer;home_ownership,addr_state,initial_list_status: one-hot encode.emp_length,sub_grade: chuẩn hóa / loại bỏ; ép kiểu các cột số sangfloat.loan_status→target(0/1), loại các khoản vay đang chạy hoặc trễ hạn.
- Cân bằng lớp (lớp 0 nhiều gấp ~4 lần lớp 1):
- Undersampling: lấy mẫu 30% lớp 0 → 305.997 / 247.260.
- Oversampling: nhân bản lớp 1 có hoàn lại → 1.018.715 / 1.018.820.
- Vector hóa & chuẩn hóa:
VectorAssemblergom 21 đặc trưng,MinMaxScalerđưa về [0, 1]. - Huấn luyện & đánh giá bằng hàm
evaluate_model()dùng chung: tính ROC AUC và PR AUC (BinaryClassificationEvaluator) trên cả train, validation và test. - Tinh chỉnh:
ParamGridBuilder(numTrees ∈ {10, 50, 100}, maxDepth ∈ {5, 10, 15}) +CrossValidator5 fold cho Random Forest.
Các đặc trưng cuối cùng gồm: term, loan_amnt, int_rate, installment, annual_inc, dti, acc_now_delinq, application_type, tax_liens, delinq_amnt, policy_code, last_fico_range_high, last_fico_range_low, recoveries, collection_recovery_fee, verification_status_encoded, grade_index, purpose_encoded, addr_state_encoded, home_ownership_encoded, initial_list_status_encoded.
| Mô hình | ROC AUC (train) | ROC AUC (val) | ROC AUC (test) | PR AUC (test) |
|---|---|---|---|---|
| Logistic Regression | 0,926 | 0,926 | 0,925 | 0,881 |
| Random Forest | 0,927 | 0,930 | 0,928 | 0,892 |
| Decision Tree | 0,875 | 0,880 | 0,874 | 0,755 |
| Mô hình | ROC AUC (train) | ROC AUC (val) | ROC AUC (test) | PR AUC (test) |
|---|---|---|---|---|
| Logistic Regression | 0,926 | 0,925 | 0,923 | 0,899 |
| Random Forest | 0,925 | 0,924 | 0,926 | 0,905 |
| Decision Tree | 0,874 | 0,874 | 0,874 | 0,794 |
Nhận xét:
- Random Forest cho kết quả tốt nhất ở cả hai cách cân bằng; Logistic Regression bám sát phía sau với chi phí tính toán thấp hơn nhiều.
- Chỉ số train, validation và test gần như bằng nhau → các mô hình không bị overfitting.
- Oversampling giữ lại toàn bộ dữ liệu lớp đa số nên PR AUC cao hơn undersampling.
pip install pyspark pandas numpy matplotlib scikit-learn imbalanced-learn jupyter
jupyter notebook BTL_BigDATA.ipynbCần Java (JDK 8/11) cho Spark. File dữ liệu datasetlending.csv (Lending Club, Kaggle) không đi kèm repo, đặt cùng thư mục với notebook trước khi chạy.
Apache Spark (PySpark SQL, MLlib: StringIndexer, OneHotEncoder, VectorAssembler, MinMaxScaler, CrossValidator) · Pandas · NumPy · Matplotlib · Jupyter