
浙大疏锦行---------------------- 1. 导入所有依赖库 ----------------------import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport warningswarnings.filterwarnings(“ignore”)from sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.linear_model import LogisticRegressionfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.metrics import (accuracy_score, precision_score, recall_score, f1_score,roc_auc_score, roc_curve, precision_recall_curve, auc)设置中文显示避免图表乱码plt.rcParams[‘font.sans-serif’] [‘SimHei’]plt.rcParams[‘axes.unicode_minus’] False---------------------- 2. 读取数据 ----------------------读取同目录下的 data.csvdf pd.read_csv(rC:\Python Study\Python60DaysChallenge-main\data.csv)标签列Credit Default1违约0正常target_col “Credit Default”查看数据基本信息print(“” * 60)print(“数据基本信息”)print(“” * 60)print(f样本总数{df.shape[0]}特征总数{df.shape[1]-1}“)print(f正负样本分布\n{df[target_col].value_counts()}”)print(f违约占比{df[target_col].mean():.2%}“)print(”\n)---------------------- 3. 数据预处理 ----------------------3.1 分离特征与标签X df.drop(target_col, axis1)y df[target_col]3.2 处理缺失值数值型用中位数填充类别型用众数填充num_cols X.select_dtypes(include[np.number]).columnscat_cols X.select_dtypes(exclude[np.number]).columnsX[num_cols] X[num_cols].fillna(X[num_cols].median())for col in cat_cols:X[col] X[col].fillna(X[col].mode()[0])3.3 类别特征独热编码X pd.get_dummies(X, columnscat_cols, drop_firstTrue)3.4 划分训练集和测试集保持正负样本比例X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.3, random_state42, stratifyy)3.5 数值特征标准化scaler StandardScaler()X_train_scaled scaler.fit_transform(X_train)X_test_scaled scaler.transform(X_test)print(“” * 60)print(“数据预处理完成”)print(“” * 60)print(f训练集样本数{X_train.shape[0]}测试集样本数{X_test.shape[0]}“)print(f预处理后特征数{X_train.shape[1]}”)print(“\n”)---------------------- 4. 定义待对比模型 ----------------------models {“逻辑回归”: LogisticRegression(random_state42, class_weight“balanced”, max_iter1000),“决策树”: DecisionTreeClassifier(random_state42, class_weight“balanced”),“随机森林”: RandomForestClassifier(n_estimators150, random_state42, class_weight“balanced”, n_jobs-1),“K近邻”: KNeighborsClassifier(n_neighbors5)}---------------------- 5. 批量训练 计算评估指标 ----------------------metrics_result []roc_dict {}pr_dict {}for model_name, model in models.items():print(f正在训练{model_name}…)# 逻辑回归和KNN用标准化后的数据树模型用原始数据 if model_name in [逻辑回归, K近邻]: model.fit(X_train_scaled, y_train) y_pred model.predict(X_test_scaled) y_prob model.predict_proba(X_test_scaled)[:, 1] else: model.fit(X_train, y_train) y_pred model.predict(X_test) y_prob model.predict_proba(X_test)[:, 1] # 计算核心评估指标 acc accuracy_score(y_test, y_pred) precision precision_score(y_test, y_pred) recall recall_score(y_test, y_pred) f1 f1_score(y_test, y_pred) roc_auc roc_auc_score(y_test, y_prob) # 计算PR曲线及PR-AUC precision_curve, recall_curve, _ precision_recall_curve(y_test, y_prob) pr_auc auc(recall_curve, precision_curve) # 保存结果 metrics_result.append({ 模型名称: model_name, 准确率 Accuracy: round(acc, 4), 精确率 Precision: round(precision, 4), 召回率 Recall: round(recall, 4), F1分数: round(f1, 4), ROC-AUC: round(roc_auc, 4), PR-AUC: round(pr_auc, 4) }) # 保存曲线数据 fpr, tpr, _ roc_curve(y_test, y_prob) roc_dict[model_name] (fpr, tpr, roc_auc) pr_dict[model_name] (recall_curve, precision_curve, pr_auc)打印评估指标总表metrics_df pd.DataFrame(metrics_result)print(“\n”)print(“” * 80)print(“各模型信贷风控评估指标汇总”)print(“” * 80)print(metrics_df.to_string(indexFalse))print(“\n”)---------------------- 6. 绘制ROC曲线 ----------------------plt.figure(figsize(10, 6), dpi100)plt.plot([0, 1], [0, 1], “k–”, linewidth1, label“随机猜测 (AUC0.5)”)for name, (fpr, tpr, auc_val) in roc_dict.items():plt.plot(fpr, tpr, linewidth2, labelf{name} (AUC{auc_val:.4f}))plt.xlabel(“假正率 FPR”, fontsize12)plt.ylabel(“真正率 TPR”, fontsize12)plt.title(“各模型 ROC 曲线对比”, fontsize14)plt.legend(loc“lower right”, fontsize10)plt.grid(alpha0.3)plt.tight_layout()plt.show()---------------------- 7. 绘制PR曲线 ----------------------plt.figure(figsize(10, 6), dpi100)pos_ratio y_test.mean()plt.axhline(ypos_ratio, color“k”, linestyle“–”, linewidth1,labelf随机猜测 (基准{pos_ratio:.3f}))for name, (recall_curve, precision_curve, auc_val) in pr_dict.items():plt.plot(recall_curve, precision_curve, linewidth2,labelf{name} (AUC{auc_val:.4f}))plt.xlabel(“召回率 Recall”, fontsize12)plt.ylabel(“精确率 Precision”, fontsize12)plt.title(“各模型 PR 曲线对比不平衡数据场景”, fontsize14)plt.legend(loc“lower left”, fontsize10)plt.grid(alpha0.3)plt.tight_layout()plt.show()---------------------- 8. 模型能力解读作业分析参考 ----------------------print(“” * 80)print(“信贷风控视角下的模型能力理解要点”)print(“” * 80)print(“1. ROC-AUC衡量模型整体区分好坏客户的能力越接近1表示整体排序能力越强”)print(“2. PR-AUC针对信贷数据正负样本不平衡比ROC更敏感更能反映对违约样本的识别能力”)print(“3. 召回率代表能识别出多少真实违约客户值越高漏判的坏账越少”)print(“4. 精确率代表预测为违约的客户中真违约的比例值越高误拒的正常客户越少”)print(“5. 逻辑回归可解释性强是风控行业基线模型随机森林等集成模型预测精度更高”)print(“6. 实际风控中需要在召回率和精确率之间做权衡根据业务成本选择最优阈值。”)