第一次打信贷违约预测类比赛的人十有八九都会卡在同一个地方数据集拿到了却不知道从哪下手。标签有了特征也有了可面对一堆看不懂的字段名、各种缺失值和类别型变量脑子里全是问号。我最初也是这么过来的后来发现最稳妥的办法就是先别想着用什么高大上的模型、复杂的特征工程直接拿随机森林跑一个完整的Baseline先把分数拿到手把整套流程跑通再去谈优化。这篇就用一个典型的信贷违约预测场景把从数据读取到提交结果的完整Baseline过程拆开揉碎讲清楚适合所有准备入门数据挖掘比赛的朋友参考。1. 为什么信贷违约预测首选随机森林作为Baseline先说结论随机森林不是精度最高的模型但它是做信贷违约预测时投入产出比最高的Baseline模型。1.1 信贷场景的数据特点与随机森林的契合点做过几场比赛之后你会发现信贷违约预测的数据集几乎都有几个共同特征。第一特征维度很高动辄几十上百个字段覆盖用户基本信息、历史借贷记录、还款行为、第三方数据等第二特征类型混乱数值型、类别型、时间型、文本型混在一起第三缺失值普遍存在而且常常不是随机缺失是跟业务逻辑相关的缺失第四样本不均衡违约用户通常只占百分之几甚至更低。随机森林恰好能在这些条件下表现稳定。它对缺失值不那么敏感虽然不能完全无视缺失但相比逻辑回归、SVM这些模型它能够容忍一定比例的缺失它对特征量纲完全不敏感不需要做标准化因为树模型的分裂只看特征的相对大小不像线性模型那样需要归一化它能自动捕捉非线性关系和特征间的交互效应这在信贷场景里特别关键比如年龄和收入结合起来才能体现还款能力这种组合关系用人手工去构造特征很难穷尽。还有一个很实际的原因——随机森林的训练效率高调参成本低。对于一份几千到几万条样本的比赛数据默认参数下的随机森林几分钟就能跑完而像XGBoost、LightGBM虽然精度更高但参数多训练过程更需要耐心调校作为第一版流程随机森林更适合用来探路。1.2 从Baseline中得到什么才算合格很多人对Baseline的理解就是跑通代码拿个分数觉得分数低就不值得投入。这个想法其实是错的。一个合格的Baseline核心价值是帮你建立起完整的数据处理流程和验证框架。拿到数据后第一版代码应该让你搞清楚的事情是训练集和测试集各有多少行多少列哪些字段是数值型、哪些是类别型、哪些是时间型/文本型缺失值分布集中在哪些字段上缺失比例大概是多少用默认参数跑完交叉验证后评价指标大致在什么水平特征重要性排序里哪些特征排在最前面把这些问题回答清楚Baseline就算完成了使命。后面不管是换模型、做特征工程还是调参都是在这个框架上做增量而不是推倒重来。我自己习惯在第一次跑Baseline时就把后续要用的模块化函数写好数据加载、缺失值统计、类别编码、模型训练、交叉验证、特征重要性输出、结果保存。前期多花半小时整理代码结构后面迭代的效率会翻几倍。1.3 随机森林背后的原理直觉严格推导随机森林需要用决策树、Bootstrap抽样、Bagging、随机特征子集这些概念。但从使用者的角度你只需要建立三个直觉。树模型是分段决策。贷不违约这件事很难用一个线性公式描述但可以拆成一系列条件判断收入大于某个值的是一批人收入小于某个值但历史逾期少的又是一批人每次分段都在降低预测的不确定性这就是决策树在做的事。随机森林是很多棵树的投票。单棵决策树容易过拟合学到的可能是噪声而不是规律。随机森林同时对样本行和特征列做随机抽样训练出大量有差异的树让它们投票决定最终结果。每棵树各有局限投票后噪声互相抵消真实的信号被保留下来。随机特征子集是防止树太像。如果每棵树都用全部特征去训练好特征会被反复选树与树之间高度相似投票的结果跟单棵树差别不大。随机森林每次分裂只从一部分特征里选最优逼着树们从不同角度学习降低了树间的相关性整体的泛化能力才更强。这套机制天然适合信贷数据。信贷数据噪声大、规律杂单靠任何一条规则都很难识别违约风险但大量有差异的弱规则投票之后稳定性就会出来。2. 数据预处理读数据、看分布、处理缺失的完整套路这个环节最容易被忽略但它决定了后面所有步骤的质量。数据预处理不是简单把缺失值填了就完事你要在动手前先把数据的全貌摸清楚。2.1 数据加载与全貌探查信贷类比赛的数据通常以CSV格式给出训练集包含特征列和标签列测试集只有特征列。加载之后第一步永远是看形状和数据字典。import pandas as pd import numpy as np train pd.read_csv(train.csv) test pd.read_csv(test.csv) print(训练集形状:, train.shape) print(测试集形状:, test.shape) print(训练集列名:, train.columns.tolist()) print(训练集标签分布:) print(train[isDefault].value_counts(normalizeTrue))这几行代码是每一场比赛的起点。看了之后你立刻明白两件事样本量有多大违约占比是多少。信贷违约数据集里违约率通常在2%到10%之间对应的就是样本不均衡问题后面交叉验证的评估方式要据此选择。isDefault是常见的标签命名方式取值0代表正常还款用户1代表违约用户。如果标签列名不同也不要紧去数据字典里找到标签列即可。有时候会遇到标签是字符串的情况比如是/否需要先映射成0和1再建模。2.2 缺失值分析先看哪里缺再决定怎么填缺失值处理没有统一答案但在信贷场景里有几类规律可以参考。用户在申请贷款时某些字段空缺可能是因为该用户没有主动填写某些信息比如车辆价值、房产面积缺了往往意味着没有该资产也可能是因为特定渠道收集不到这部分数据这时候缺了就代表渠道差异。所以处理缺失值的第一步不是填值而是统计每个字段的缺失比例。missing_df pd.DataFrame({ 列名: train.columns, 缺失率: train.isnull().mean().round(4) }).sort_values(缺失率, ascendingFalse) print(missing_df[missing_df[缺失率] 0].head(20))统计完之后按经验把缺失字段分成几类缺失率极低低于1%的字段可以直接用中位数或众数填充这种量级的缺失对结果几乎没影响。缺失率中等在1%到30%之间的字段需要用合理策略填充。数值型用中位数比均值更稳妥因为中位数不受极端值影响类别型用众数填充或者单独填一个未知类别。缺失率很高超过50%的字段要谨慎使用。有些字段缺失率过高时它能提供的真实信息有限直接删掉是一种选择。但在信贷比赛中我的经验是保留这些字段填充一个特殊值让模型自己去判断缺失这个状态本身的信息量。因为用户没填车辆价值这件事本身就可能暗示用户没有车缺失状态在树模型里可以被当成一种分布上的区别。有一种做法值得一试为缺失率高的字段额外创建一个布尔指示特征1表示该样本在此字段缺失0表示不缺失。随机森林可以学到缺失模式与违约率之间的关联。for col in [veh_price, house_area, job_years]: train[col _is_missing] train[col].isnull().astype(int) test[col _is_missing] test[col].isnull().astype(int)这个技巧在信贷场景里效果不错因为业务逻辑上缺失往往跟风险相关。2.3 数值型与类别型字段的分流处理信贷数据里类型混杂需要区分处理。数值型字段分两种一种是收入、年龄、贷款金额这样的真实数值另一种是等级评分取值范围有限比如0到10之间的整数。后者可以按数值型处理也可以尝试转成类别型需要做实验对比没有绝对标准。类别型字段在信贷数据里出现频繁职业类型、学历、婚姻状况、居住城市等级、贷款用途等都属于这类。随机森林本身不支持直接吃字符串必须先把类别转成数值。我用得最多的是LabelEncoder简单可靠from sklearn.preprocessing import LabelEncoder for col in cat_cols: le LabelEncoder() train[col] le.fit_transform(train[col].astype(str)) test[col] le.transform(test[col].astype(str))注意fit_transform必须在训练集上执行transform在测试集上执行保证编码规则一致。如果测试集某个类别在训练集中没出现过transform会报错稳妥的做法是先合并数据集做统一的编码映射。all_data pd.concat([train[cat_cols], test[cat_cols]], axis0) for col in cat_cols: le LabelEncoder() all_data[col] le.fit_transform(all_data[col].astype(str)) train[col] all_data[col][:len(train)] test[col] all_data[col][len(train):]另一个办法是pd.factorize()也能实现类似功能。有人会问类别型字段用OneHotEncoder会不会更好理论上独热编码能保留更完整的信息但代价是特征维度暴涨当类别数很多时还会引入稀疏性问题。在Baseline阶段LabelEncoder就够用了先拿到分数再说。2.4 特征与标签对齐检查有个隐蔽的坑值得提醒训练集和测试集的特征对齐。比赛数据偶尔会有列顺序不一致、列数不一致的情况。最稳的办法是拿到列名列表用交集对齐后再建模。common_cols list(set(train.columns) set(test.columns)) X_train train[common_cols] X_test test[common_cols] y_train train[isDefault]这个操作看起来多余但能帮你规避大量莫名其妙的报错。我用过的某个数据集里训练集多了一列sample_id之类的元信息测试集里没有如果不过滤直接训练随后在测试集上预测时就会报特征数量不匹配排查半天才发现是列对齐出了问题。3. 随机森林建模三板斧训练、验证、预测提交数据准备完之后建模部分其实很快。核心是建立一套标准的训练和验证流程而不是纠结于参数调优。3.1 训练集与验证集的划分策略信贷违约比赛的常用做法是训练集内部再切分留出一部分数据做本地验证集用于评估模型表现。切分时要注意保持标签分布的一致用分层抽样。from sklearn.model_selection import train_test_split X_train, X_val, y_train, y_val train_test_split( X_train, y_train, test_size0.2, random_state42, stratifyy_train )stratifyy_train是必须的尤其是违约率只有几个百分点的时候不用分层抽样验证集里可能一个违约样本都没有评估结果会完全失真。当样本量较小时单次划分的验证结果方差很大。更严谨的做法是交叉验证。比赛初期用5折交叉验证就够了可以帮你判断模型的稳定性。每次折的得分差别大说明模型方差高或者数据噪声大后续调参方向就要偏保守。from sklearn.model_selection import cross_val_score from sklearn.ensemble import RandomForestClassifier rf RandomForestClassifier(n_estimators200, max_depth10, random_state42) scores cross_val_score(rf, X_train, y_train, cv5, scoringroc_auc) print(交叉验证AUC均值: {:.4f} (/- {:.4f}).format(scores.mean(), scores.std()))评分指标的选择很重要。信贷违约预测中主流是AUC它的含义是随机抽取一个正样本和一个负样本模型把正样本排在负样本前面的概率。AUC不受阈值影响适合用来衡量模型的排序能力。有的比赛要求用KS或者其他指标务必看清比赛规则。3.2 随机森林关键参数的含义与Baseline取值随机森林有几个参数对结果影响最大值得逐个理解。第一个是n_estimators即树的数量。太少了模型不稳太多了训练变慢且边际收益递减Baseline阶段取100到300之间比较合适。第二个是max_depth树的最大深度不设的话树会长到不能再分容易过拟合。信贷场景里特征多、噪声大限制深度是必要的Baseline可以从10到20开始试。第三个是min_samples_leaf叶节点的最小样本数设大一点能让每片叶子上的样本更充足预测结果更平滑信贷场景里我习惯从50往上试。第四个是max_features每次分裂时随机抽取的特征数量默认是特征数的平方根在大部分情况下够用。Baseline阶段不需要过度纠结参数直接用一组稳妥的取值model RandomForestClassifier( n_estimators200, max_depth15, min_samples_leaf50, max_featuressqrt, class_weightbalanced_subsample, n_jobs-1, random_state42 )class_weightbalanced_subsample是处理不均衡的一个辅助手段给少数类更高的权重让模型更关注违约样本。这个参数在信贷比赛里值得设置因为我们的目标是尽可能识别出违约用户而不只是整体准确率高。n_jobs-1可以让所有CPU核心并行训练速度提升明显。3.3 训练与本地验证切好数据之后训练模型就一句话的事model.fit(X_train, y_train)然后立刻在验证集上做预测评估表现from sklearn.metrics import roc_auc_score y_pred_proba model.predict_proba(X_val)[:, 1] auc_score roc_auc_score(y_val, y_pred_proba) print(验证集AUC: {:.4f}.format(auc_score))这里用的是predict_proba而不是predict。AUC需要的是概率值不是0/1分类结果。这是新手最容易出错的地方用predict得到类别标签之后去算AUC结果往往是0.5上下毫无意义。提交的时候同样要用概率。比赛页面通常允许提交概率形式的预测结果在给结果排序时概率值越精确越好。3.4 生成提交文件比赛平台一般要求上传指定格式的CSV文件包含用户ID和预测概率两列。生成提交文件的代码长这样test_proba model.predict_proba(X_test)[:, 1] submission pd.DataFrame({ id: test_id.values, isDefault: test_proba }) submission.to_csv(baseline_rf.csv, indexFalse)提交文件的列名必须和比赛官方给出的样例文件完全一致顺序无所谓但列名必须一样否则提交时会报格式错误。这个看起来不起眼的问题每次比赛都会有一批人踩坑。test_id是测试集里每个样本的唯一标识通常在原始测试数据里。如果你用的特征矩阵是从合并数据中处理过的记得把测试集的ID单独保存出来避免后面找不回来。提交之后线上分数和本地验证分数之间通常会有一个小差距这很正常。但如果差距非常大就要回头检查是不是有数据泄漏或者训练集和测试集分布差异太大。4. 特征重要性分析从Baseline里找到提分线索Baseline跑通之后千万别急着交卷。随机森林的另一个巨大优势是它能直接输出特征重要性排序这份排序就是你后续特征工程和模型优化的第一手线索。4.1 特征重要性怎么看随机森林的特征重要性是基于袋外误差或者Gini不纯度降低的累计量来计算的。sklearn直接提供了接口importances model.feature_importances_ feature_names X_train.columns importance_df pd.DataFrame({ 特征: feature_names, 重要性: importances }).sort_values(重要性, ascendingFalse) print(importance_df.head(30))得到排序之后我一般会做三件事。看头部特征是否符合业务直觉。排在前面的特征里如果有莫名其妙的字段比如某个ID编号表现出很高的重要性就要警惕是不是有泄漏。ID列在信贷数据里有时能隐性地关联到某些风险信息但直接用ID做预测不靠谱这种特征应该剔除。看尾部特征能不能删除。重要性极低的特征留着无害但会增加训练噪音和计算开销。可以考虑用SelectFromModel做特征筛选保留重要性超过阈值的特征重新训练对比验证集分数变化。看特征组合方向。如果某个类别型特征编码后重要性很高比如所在省份排名靠前那后续可以考虑对这个特征做细分处理。如果某个数值特征重要性很高比如历史逾期次数可以考虑用它对样本做分组统计特征比如该用户逾期次数在相同收入人群中的排名这种二阶特征往往能带来稳定提升。4.2 基于重要性做第一轮特征迭代见过太多人把精力花在疯狂调参上却忽略了特征迭代的收益。随机森林在特征已经够用的情况下提升空间有上限但特征工程能带动模型提升一个台阶。我常用的第一轮迭代策略是围绕重要性靠前的特征构造交叉特征。比如收入是重要特征职业类别也是重要特征就可以构造收入/职业类别均值这样的比值特征反映用户在所处职业群体中的相对收入水平。再比如年龄和贷款金额都重要可以构造贷款金额/年龄的组合近似反映每岁负担的还款压力。树模型虽然能在分裂时自动组合特征但显式构造的交叉特征能让它更容易发现这些规律尤其在深度受限的情况下。train[income_per_age] train[income] / (train[age] 1) test[income_per_age] test[income] / (test[age] 1) train[loan_ratio] train[loan_amount] / train[total_asset] test[loan_ratio] test[loan_amount] / test[total_asset]注意分母加1或者加一个极小值防止除零。构造完新特征后重新跑一遍完整的训练和验证流程对比AUC是否提升。有提升就保留没提升就删掉别带着一堆无效特征堆积反而增加过拟合风险。4.3 缺失指示特征在随机森林中的特殊作用前面提到的缺失本身就是信息这个观点在随机森林里有个天然的优势树分裂时会处理缺失值将缺失样本分到某个子节点。但显式构造缺失指示特征能让模型更明确地利用缺失模式。我做过一组对比实验不加缺失指示特征时某份信贷数据验证集AUC在0.72左右给缺失率最高的6个字段加上缺失指示特征后AUC提升了约0.006到0.008。幅度不算惊人但几乎不需要额外成本。类似的实验在多个信贷数据集上都能观察到正向效果这可能是因为申请贷款时不填某个字段本身确实和用户资质有相关性。这条经验适合拿来做Baseline的标配操作只要缺失字段不是全列缺失或完全无意义都可以给高频缺失字段创建指示特征。5. 交叉验证与评估方式别让一次性划分骗了你单独拿一次验证集的结果就判断模型好坏是新手最常见的错误。交叉验证做的事情是把数据切成多份轮流做验证最后把分数平均相当于做了多次独立实验结果可信度远高于单次划分。5.1 为什么信贷数据特别依赖交叉验证信贷违约数据集的不均衡特性决定了单次划分的风险很高。假设违约率只有3%随机切分的时候验证集里可能只会有几十个违约样本。不同的切法这几十个违约样本在特征空间里的分布可能有很大差别模型在验证集上的AUC自然忽高忽低。交叉验证能部分缓解这个问题。5折交叉验证把样本分成5份每份都能参与到训练和验证中最终平均分比单次划分稳定得多。更重要的是交叉验证的方差信息能反映模型对数据分布的敏感程度方差太大说明模型过拟合或者数据存在明显异质性后续要调整模型的复杂度比如减小max_depth、增大min_samples_leaf。5.2 评分函数的选择与阈值判断除了AUC信贷违约预测里还有几个常用评估指标。KS统计量衡量好坏样本累计分布的最大差距风控行业用得很多F1分数关注精确率和召回率的平衡适合类别不平衡且需要明确判断的场景LogLoss则关注概率校准度对概率的绝对值敏感。比赛用什么指标的规则通常在赛题说明里写得清清楚楚直接按赛题要求来。如果比赛要求的是F1分数那predict_proba得到的概率还需要额外确定阈值把概率转成0/1标签这一步可以用验证集搜索最优阈值from sklearn.metrics import f1_score thresholds np.arange(0.1, 0.7, 0.05) best_score 0 best_threshold 0.5 for t in thresholds: pred (y_pred_proba t).astype(int) score f1_score(y_val, pred) if score best_score: best_score score best_threshold t print(最佳阈值: {:.2f}, 验证集F1: {:.4f}.format(best_threshold, best_score))确定阈值后对测试集概率应用同一个阈值生成标签提交。5.3 本地验证分数与线上分数的差距管理本地AUC很高线上猛然掉了一截这种情况在信贷比赛里太常见了。通常有几种原因。第一种是训练集和测试集分布不一致。信贷数据的分布会随政策、季节、客群变化而迁移测试集可能是不同时间段的数据。这种情况下的应对策略是做对抗验证训练一个分类器区分训练集和测试集的来源看能不能达到高AUC。如果对抗验证AUC明显高于0.5说明分布差异明显特征选择上就更倾向于选对抗验证中无法区分的稳定特征。第二种是本地验证集划分方式与比赛评价方式不一致。赛题如果说明用留出集评分你的本地划分方式要尽量模拟官方的切分逻辑。有的比赛按时间切分这时就不能随机分层抽样而要按时间顺序划分。第三种是存在数据泄漏。特征重要性里出现异常高的特征或者本地验证分数高到不现实就要仔细审查。信贷数据里常见的泄漏源包括包含未来信息的特征、用户ID编号等辅助字段、以及那些在现实中预测时无法拿到的事后变量。Baseline阶段遇到本地高分线上低分别急着质疑模型先排查这三类原因。6. 参数调优思路从默认参数出发的快速搜索Baseline跑通、特征重要性分析做完之后可以进入参数调优阶段。随机森林的参数空间不算大但每个参数的合理范围值得摸一遍。6.1 两阶段调优法我习惯将调参分成两个阶段。第一阶段粗调确定max_depth和min_samples_leaf的大致范围因为这两个参数直接决定模型复杂度对过拟合影响最大。第二阶段精调固定前两个参数后再用网格搜索或者随机搜索调整n_estimators和max_features。第一阶段可以用一组简化代码快速实验from sklearn.model_selection import GridSearchCV param_grid { max_depth: [10, 15, 20, 25], min_samples_leaf: [20, 50, 100] } gs GridSearchCV( RandomForestClassifier(n_estimators200, random_state42), param_grid, cv5, scoringroc_auc, n_jobs-1 ) gs.fit(X_train, y_train) print(最佳参数:, gs.best_params_) print(最佳AUC:, gs.best_score_)GridSearchCV会遍历所有参数组合数据集大时计算量不小。这时候灵活性更重要可以用RandomizedSearchCV随机采样参数组合效率更高在参数空间较大时往往能更快找到好区域。6.2 参数组合的权重思考不同参数对模型的影响在信贷场景里有经验顺序。最重要的是max_depth和min_samples_leaf它们控制树的复杂度。如果验证集AUC和训练集AUC差距很大优先减小max_depth或增大min_samples_leaf这是治过拟合的利器。其次是n_estimators它影响模型的稳定性增大树的数量通常能让AUC曲线稍微上扬并稳定下来但到了三四百棵之后收益就很小了。最后是max_features默认的平方根效果在大多数时候够用但如果特征数量特别多可以尝试降低到0.3或0.4倍特征数增加树的多样性有时候能带来意外提升。class_weight的调整也很关键。如果模型对违约样本的召回率明显偏低可以考虑加重违约类权重比如设置{0: 1.0, 1: 3.0}观察AUC和F1的变化。这类调整需要结合业务需求有的比赛关注AUC本身权重影响有限但如果赛题要求F1或者KS权重就是关键手段。6.3 调参的边际收益递减必须说一句大实话随机森林的调参收益通常不会特别夸张。如果验证集AUC从0.70提升到0.72已经算不小的进步想靠调参从0.70冲到0.78几乎不可能那要靠特征工程和更强大的模型才能实现。所以我的建议是调参适可而止把时间花在特征迭代上更重要。参数调优本身是一个稳妥的增量步骤但不要在随机森林上调到极致之后再去试其他模型可以先确认baseline的分数落在合理区间然后并行展开特征工程和模型对比两条路线。毕竟随机森林本身只是一个基线它的作用是告诉你这个问题的难度大致在一个什么水平。7. 处理样本不均衡的几个实操手段信贷数据的不均衡是绕不开的难题。违约用户可能只占3%到5%如果什么都不做模型会把所有样本都预测成正常AUC虽然可能在0.5左右徘徊但对真正要解决的识别违约用户这个问题毫无意义。7.1 评估指标和业务目标对齐首先要想清楚比赛到底要求什么。如果只看AUC其实不均衡的负面影响相对可控因为AUC只关心排序能力哪怕违约样本少只要模型能把它们排在前面AUC就能上去。但如果看的是F1、召回率这类指标不均衡问题就必须正面处理否则少数类会被严重忽略。随机森林里处理不均衡有三种主要手段。第一种是class_weight调整类别权重第二种是下采样让正常用户数量和违约用户数量接近第三种是上采样用SMOTE这类方法生成少数类的合成样本。每一种手段都有代价。下采样会丢失大量数据上采样可能引入额外噪声。在这三者之间我通常优先选class_weight因为它不改变样本集本身只是给少数类更高的损失权重更稳健。7.2 使用class_weight和阈值移动的组合策略实际操作中把class_weightbalanced作为起点配合阈值移动是处理信贷不均衡最实用的搭配。训练出的模型可能会倾向把预测概率整体拉高这时再在验证集上重新搜索一个较高的决策阈值而不是死守0.5。model_weighted RandomForestClassifier( n_estimators200, max_depth15, min_samples_leaf50, class_weightbalanced, random_state42 ) model_weighted.fit(X_train, y_train) y_pred_proba_w model_weighted.predict_proba(X_val)[:, 1] print(加权后验证集AUC: {:.4f}.format(roc_auc_score(y_val, y_pred_proba_w)))权重设置后样本量较大的正常类依然会在决策中占主导但少数类的信号被放大排序能力往往会更好一些。7.3 过采样方法的适用条件SMOTE这类方法在信贷场景里效果取决于数据本身的结构。如果特征空间里正常用户和违约用户本身有较强的可分性SMOTE生成的合成样本能帮模型学到更平滑的边界如果噪声本来就大SMOTE反而可能制造出违背业务逻辑的样本把模型带偏。我的建议是在Baseline阶段先不碰SMOTE。跑完class_weight加阈值移动之后如果分数仍然偏低再考虑用imbalanced-learn库里的SMOTE做实验。务必要在交叉验证的每一折内部进行过采样不能在划分之前就做否则会出现数据泄漏验证分数虚高。from imblearn.over_sampling import SMOTE from imblearn.pipeline import make_pipeline smote_pipe make_pipeline( SMOTE(random_state42), RandomForestClassifier(n_estimators200, max_depth15, random_state42) ) scores_smote cross_val_score(smote_pipe, X_train, y_train, cv5, scoringroc_auc)用make_pipeline包起来保证交叉验证时SMOTE只作用于训练折不触碰验证折这是用好过采样方法的关键。整体看下来用随机森林做信贷违约预测的Baseline本质上是在数据理解和评估框架上花功夫模型本身反而是最简单的环节。数据清洗、编码、缺失处理、交叉验证、特征重要性分析这些步骤无论你后续换成LightGBM、XGBoost还是深度学习模型全部都要重新走一遍。所以Baseline的意义不在分数在流程。先把流程跑通把每一块数据的前因后果摸明白后面每换一个模型、每加一个特征都是在为这份底稿做增量。我自己每次拿到新的信贷数据集都会从这套随机森林流程入手用最快速度搭出第一版结果然后顺着特征重要性和交叉验证的线索逐步深入。如果你正准备参加类似的比赛照着这个流程先完整跑一遍跑完你自然知道下一步该往哪里使劲。
阅读完成 · 觉得有帮助?