尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

信贷风控实战:从数据预处理到模型调优的完整数据挖掘流程解析

信贷风控实战:从数据预处理到模型调优的完整数据挖掘流程解析 1. 项目概述从一道赛题看信贷风控的实战演练最近在整理过往的竞赛项目翻到了“国赛-19C”这道关于信贷决策的经典数据挖掘题。这道题可以说是很多数据科学从业者尤其是想进入金融科技领域的朋友绕不开的一个“练手”项目。它模拟了一个非常真实的场景给你一堆脱敏后的用户申请数据让你去判断这个人会不会违约也就是我们常说的“好客户”还是“坏客户”。这听起来简单不就是个二分类问题吗但真做起来从数据理解、特征工程到模型构建与评估每一步都藏着不少门道和“坑”。今天我就以这道赛题为蓝本结合我这些年做风控模型的经验从头到尾拆解一遍把那些教科书里不会写的、只有踩过坑才知道的细节都摊开来聊聊。无论你是正在准备相关竞赛的学生还是刚转行做数据挖掘的工程师相信这篇“事后复盘”式的总结都能给你带来一些直接的启发和可复现的参考。2. 赛题核心与数据初探理解你要解决的真实问题2.1 问题本质信贷场景下的二分类预测首先我们必须明确我们面对的是一个什么样的业务问题。题目是“信贷决策问题”决策的核心就是“是否放贷”。从机器学习的角度看这是一个标准的监督学习二分类任务。我们的目标是构建一个模型能够根据用户申请时提交的各项信息如年龄、收入、职业、历史信用记录等预测其未来发生违约即成为“坏客户”的概率。这里需要立刻建立两个关键认知业务的不对称性预测错误的代价是不对等的。把“坏客户”误判为“好客户”False Negative意味着银行将直接承受贷款损失而把“好客户”误判为“坏客户”False Positive银行损失的只是一次潜在的利息收入机会。因此我们的模型必须对“坏客户”有更高的识别能力这直接影响了后续评估指标的选择和模型阈值的调整。数据的局限性竞赛数据是脱敏和加工过的它剥离了具体的业务背景和字段含义但保留了真实数据中的典型问题如缺失值、类别不平衡、特征量纲不一等。我们的工作就是在这种“半盲”状态下通过技术手段挖掘出有效的预测模式。2.2 数据加载与初步观察拿到数据通常是train.csv和test.csv后别急着跑模型。前期的“侦察”工作决定了后续战役的成败。我会用Python的Pandas和Matplotlib/Seaborn库来做这件事。import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 加载数据 train_data pd.read_csv(train.csv) test_data pd.read_csv(test.csv) print(f训练集形状: {train_data.shape}) print(f测试集形状: {test_data.shape}) # 查看前几行 print(train_data.head()) # 查看基本信息 print(train_data.info()) # 查看数值型特征的统计摘要 print(train_data.describe()) # 查看目标变量分布 print(train_data[label].value_counts()) print(f坏客户比例: {train_data[label].mean():.2%})关键操作与解读data.shape立刻知道你有多少样本行和特征列。国赛数据通常特征维度不低可能有上百维。data.info()这是你的第一张“体检报告”。重点关注数据类型哪些是object通常是字符串/类别哪些是int/float这决定了后续的处理方式。非空计数一眼看出哪些特征存在大量缺失Non-Null Count远小于总行数。缺失值处理是特征工程的第一道坎。data.describe()针对数值型特征查看均值、标准差、分位数等。要特别警惕异常值max值是否大得离谱例如年龄出现200岁收入出现负数或天文数字。分布情况通过50%中位数和mean均值的对比可以初步感知数据是否偏斜。目标变量分布这是至关重要的一步。如果label1代表坏客户那么label的均值就是坏客户率。在信贷场景中这个比例通常很低比如2%-5%这就是典型的类别不平衡问题。如果训练集中坏客户只占3%而测试集也是类似分布那么一个把所有客户都预测为“好”的傻瓜模型准确率也能达到97%但这毫无意义。我们必须使用精确率、召回率、F1-Score、AUC-ROC等指标并考虑过采样、欠采样或代价敏感学习等方法。注意在真实业务中我们称之为“违约率”或“坏账率”。竞赛数据为了脱敏常用label、target或isDefault等字段名。务必先确认数据说明文档如果有的话搞清楚0和1分别代表什么。3. 数据预处理与特征工程从脏数据中提炼黄金数据预处理和特征工程往往占据一个数据挖掘项目70%以上的时间和精力其效果直接决定了模型性能的天花板。3.1 缺失值处理不是简单填充了事缺失值处理没有银弹需要根据特征的含义和缺失机制来制定策略。分析缺失模式使用train_data.isnull().sum().sort_values(ascendingFalse)来查看每个特征的缺失数量。甚至可以画一个缺失值热力图观察缺失是否集中在某些样本或某些特征上这可能是某种业务逻辑导致如只有特定人群才需要填写某项信息。制定填充策略数值型特征若缺失很少如5%且分布近似正态可用均值填充。若分布偏斜有异常值使用中位数填充更稳健。更高级的做法将其视为一个预测问题用其他特征来建模预测缺失值。但在竞赛中为效率计中位数是常用选择。类别型特征最常用的是用众数出现最频繁的类别填充。可以创建一个新的类别如“MISSING”用来表示“缺失”本身可能就是一种信息例如不愿填写某项信息的客户可能风险更高。考虑删除如果某个特征缺失率极高比如超过50%并且业务上难以解释可以考虑直接删除该特征。同样如果某一行样本在关键特征上大量缺失也可以考虑删除该样本但要谨慎避免引入偏差。# 示例分别处理数值型和类别型缺失 numeric_features train_data.select_dtypes(include[np.number]).columns categorical_features train_data.select_dtypes(include[object]).columns # 数值型用中位数填充 for col in numeric_features: if train_data[col].isnull().any(): median_val train_data[col].median() train_data[col].fillna(median_val, inplaceTrue) test_data[col].fillna(median_val, inplaceTrue) # 注意要用训练集的中位数填测试集 # 类别型用众数填充并增加“MISSING”标志位 for col in categorical_features: if train_data[col].isnull().any(): mode_val train_data[col].mode()[0] train_data[col].fillna(mode_val, inplaceTrue) test_data[col].fillna(mode_val, inplaceTrue) # 可以增加一个缺失指示特征 train_data[col_is_missing] train_data[col].isnull().astype(int) test_data[col_is_missing] test_data[col].isnull().astype(int)实操心得处理测试集缺失值时务必使用从训练集计算出的统计量如中位数、众数而不是在测试集上重新计算。这是数据泄露的常见陷阱模型上线后对新样本的处理必须完全复用训练时学到的规则。3.2 异常值处理辨别“噪音”与“信号”异常值可能是数据录入错误也可能是真实的高风险个案如极端高负债者。不能武断删除。可视化发现对关键数值特征绘制箱线图Boxplot或直方图直观查看离群点。统计方法判定常用IQR四分位距法。将超出[Q1 - 1.5*IQR, Q3 1.5*IQR]范围的值视为温和异常值超出[Q1 - 3*IQR, Q3 3*IQR]的视为极端异常值。业务逻辑判定这是更可靠的方法。例如年龄范围应在18-70岁左右收入应为正数信用卡持有数量不可能为负数等。结合对字段的猜测尽管已脱敏来设定合理范围。处理方式修正如果明确是错误如年龄300岁且样本量不大可以按业务逻辑修正为边界值或设为缺失。盖帽对于需要保留的异常值常用“盖帽法”Winsorization将超出99分位数和1分位数的值分别用99分位数和1分位数的值替代。分箱将连续值离散化到几个区间中异常值会被归入最高或最低的箱这也是常用的风控建模技巧。# 示例使用IQR法检测并盖帽处理某个数值特征‘income’ Q1 train_data[income].quantile(0.25) Q3 train_data[income].quantile(0.75) IQR Q3 - Q1 lower_bound Q1 - 1.5 * IQR upper_bound Q3 1.5 * IQR # 盖帽 train_data[income_capped] np.clip(train_data[income], lower_bound, upper_bound) # 对测试集应用相同的边界 test_data[income_capped] np.clip(test_data[income], lower_bound, upper_bound)3.3 特征编码让计算机理解类别信息机器学习模型无法直接处理“男”、“女”这样的文本必须转化为数字。有序类别特征如果类别有内在顺序如学历高中本科硕士博士使用标签编码Label Encoding即赋予0,1,2,3...的整数。但要注意很多模型如树模型会认为数字大小有意义所以只有当顺序确实存在时才用。无序类别特征绝大多数情况属于此类。必须使用独热编码One-Hot Encoding。它为每个类别创建一个新的二进制特征0或1。例如“职业”有3类就生成3个新特征“职业_工程师”、“职业_教师”、“职业_其他”样本属于哪一类对应的特征就是1其余为0。注意维度爆炸如果某个类别特征取值非常多如“城市”有几百个独热编码会产生大量稀疏特征。此时可以考虑频数编码用该类别的出现频率来替代。目标编码用该类别下目标变量这里是违约率的均值来替代。这是风控建模中非常强大但需谨慎使用的技巧极易造成数据泄露必须放在交叉验证的循环中进行或在训练集上编码后映射到测试集。from sklearn.preprocessing import OneHotEncoder # 假设 ‘occupation’ 是一个无序类别特征 encoder OneHotEncoder(sparse_outputFalse, handle_unknownignore) # handle_unknownignore 防止测试集出现新类别报错 occupation_encoded encoder.fit_transform(train_data[[occupation]]) # 将编码后的特征转换为DataFrame并合并回原数据 occupation_df pd.DataFrame(occupation_encoded, columnsencoder.get_feature_names_out([occupation])) train_data pd.concat([train_data.drop(occupation, axis1), occupation_df], axis1) # 对测试集进行转换使用训练集拟合好的encoder test_occupation_encoded encoder.transform(test_data[[occupation]]) test_occupation_df pd.DataFrame(test_occupation_encoded, columnsencoder.get_feature_names_out([occupation])) test_data pd.concat([test_data.drop(occupation, axis1), test_occupation_df], axis1)3.4 特征构造与选择发挥创造力的舞台这是提升模型性能的关键也是区分新手和老手的地方。业务逻辑构造尽管数据脱敏但我们可以根据常见的风控维度进行猜测和构造。负债比率如果数据中有“月收入”和“总负债”可以构造“负债收入比”。信贷历史密度如果有“首次信贷时间”和“信贷账户数”可以构造“平均每年开立账户数”。行为交叉特征将类别特征两两组合形成新的交叉特征再编码。例如“职业”和“教育程度”的组合可能揭示更细分的客群风险。数值特征分箱Binning将连续变量如“年龄”、“收入”离散化为几个区间如20-3030-40...。这有助于捕捉非线性关系并且对异常值不敏感。分箱后通常再进行独热编码或序数编码。特征选择在构造了大量特征后需要剔除冗余和不相关的特征防止过拟合加快训练速度。过滤法计算每个特征与目标变量的相关性如卡方检验、互信息、相关系数保留排名靠前的。包裹法如递归特征消除RFE通过模型性能来评价特征子集的好坏效果更好但计算成本高。嵌入法利用模型训练过程中的指标如树模型的feature_importances_线性模型的系数绝对值来选择特征。这是最常用且高效的方法。from sklearn.ensemble import RandomForestClassifier from sklearn.feature_selection import SelectFromModel # 使用随机森林进行特征重要性排序和选择 X_train train_data.drop(label, axis1) y_train train_data[label] rf RandomForestClassifier(n_estimators100, random_state42, n_jobs-1) rf.fit(X_train, y_train) # 查看特征重要性 importances pd.DataFrame({feature: X_train.columns, importance: rf.feature_importances_}) importances importances.sort_values(importance, ascendingFalse) print(importances.head(20)) # 根据重要性阈值选择特征 selector SelectFromModel(rf, thresholdmedian, prefitTrue) # 选择重要性在中位数以上的特征 X_train_selected selector.transform(X_train) selected_features X_train.columns[selector.get_support()] print(fSelected {len(selected_features)} features.)4. 模型构建、训练与调优寻找最优的预测机器预处理完成后我们进入模型环节。对于结构化数据的二分类问题树模型及其集成方法通常是首选。4.1 模型选型与基准建立不要一开始就追求最复杂的模型。建立一个简单的基准模型至关重要。逻辑回归优秀的基准模型。它简单、可解释性强可以作为性能的底线。如果更复杂的模型无法显著超越逻辑回归说明特征工程可能有问题。决策树/随机森林随机森林是这类问题的“万金油”对异常值不敏感能处理非线性关系自带特征重要性评估且不太容易过拟合相比单棵决策树。梯度提升树如XGBoost、LightGBM、CatBoost是当前竞赛和工业界的霸主。它们精度高速度快功能强大如自动处理缺失值、类别特征。国赛19C这类题目最终前排方案几乎都使用了它们。第一步划分验证集在动测试集之前必须从训练集中分出一部分作为本地验证集用于评估模型性能和调参。from sklearn.model_selection import train_test_split # 假设 X 是特征矩阵y 是标签 X train_data.drop(label, axis1) y train_data[label] X_train, X_val, y_train, y_val train_test_split(X, y, test_size0.2, random_state42, stratifyy) # stratifyy 非常重要确保训练集和验证集中好坏客户的比例与原数据集一致。第二步训练基准模型并评估from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report, roc_auc_score, f1_score # 逻辑回归基准 lr LogisticRegression(max_iter1000, random_state42) lr.fit(X_train, y_train) y_val_pred_lr lr.predict(X_val) y_val_proba_lr lr.predict_proba(X_val)[:, 1] print(逻辑回归性能:) print(classification_report(y_val, y_val_pred_lr)) print(fAUC-ROC: {roc_auc_score(y_val, y_val_proba_lr):.4f}) print(fF1-Score: {f1_score(y_val, y_val_pred_lr):.4f}) # 随机森林基准 rf RandomForestClassifier(n_estimators100, random_state42, n_jobs-1) rf.fit(X_train, y_train) y_val_pred_rf rf.predict(X_val) y_val_proba_rf rf.predict_proba(X_val)[:, 1] print(\n随机森林性能:) print(classification_report(y_val, y_val_pred_rf)) print(fAUC-ROC: {roc_auc_score(y_val, y_val_proba_rf):.4f}) print(fF1-Score: {f1_score(y_val, y_val_pred_rf):.4f})4.2 应对类别不平衡让模型“看见”少数类在风控中我们更关心召回“坏客户”的能力。默认的模型会偏向多数类。调整类别权重大多数分类器如逻辑回归、随机森林、XGBoost都提供class_weight参数。可以设置为‘balanced’让算法自动根据类别频率调整权重或者手动指定例如{0: 1, 1: 5}意味着误判一个坏客户的代价是误判一个好客户的5倍。重采样技术过采样增加少数类样本的复制或生成新样本如SMOTE算法。风险是可能过拟合。欠采样随机减少多数类样本。风险是丢失信息。综合采样结合过采样和欠采样。使用更适合的评估指标不要只看准确率。重点关注精确率预测为坏的客户中真正坏的比例。代表放贷决策的“安全性”。召回率所有真正的坏客户中被模型找出来的比例。代表模型的“查全能力”。F1-Score精确率和召回率的调和平均数是综合考量。AUC-ROC模型整体排序能力的体现对类别不平衡不敏感是风控模型最核心的指标之一。KS值风控特有指标衡量模型区分好坏客户的能力值越大越好通常0.3认为模型有区分能力。# 以随机森林为例使用类别权重 rf_balanced RandomForestClassifier(n_estimators100, random_state42, class_weightbalanced, n_jobs-1) rf_balanced.fit(X_train, y_train) y_val_pred_bal rf_balanced.predict(X_val) print(classification_report(y_val, y_val_pred_bal)) # 你会发现对坏客户label1的召回率通常会有提升4.3 模型调优从“能用”到“好用”基准模型性能达标后通过调参来挖掘模型潜力。这里以LightGBM为例因为它速度快、效率高非常适合此类竞赛。import lightgbm as lgb from sklearn.model_selection import GridSearchCV, RandomizedSearchCV # 创建LightGBM数据集 train_set lgb.Dataset(X_train, labely_train) val_set lgb.Dataset(X_val, labely_val, referencetrain_set) # 设置初始参数 params { objective: binary, # 二分类 metric: auc, # 评估指标 boosting_type: gbdt, learning_rate: 0.05, num_leaves: 31, max_depth: -1, # -1表示不限 min_child_samples: 20, subsample: 0.8, # 行采样 colsample_bytree: 0.8, # 列采样 reg_alpha: 0, # L1正则 reg_lambda: 0, # L2正则 random_state: 42, n_jobs: -1, verbose: -1, is_unbalance: True # 处理不平衡数据等同于设置class_weight } # 早期停止法训练 model lgb.train(params, train_set, num_boost_round10000, # 设置一个很大的轮数 valid_sets[val_set], callbacks[lgb.early_stopping(stopping_rounds100), lgb.log_evaluation(100)]) # 早停与日志 # 预测 y_val_proba_lgb model.predict(X_val, num_iterationmodel.best_iteration) print(fLightGBM AUC: {roc_auc_score(y_val, y_val_proba_lgb):.4f})调参策略先粗后细先调整对模型影响最大的参数如learning_rate学习率、num_leaves/max_depth树复杂度、n_estimators树的数量。使用交叉验证GridSearchCV或RandomizedSearchCV可以系统性地搜索参数组合。对于LightGBM由于训练快可以尝试较广的范围。关键参数经验learning_rate小学习率如0.01-0.1配合更多树n_estimators通常效果更好但训练慢。需要权衡。num_leaves这是控制树复杂度的主要参数值越大模型越复杂容易过拟合。一个经验法则是num_leaves 2^(max_depth)。subsample和colsample_bytree类似于随机森林的行列采样可以防止过拟合一般设置在0.7-0.9。reg_alpha和reg_lambdaL1和L2正则化给模型增加惩罚项防止过拟合。可以从0开始尝试。4.4 模型融合集众家之长单一模型可能达到瓶颈融合多个模型的结果往往能稳定提升性能。简单平均/加权平均对多个模型如调参后的LightGBM、XGBoost、CatBoost的预测概率进行平均。Stacking用多个初级模型的预测结果作为新特征训练一个次级模型通常是逻辑回归来做最终预测。这是竞赛中高级玩家常用的“大杀器”。from sklearn.linear_model import LogisticRegression # 假设我们有三个训练好的模型lgb_model, xgb_model, cb_model # 它们对验证集的预测概率分别为lgb_val_proba, xgb_val_proba, cb_val_proba # 构建次级特征 stacking_X_val np.column_stack((lgb_val_proba, xgb_val_proba, cb_val_proba)) # 训练次级模型元模型 meta_model LogisticRegression() meta_model.fit(stacking_X_val, y_val) # 对测试集进行预测 # 首先用初级模型预测测试集得到lgb_test_proba, xgb_test_proba, cb_test_proba stacking_X_test np.column_stack((lgb_test_proba, xgb_test_proba, cb_test_proba)) final_test_proba meta_model.predict_proba(stacking_X_test)[:, 1]注意事项Stacking时初级模型必须在训练集的不同子集上训练例如通过交叉验证以避免次级模型过拟合。通常使用sklearn的StackingClassifier可以更方便地实现这一过程。5. 评估、验证与结果提交最后的临门一脚模型训练好之后不能只看它在验证集上的表现就沾沾自喜。5.1 多维度模型评估除了看整体的AUC和F1我们还需要更细致的分析。绘制ROC曲线和计算AUC这是必做项直观展示模型在不同阈值下的性能。绘制PR曲线在类别极度不平衡时PR曲线精确率-召回率曲线比ROC曲线更能反映模型在少数类上的性能。绘制KS曲线并计算KS值风控经典指标。绘制Lift图评估模型在头部客群预测风险最高的那部分人中的识别能力。分析特征重要性不仅是为了选择特征更是为了模型的可解释性。我们可以向业务方解释是哪些因素主要驱动了风险判断。from sklearn.metrics import roc_curve, precision_recall_curve, auc # 计算ROC曲线 fpr, tpr, thresholds_roc roc_curve(y_val, y_val_proba_lgb) roc_auc auc(fpr, tpr) # 计算PR曲线 precision, recall, thresholds_pr precision_recall_curve(y_val, y_val_proba_lgb) pr_auc auc(recall, precision) # 绘制双图 fig, (ax1, ax2) plt.subplots(1, 2, figsize(12, 5)) ax1.plot(fpr, tpr, labelfROC curve (AUC {roc_auc:.3f})) ax1.plot([0, 1], [0, 1], k--) ax1.set_xlabel(False Positive Rate) ax1.set_ylabel(True Positive Rate) ax1.set_title(ROC Curve) ax1.legend() ax2.plot(recall, precision, labelfPR curve (AUC {pr_auc:.3f})) ax2.set_xlabel(Recall) ax2.set_ylabel(Precision) ax2.set_title(Precision-Recall Curve) ax2.legend() plt.tight_layout() plt.show()5.2 阈值选择与业务对齐模型输出的是违约概率0到1之间。我们需要一个阈值如0.5来将其转化为“通过”或“拒绝”的决策。默认0.5阈值在类别平衡时有效但在风控中需要调整。如果业务追求资产安全宁愿错杀好客户也不放过坏客户。那么应该提高阈值如0.7。这样只有违约概率极低的客户才会被通过精确率提高但召回率下降。如果业务追求市场规模愿意承担一定风险来获取更多客户。那么可以降低阈值如0.3。这样更多客户会被通过召回率提高但精确率下降。我们可以根据业务对精确率和召回率的偏好在验证集的PR曲线上选择对应的最优阈值。# 寻找使F1-Score最大的阈值 f1_scores [] for thresh in np.arange(0.1, 0.9, 0.01): y_pred (y_val_proba_lgb thresh).astype(int) f1 f1_score(y_val, y_pred) f1_scores.append((thresh, f1)) best_thresh, best_f1 max(f1_scores, keylambda x: x[1]) print(fBest threshold for F1: {best_thresh:.2f}, Best F1: {best_f1:.4f}) # 或者根据业务成本设定阈值 # 假设误拒一个好客户的成本是C_fp误放一个坏客户的成本是C_fn # 最优阈值 ≈ C_fp / (C_fp C_fn) 在概率校准良好的情况下5.3 提交结果前的最终检查在生成最终用于提交的测试集预测文件前务必进行以下检查数据一致性确保测试集经过了与训练集完全相同的预处理流程使用相同的填充值、编码器、缩放器。预测概率校准检查模型输出的概率是否反映了真实的违约可能性。可以使用CalibratedClassifierCV进行概率校准。格式检查严格按照竞赛要求生成提交文件通常是两列ID和Predicted_Probability。检查文件编码、分隔符、列名是否正确。合理性检查查看预测结果的分布。如果所有概率都集中在0.5附近或者分布与训练集差异极大可能预示着问题。# 最终预测与提交 # 假设 test_data 是已经完全预处理好的测试集特征 final_test_proba model.predict(test_data, num_iterationmodel.best_iteration) # 对于LightGBM # 创建提交DataFrame (假设测试集有‘id’列) submission pd.DataFrame({ id: test_data[id], probability: final_test_proba }) # 保存 submission.to_csv(submission_final.csv, indexFalse) print(Submission file saved.)6. 常见问题与避坑指南那些年我踩过的“坑”回顾整个流程有几个地方特别容易出错这里集中列出来希望能帮你省下大量调试时间。问题现象/原因解决方案数据泄露模型在验证集上表现极好但在测试集或真实环境中一塌糊涂。最常见原因是在预处理时如填充缺失值、标准化使用了全量数据包含验证集/测试集的统计信息。严格隔离任何从数据中“学习”到的参数均值、中位数、编码映射、PCA成分等都必须仅从训练集计算然后应用到验证集和测试集。使用sklearn的Pipeline可以很好地管理这个过程。验证集分布偏移随机划分验证集后发现其好坏客户比例与训练集差异很大导致评估不可信。分层抽样在train_test_split时务必使用stratifyy参数。在交叉验证时使用StratifiedKFold。类别不平衡处理不当模型对少数类坏客户的预测能力极差召回率接近0。1. 使用正确的评估指标AUC, F1, RecallPrecision。2. 在模型参数中设置class_weightbalanced或自定义权重。3. 尝试过采样如SMOTE或欠采样技术。4. 使用对不平衡数据更鲁棒的模型如LightGBM设置is_unbalanceTrue。特征工程过度/不足特征太少模型学不到规律特征太多且杂乱模型过拟合。1.先做必要的处理好缺失、异常、编码。2.构造有业务感的特征哪怕数据已脱敏。3.一定要做特征选择使用模型重要性、相关性分析等方法过滤掉噪音特征。树模型自带重要性评估要善用。模型过拟合训练集AUC接近1验证集AUC低很多。1.增加正则化增大reg_alpha,reg_lambdaLGBM/XGBoost或C的倒数逻辑回归。2.降低模型复杂度减少树的最大深度max_depth、叶子数num_leaves。3.增加随机性增加行/列采样比例subsample,colsample_bytree。4.使用早停在验证集性能不再提升时停止训练这是防止过拟合最有效的手段之一。预测结果全为0或1提交后得分极低或为0。1. 检查阈值是否错误地将概率直接四舍五入了提交的应该是概率值而不是0/1标签除非赛题明确要求提交标签。2. 检查数据预处理一致性测试集是否因为某个步骤遗漏导致特征维度或含义与训练时不同3. 检查目标变量定义是否搞反了0和1的含义最后一点个人体会数据挖掘竞赛尤其是像国赛-19C这样的经典题目它最大的价值不在于得到一个多高的排名而在于逼着你走完一个完整的、工业级的建模流程。从最初面对一堆陌生数据的茫然到一步步清洗、探索、构造、实验、调优最后形成一个稳定的预测 pipeline。这个过程里培养出的数据敏感度、工程化思维和问题解决能力远比那个最终的AUC分数重要。当你以后再遇到一个真实的风控、营销或预测问题时这套从“数据”到“决策”的方法论就是你最趁手的工具。所以多动手多思考多总结把这个项目吃透它的价值会远超你的想象。
返回列表