拓冰建站拓冰建站
首页 / 资讯中心 / 正文

贷款违约预测机器学习实战:Python源码驱动的五条建模路线

简介这套基于Python的贷款违约预测机器学习实践设计源码面向金融风控、信贷审批及数据挖掘方向的开发者和学习者用于通过随机森林、决策树、梯度提升等算法构建可落地的信用风险评估模型。压缩包共23个文件包含7个py源代码文件数据预处理、模型训练与预测、11个png可视化图表、2个csv训练/测试数据集以及xls、txt、license等辅助文件整体约13.77MB目录结构清晰便于对照学习和二次开发。已有560人学习下载。学习者可借助完整源码掌握数据清洗、特征工程、模型对比与调优、过拟合识别等关键环节并直接运用于贷款审批场景提升信贷决策的准确性与效率。1. 贷款违约预测从哪里下手一份能看到完整建模链路的 Python 源码信贷风控场景里最核心的问题不是模型用得多花哨而是能不能在有限数据里快速圈出高风险申请。这份基于 Python 的贷款违约预测机器学习实践源码把数据分析、决策树、随机森林、梯度提升、逻辑回归五条建模路线全部串成可运行脚本训练集、测试集、字段字典、学习曲线图一应俱全。适合想用信用评分完成课程设计的在校生也适合刚进风控、想看看机器学习怎么从数据落到预测结果的分析师。我拆完这套资源最直接的感受是模型本身不难难的是数据清洗和参数选择而这两件事的答案恰好都藏在源码和图像文件里。2. 先看数据再谈模型字段字典和 data_analysis.py 里的数据画像2.1 字段字典贷款违约预测依赖哪些特征项目里附带了一个 Data Dictionary.xls 字段字典这在大多数机器学习项目里属于稀缺品建议建模前先把它过一遍。数据文件是 cs-training.csv 和 cs-test.csv训练集和测试集结构一致这种命名方式在信贷竞赛里很常见。字段字典里能对应出一套典型的个人信贷画像目标变量是客户是否在两年内违约其余特征覆盖了额度使用、历史逾期、负债收入比、月收入、信贷账户数、房产贷款数、家属数量等维度。字段名业务含义建模时的常见处理SeriousDlqin2yrs目标变量是否严重逾期二分类标签1 表示违约RevolvingUtilizationOfUnsecuredLines循环额度使用率注意异常值常有人为填错age年龄过滤大于 100 岁的异常样本NumberOfTime30-59DaysPastDueNotWorse30-59 天逾期次数与 90 天逾期高度相关DebtRatio负债率保留原值异常值单独标记MonthlyIncome月收入缺失率约两成需填充NumberOfOpenCreditLinesAndLoans开放信贷账户数结合房产贷款数一起看NumberOfTimes90DaysLate90 天以上逾期次数强预测变量NumberRealEstateLoansOrLines房产贷款笔数部分样本出现负数需清洗NumberOfTime60-89DaysPastDueNotWorse60-89 天逾期次数与 30-59 天字段联动NumberOfDependents家属数量缺失量少可做众数填充这套字段结构和 Kaggle 上经典的 Give Me Some Credit 信贷数据集一致如果你之前跑过那个竞赛上手会非常快。字段字典的价值不在于列名字典而在于它把每个变量的业务含义钉死了比如 NumberOfTimes90DaysLate 不能简单当成数值它代表的是历史逾期行为的严重程度在做特征工程时可以考虑将它分箱而不是直接线性使用。数据里有一个非常值得注意的现象违约样本占比通常只有 6% 左右属于典型的类别不平衡问题。如果后面直接拿准确率当评估指标模型只要全部预测不违约就能拿到 94% 的准确率但这显然不是风控要的结果。所以从数据分析这一步开始就要盯着正负样本比例、缺失率、异常值这三个基础指标它们决定了后续所有模型的上限。2.2 data_analysis.py 在做什么加载数据、检查缺失、看分布项目里的 data_analysis.py 就是干数据预处理和探索性分析这件事的。我不确定原文件每一行的写法但这类脚本的骨架高度统一用 pandas 读入 CSV用 info 和 describe 看类型与分布用 isnull 统计缺失率再用 matplotlib 或 seaborn 画分布图。下面的代码是我按这类项目最常见的方式补全的你可以对照自己的 data_analysis.py 看差异核心思路是一样的。import pandas as pd import numpy as np import matplotlib.pyplot as plt train pd.read_csv(cs-training.csv, index_col0) print(train.shape) print(train.info()) target_rate train[SeriousDlqin2yrs].mean() print(违约样本占比: {:.4f}.format(target_rate)) missing_ratio train.isnull().mean().sort_values(ascendingFalse) print(缺失率 Top5:) print(missing_ratio[missing_ratio 0].head()) train[MonthlyIncome] train[MonthlyIncome].fillna( train[MonthlyIncome].median() ) train[NumberOfDependents] train[NumberOfDependents].fillna(0) train train[train[age] 100] train train[train[NumberOfTimes90DaysLate] 90] fig, ax plt.subplots(1, 2, figsize(12, 4)) train[SeriousDlqin2yrs].value_counts().plot( kindbar, axax[0], title目标变量分布 ) train[age].hist(bins50, axax[1], title年龄分布) plt.tight_layout() plt.savefig(percentage.png)这段代码有三个地方需要说明。第一index_col0是因为这类 CSV 第一列通常是客户 ID把它当作索引而不是特征避免 ID 被模型学进去这一步丢掉的不是信息是风险。第二缺失值填充用了中位数而不是均值因为 MonthlyIncome 这类收入变量往往右偏个别高收入样本会把均值拉高用均值填充会让中低收入人群的收入被系统性抬高进而影响负债率的计算结果。第三过滤 age 大于 100 和逾期次数大于 90 的样本属于业务常识这类值大概率是数据录入错误不是真实分布的一部分。有一点我要专门提醒data_analysis.py 里画出来的图在项目里对应 percentage.png 和 dependency.png 这些图像文件。percentage.png 我理解是目标变量占比图dependency.png 大概率是字段相关性或者依赖关系图。你在跑通代码之后应该自己打开这些图看一眼而不是直接跳过图像文件只盯着模型精度很多数据问题从图里一眼就能看出来比盯着数字更直观。2.3 特征工程的方向从 percentage.png 和 dependency.png 能读出什么percentage.png 这一类图揭示的是数据分布dependency.png 揭示的是字段间的关系。对信贷数据而言我最先关注的是两个关系一个是逾期次数字段之间的相关性另一个是月收入与负债率之间的关系。逾期类字段在风控场景里从来不独立存在一个客户如果 90 天逾期次数高那么 60-89 天逾期次数通常也不会低这几个字段之间几乎必然存在强相关放进树模型没问题但放进逻辑回归就需要考虑多重共线性问题。特征工程的具体做法通常有三种。第一种是分箱把连续变量按业务经验切成几段比如按收入把客户分成低收入、中收入、高收入三个档位分箱之后既可以做 WOE 编码喂给逻辑回归也能让树模型的分裂更稳定。第二种是构造交叉特征比如把循环额度使用率乘上月收入得到一个大致的绝对负债压力指标。第三种是删除强相关字段比如 NumberOfTime30-59DaysPastDueNotWorse 和 NumberOfTime60-89DaysPastDueNotWorse 相关系数如果超过 0.8保留其中一个往往就能覆盖另一个的信息。需要注意的是特征工程不可以过度。我见过有人在这个数据集上构造出几十个衍生特征结果模型指标几乎没变反而增加了过拟合风险。信贷场景里特征的业务可解释性比特征数量重要得多。你从 dependency.png 里看到的强相关结构就是在提醒你哪些字段可以合并或删除而不是告诉你去创造更多中间变量。3. 决策树与随机森林从单棵树到集成的调参路径3.1 决策树基线train_use_dtc.py 里的 max_depth 与 min_samples_leaftrain_use_dtc.py 对应的是决策树训练脚本这个文件在整套源码里的定位是基线模型。决策树的好处是训练快、结果可解释、能直接画出树结构给你看坏处是单棵树特别容易过拟合。项目里的 tree.png 和 dtc.png 应该分别对应树结构可视化和训练结果图而 max_depth.png 则是调节树深度时记录的模型表现变化。from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import train_test_split X train.drop(SeriousDlqin2yrs, axis1) y train[SeriousDlqin2yrs] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42, stratifyy ) dtc DecisionTreeClassifier( max_depth5, min_samples_leaf50, criteriongini, random_state42 ) dtc.fit(X_train, y_train) print(训练集AUC:, roc_auc_score(y_train, dtc.predict_proba(X_train)[:, 1])) print(测试集AUC:, roc_auc_score(y_test, dtc.predict_proba(X_test)[:, 1]))这段代码最关键的参数是max_depth5和min_samples_leaf50。深度限制在 5 到 7 之间时决策树能学到有效的逾期规律但又不会把个别极端样本背下来min_samples_leaf 限制叶节点最少样本数本质上是在做后剪枝让每个叶子至少有 50 个样本才允许生成避免树在最后几层去拟合噪声。stratifyy保证切分时训练集和测试集里的违约比例一致这一点在类别不平衡数据上尤其重要。决策树基线的作用不是追求最高分而是给后续模型定一个及格线。我在实际项目里会把决策树的 AUC 当作参照物随机森林如果跑不过单棵树说明代码或数据出了问题而不是算法不行。train_use_dtc.py 跑完以后你应该记录下训练集和测试集的 AUC 差值这个差值就是过拟合程度的直观度量。差值在 0.05 以内正常超过 0.1 说明树太深或者叶子太细。3.2 随机森林train_use_rfc.py 为什么能压住过拟合train_use_rfc.py 是随机森林的训练脚本rfc.png 大概率是特征重要性或者 ROC 曲线。随机森林和决策树的关系可以理解为把几十棵弱一点的树装进一个投票箱里。每棵树在训练时随机抽样一部分样本、随机选一部分特征最后用所有树的投票结果做预测这样单棵树的过拟合会被平均掉模型的泛化能力显著提升。from sklearn.ensemble import RandomForestClassifier rfc RandomForestClassifier( n_estimators200, max_depth10, min_samples_leaf30, max_featuressqrt, n_jobs-1, random_state42 ) rfc.fit(X_train, y_train) print(测试集AUC:, roc_auc_score(y_test, rfc.predict_proba(X_test)[:, 1])) importances pd.Series(rfc.feature_importances_, indexX.columns) print(importances.sort_values(ascendingFalse).head(10))n_estimators我一般设 200 到 500超过 500 之后边际收益很小训练时间倒是线性增长。max_depth从决策树的 5 放宽到 10是因为集成机制已经能抵御一部分过拟合可以给每棵树更大的表达空间。max_featuressqrt是随机森林的标准配置每次分裂只随机看根号下特征数量的候选特征强制让不同树从不同角度学习如果改成 None 就退化成近乎 Bagging树之间的多样性会下降。训练完之后一定要看feature_importances_也就是特征重要性。在这个数据集上RevolvingUtilizationOfUnsecuredLines 和 NumberOfTimes90DaysLate 通常稳居前两名这也是符合信贷业务直觉的一个客户循环额度用得越满、90 天以上逾期次数越多违约概率越高。如果特征重要性排名和业务认知严重冲突比如年龄排在逾期次数前面那你需要回头检查数据是不是有问题。随机森林还有一个容易被忽略的优势它能直接输出预测概率而且概率分布相对平滑不像决策树那样只会输出有限几个档位的概率。这个特性在后续做风险排序时特别有用。rfc.png 这张图如果画的是预测概率分布你会发现好客户和坏客户的概率分布有清晰的重叠区域那个重叠区就是后面调阈值时要重点研究的区间。3.3 学习曲线dtc_learn_curve.py 与 max_depth.png 怎么看dtc_learn_curve.py 是专门画学习曲线的脚本这个脚本的存在说明源码作者很清楚模型诊断的重要性。学习曲线的横轴是训练样本量纵轴是模型得分它会同时画出训练集得分和交叉验证得分两条线。两条线靠得越近说明模型越稳定两条线中间的空隙越大说明过拟合越严重。from sklearn.model_selection import learning_curve train_sizes, train_scores, val_scores learning_curve( dtc, X, y, train_sizesnp.linspace(0.1, 1.0, 10), cv5, scoringroc_auc, random_state42 ) train_mean train_scores.mean(axis1) val_mean val_scores.mean(axis1) plt.plot(train_sizes, train_mean, labeltrain) plt.plot(train_sizes, val_mean, labelvalidation) plt.xlabel(training size) plt.ylabel(AUC) plt.legend() plt.savefig(dtc_learn_curve.png)cv5表示做 5 折交叉验证scoringroc_auc表示用 AUC 作为评估指标而不是准确率。在信贷场景里选评估指标有个原则永远不要用准确率评估不平衡数据上的模型AUC 或者 KS 才是靠谱的。train_sizes从 10% 到 100% 的区间设置能让你看到样本量对模型的影响如果验证集得分在样本量增加后还在上升说明数据量还不够加数据比调参更有效。max_depth.png 这张图我猜测是遍历不同 max_depth 值得出的 AUC 变化曲线。常见的结果是深度从 1 增加到 5 时测试集 AUC 快速上升5 到 10 之间趋于平缓10 之后训练集 AUC 继续涨但测试集 AUC 开始下滑。这个拐点就是你要选的深度值。不看学习曲线直接抄别人代码里的 max_depth5往往会在自己的数据上翻车因为最优深度和特征数量、样本量强相关。4. 梯度提升与逻辑回归两类建模路线的正面交锋4.1 梯度提升train_use_boosting.py 的弱学习器组合逻辑train_use_boosting.py 对应梯度提升模型boost.png 和 sample_leaf.png 是它的配套图像。梯度提升的思路和随机森林相反随机森林并行训练多棵树再投票梯度提升串行地一棵一棵训练每一棵新树都在拟合前面所有树拼起来还剩下的残差。这个逻辑决定了梯度提升在表格数据上通常精度更高但训练更慢、参数更多、更容易过拟合。from sklearn.ensemble import GradientBoostingClassifier gbc GradientBoostingClassifier( n_estimators200, learning_rate0.05, max_depth4, min_samples_leaf100, subsample0.8, random_state42 ) gbc.fit(X_train, y_train) print(训练集AUC:, roc_auc_score(y_train, gbc.predict_proba(X_train)[:, 1])) print(测试集AUC:, roc_auc_score(y_test, gbc.predict_proba(X_test)[:, 1]))梯度提升的参数比随机森林更敏感。learning_rate0.05表示每棵树只贡献 5% 的预测能力学习率越小需要的树越多但过拟合风险越低。n_estimators200配合 0.05 的学习率在中等规模数据集上是一个比较稳妥的起点。subsample0.8表示每棵树只用 80% 的样本这能引入随机性、抑制过拟合效果类似随机森林的行采样。min_samples_leaf100在梯度提升里要比在随机森林里设得更大因为每棵树拟合的是残差叶子太细容易把噪声也拟合进去。sample_leaf.png 如果我没猜错画的是 min_samples_leaf 不同取值下的模型表现曲线。这类曲线有一个很典型的规律随着 min_samples_leaf 增大训练集 AUC 平缓下降测试集 AUC 先升后降。最优值通常在 50 到 200 之间如果这个值太小你会看到训练集 AUC 非常高而测试集 AUC 很低这是梯度提升最经典的过拟合症状。4.2 逻辑回归和信用评分卡train_use_lr.py 的可解释性优势train_use_lr.py 是用逻辑回归做违约预测的脚本lr.png 应该是系数或者 ROC 相关图像。在这个项目里补上逻辑回归不是为了刷 AUC而是为了给整个建模流程一个可解释性出口。树模型的预测结果只能告诉你客户违约概率高逻辑回归却能把每个特征的贡献量化成系数这在需要向监管或业务方解释模型逻辑的信贷场景里是硬需求。from sklearn.linear_model import LogisticRegression from sklearn.preprocessing import StandardScaler scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) lr LogisticRegression( penaltyl2, C1.0, solverliblinear, max_iter500, random_state42 ) lr.fit(X_train_scaled, y_train) coef_df pd.Series(lr.coef_[0], indexX.columns) print(coef_df.sort_values(ascendingFalse))逻辑回归建模前需要标准化因为 L2 正则化惩罚的是系数绝对值大小如果特征量纲不一致量纲大的特征会无辜地受到更重的惩罚。penaltyl2是默认配置C1.0是正则强度的倒数C 越小惩罚越强。solverliblinear对中小规模二分类数据集比较合适样本量大了可以考虑换成 lbfgs。max_iter500防止某些特征尺度悬殊时迭代不收敛。如果想把逻辑回归升级成真正意义上的信用评分卡常见做法是先把连续变量分箱、做 WOE 编码再送入逻辑回归。这套源码里没有单独列出评分卡转换脚本但 train_use_lr.py 已经提供了逻辑回归的训练框架你只需要把原始特征替换成分箱后的 WOE 值就能得到标准评分卡。评分卡的输出公式很简单基础分加上每个特征的系数乘 WOE 值再经过一个线性变换映射成 300 到 850 之间的信用分。这个变换在银行为主的信贷体系里有一套自己的标准不同机构的基准分和刻度不一样。逻辑回归的精度通常比梯度提升低几个点的 AUC但换来的是完全可解释的系数。在风控业务里有时一个能说清楚逻辑的 0.75 AUC 模型比一个说不清楚逻辑的 0.78 AUC 模型更受业务方欢迎因为前者能直接支撑审批策略的调整。系数方向也值得检验月收入系数应该是负的、90 天逾期次数系数应该是正的如果符号和业务直觉相悖赶紧回去查数据。4.3 模型对比怎么落地从 boost.png、lr.png 到 open.png项目里的 boost.png、lr.png、dtc.png、rfc.png 分别来自四个模型的训练记录而 open.png 我猜测是某个整体对比图可能是四条 ROC 曲线叠加在同一张图上的效果。看这类对比图不能只看谁的面积大还要看曲线在哪个区间拉开了差距。如果两个模型在高分段低假阳率区域表现接近在低分段差距明显那实际决策时需要优先考虑高分段的表现因为信贷审批通常只挑分数最高的那批客户放款。模型对比的实操方法是把召回率、精确率、AUC、KS 放在一张表里统一看而不是只盯 AUC。模型训练集 AUC测试集 AUCKS可解释性训练耗时决策树0.720.680.31高极短随机森林0.850.780.39中短梯度提升0.880.800.42低长逻辑回归0.760.740.35高极短上面的数字是示意不是这套源码在固定随机种子下的确定输出具体数值要看你自己跑出来的结果。但几个规律是稳定的树模型的训练集 AUC 会明显高于测试集集成模型的测试集 AUC 通常优于单棵树和逻辑回归逻辑回归的测试集 AUC 和训练集 AUC 差距最小。如果你的结果里随机森林的训练集 AUC 到了 0.9 以上而测试集只有 0.7说明需要加大 min_samples_leaf 或者减小 max_depth。模型选择到最后往往不是单纯比精度而是要结合部署环境和解释需求。如果目标是课程设计展示三个模型对比图表本身就能撑起一个章节如果目标是真实业务落地我会建议用梯度提升做线上预测、用逻辑回归做策略解释两个模型并行跑互相校验。5. 避坑贷款违约建模中常见的四个翻车现场5.1 四个高频踩坑记录第一个坑是缺失值填充方式想当然。现象直接用 MonthlyIncome 的均值填充后逻辑回归的系数出现异常负债率特征变得不显著。原因收入变量右偏严重均值被少数高收入样本拉高大部分中低收入客户的填充值偏大进而扭曲了 DebtRatio 的语义。解决先用直方图看收入分布再用中位数填充或者用其他字段训练一个简单模型预测缺失收入我在这个数据集上习惯用中位数简单稳定。第二个坑是训练集和测试集处理不一致。现象训练集 AUC 很高测试集 AUC 明显偏低但模型没有明显过拟合。原因数据清洗时只处理了训练集用train.dropna()删掉了缺失行然后拿没有缺失的训练集和仍带缺失的测试集去做同样预处理测试集直接报错或者效果崩盘。解决把所有数据清洗逻辑封装成函数训练集和测试集调用同一套函数缺失值填充的中位数必须在训练集上计算再应用到测试集绝不能拿测试集统计量去回填测试集那是数据泄露。第三个坑是用准确率评估模型。现象模型预测结果里违约一个都没抓到但准确率高达 94%汇报时被业务方质疑模型没卵用。原因违约样本占比只有 6%全部预测为不违约就能拿 94% 准确率模型实际没有任何区分能力。解决评估指标换成 AUC、KS、召回率重点看违约样本的召回率。我在实际项目里还会单独看模型在违约样本 top 5% 概率区间里的命中率这才是风控真正关心的数字。第四个坑是决策树深度不设上限。现象决策树训练集 AUC 0.99测试集 AUC 0.62过拟合严重。原因默认的 max_depthNone 会让树一直分裂到每个叶子只有一个样本等于把训练集完整背了下来。解决先把 max_depth 限定在 3 到 15 之间遍历再配合 min_samples_leaf 一起调我通常先把 min_samples_leaf 固定为 50再扫 max_depth这样两个参数不会互相干扰。5.2 图像文件的误读学习曲线、分布图、ROC 曲线别搞混这套源码附带的 11 张 PNG 图里有一部分是中间诊断图有一部分是最终结果图第一次拿到项目的人容易把所有图都当成成绩单来读。我的建议是先把图分成三类数据分布图看样本结构学习曲线图看模型状态ROC 曲线图看模型能力。把 distribution 图当成 ROC 去解读会觉得这个模型烂到没法看其实只是类分布不均衡而已。还有一类误读是把单次划分的 AUC 当成交叉验证结果。如果图像里只有一条测试集曲线而没有方差阴影说明它大概率是一次固定划分的结果这类结果稳定性有限换一个 random_state 可能就差一两个点不用过度纠结。真正可靠的做法是自己跑一遍交叉验证把五个折的 AUC 均值当作模型真实水平的估计值图像文件只作为辅助诊断存在。6. 用 predict.py 完成预测闭环从训练权重到新样本打分6.1 predict.py 的常见调用方式predict.py 在整套源码里是收尾角色它把训练好的模型应用到新数据上。训练脚本和预测脚本分开写这是工程上的好习惯否则每次预测都要重新训练一遍模型。predict.py 的常见结构是加载训练阶段保存的模型文件读取待预测的测试集做和训练时完全相同的数据预处理输出每个客户的违约概率。import pandas as pd import joblib model joblib.load(best_model.pkl) test pd.read_csv(cs-test.csv, index_col0) test[MonthlyIncome] test[MonthlyIncome].fillna( test[MonthlyIncome].median() ) # 注意这里的中位数应该来自训练集不能在本脚本里重新算 prob model.predict_proba(test)[:, 1] result pd.DataFrame({ customer_id: test.index, default_prob: prob }) result.to_csv(prediction_result.csv, indexFalse)这里有一个我在实际项目里交过学费的点测试集填充用的中位数必须在训练阶段算好并存下来而不是在 predict.py 里拿测试集现算。测试集的中位数含了测试样本自己的信息用它填充相当于把未来的数据泄露进了预测流程这在真实业务里是不允许发生的。正确做法是在训练脚本里把train[MonthlyIncome].median()保存成一个小文件predict.py 直接加载这个值来用。6.2 概率阈值与业务成本不是大于 0.5 就拒绝模型输出的违约概率不能直接拿去拒绝客户0.5 这个阈值对信贷场景没有任何业务含义。正确的做法是画出概率分布直方图看好客户和坏客户在哪个概率区间重叠再把审批通过率目标和坏账容忍度放进去反推阈值。比如业务要求坏账率不超过 3%就在预测结果里从低概率到高概率累加找到能让坏账率刚好不超过 3% 那个概率值作为审批线。如果同时要在成本和收益之间权衡可以构造一个最简单的损失矩阵拒绝一个好客户损失一笔潜在收入放行一个坏客户损失一笔本金。把两个损失比代进去最优阈值会从 0.5 明显偏移到更低或更高的位置。这类判断在源码里没有成品代码但 predict.py 输出概率之后你完全可以用 pandas 把这段逻辑补出来代码量不超过二十行。6.3 每次训练必须留下的四样东西从那以后我每次在信贷数据上训练模型都强制走一遍模型权重文件、特征列表、预处理参数、评估指标记录这四样东西一样都不能少。特征列表尤其重要训练时用了哪些字段、顺序是什么预测时必须完全一致少一个字段整个模型就在报错和静默出错之间二选一。预处理参数包括刚才说的中位数、众数、标准化用的均值和标准差这些参数要和模型文件存在一起最好加个版本号。这个习惯是从一次翻车里学来的。当时我给银行交付一个违约预测接口预测脚本里少了一个训练阶段做过的字段类型转换线上连续预测了一个月都没报错结果后期排查发现那一个字段的类型从数值变成了对象模型在这个字段上全部取了缺失值路径预测概率整体偏差了差不多 3 个百分点。从那以后我要求自己无论是课程设计还是真实项目训练脚本和预测脚本必须共享同一个预处理函数定义不允许各写一份。希望这个小习惯对你也有用。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门