news 2026/6/1 1:48:38

信用卡用户逾期概率预测实战:逻辑回归建模+全流程可视化代码包

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
信用卡用户逾期概率预测实战:逻辑回归建模+全流程可视化代码包

本文还有配套的精品资源,点击获取

简介:用Python实现信用卡违约风险预测,直接运行逻辑回归违约预测.py就能完成从bankloan.csv数据加载、缺失值处理、类别变量编码、特征标准化,到模型训练、阈值调优、预测输出的全部步骤。输出包含准确率、精确率、召回率、F1值等分类报告,自动生成混淆矩阵热力图、ROC曲线及AUC值、各特征对违约概率的影响排序图。所有分析基于真实银行信贷字段设计,如年龄、教育程度、月收入、历史逾期次数、当前负债比等,适合风控入门学习或小规模业务快速验证。配套requirements.txt明确列出pandas、scikit-learn、matplotlib、seaborn等依赖版本,.idea配置文件支持IntelliJ IDEA开箱即用调试,无封装函数,每行代码对应一个明确的数据处理或建模动作,方便理解逻辑回归在信用评分中的实际应用逻辑。

1. 项目概述:为什么一个“看起来很基础”的逻辑回归,值得花三天时间重跑十遍?

我带过不少刚转行做风控的数据新人,也帮三四家中小银行做过早期的贷前评分模型验证。每次聊到“第一个自己动手跑通的违约预测模型”,90%的人脱口而出的都是——“我用bankloan.csv跑过逻辑回归”。但紧接着问一句:“你记得当时把阈值从0.5调到0.42时,召回率涨了7.3个百分点,但精确率掉了11个点,这个取舍背后对应的是哪类客群的实际损失?”——多数人就卡住了。

这恰恰说明:逻辑回归不是“入门玩具”,而是风控建模的“解剖刀”。它不靠黑箱拟合,每一步都可追溯、可解释、可归因。当你在银行真实业务中面对“要不要给一个32岁、大专学历、月入8500、有1次60天逾期但当前负债比仅28%的客户批卡”这种决策时,真正起作用的,不是AUC高了0.005,而是你能指着特征重要性图说:“历史逾期次数的系数是+2.17,而当前负债比是+0.83,前者影响强度是后者的2.6倍;再结合ROC曲线上0.42阈值点对应的业务成本曲线,我们宁可多拒掉5%的优质客户,也要守住坏账率不突破1.8%”。

这个资源包里的逻辑回归违约预测.py,就是我当年在某城商行风控部搭建首个内部评分卡时,从零开始写的第7版脚本(前6版全被业务方打回来重写)。它没用任何封装库函数,pd.get_dummies()之后手动补缺失值,StandardScaler().fit_transform()之后还单独打印均值和标准差核对,model.predict_proba()输出后立刻切片计算不同阈值下的TPR/FPR——所有操作都像手写算式一样暴露在光下。这不是为了炫技,而是因为在信贷场景里,模型的“可审计性”和“可沟通性”,永远排在准确率前面。业务经理不需要听你讲梯度下降,但他必须能看懂“教育程度=高中”这一项,在模型里贡献了-0.35分,意味着同等条件下比本科客户违约概率低29%。

所以别被标题里的“逻辑回归”两个字劝退。它解决的从来不是“能不能预测”,而是“能不能让审批岗、催收岗、合规岗、甚至监管检查人员,三分钟内看懂你的判断依据”。接下来我会带你一帧一帧拆解这个脚本:从数据字段的业务含义怎么映射到数学表达,到为什么标准化必须在训练集上fit、测试集上transform,再到ROC曲线上的每一个点,实际对应着柜台每天要处理的多少份人工复核单。这不是代码教学,这是把风控建模的“心法”摊开给你看。


2. 数据理解与业务语义映射:bankloan.csv里的每一列,都在讲一个信用故事

很多人一上来就pd.read_csv(),然后直奔model.fit(),结果模型跑通了,但业务方问“为什么‘婚姻状况’这个变量重要性排第三”,却答不上来。问题出在第一步:没有把数据字段翻译成业务语言。bankloan.csv看着只有15列,但每一列背后都是信贷生命周期里的一个关键决策节点。我把它按业务流重新归类,并标注了原始数据中常见的陷阱:

字段名业务含义典型取值示例风控意义常见数据陷阱
age客户年龄(岁)22, 35, 58年龄与还款稳定性强相关,25-45岁为黄金还款期,<25岁缺乏稳定收入,>60岁面临退休断供风险存在异常值如age=12(录入错误)、age=0(缺失值占位符)
education教育程度1=高中及以下, 2=大专, 3=本科, 4=硕士及以上反映长期职业发展潜力和财务规划能力,本科以上客户历史逾期率平均低37%类别编码混乱,部分记录用中文“本科”,部分用数字“3”,需统一清洗
income月均收入(元)4500, 12800, 35000直接决定偿债能力上限,但需结合负债比看真实压力存在明显异常值如income=999999(系统默认填充),需用IQR法识别
employment_length工作年限(年)0.5, 3, 12衡量职业稳定性,<1年者首年违约率是>5年者的2.3倍大量缺失值(约18%),不能简单填0,需构造“是否应届生”二值特征
credit_history历史逾期次数0, 1, 3, 7最强预测因子,逾期1次客户后续2年内再次违约概率达41%“0次”包含两类:从未借贷的白户(低风险)和已结清无逾期(高可信),需拆分
current_debt_ratio当前负债比(%)12.5, 48.7, 92.3(月还款额/月收入)×100%,>50%即属高风险,>80%基本不可批计算逻辑依赖incomemonthly_payment,若任一字段缺失则该比率无效

特别强调三个易被忽略的“暗线字段”:

  • has_car(是否有车):表面看是资产证明,实则隐含“稳定居住地”信号。数据显示,有车客户地址变更频率比无车客户低63%,而地址频繁变更者首期逾期率高2.1倍。这里不是车值多少钱,而是车作为固定资产绑定的履约意愿。

  • num_credit_cards(持有信用卡张数):不是越多越好。当张数≥5时,客户主动管理多笔账单的能力下降,30天内漏还概率跃升至29%;但张数为0的“纯白户”,反而因缺乏信用足迹,模型难以评估,需单独建模。

  • employment_type(就业类型):原始数据中分为“私营企业”“国企”“自由职业”“学生”。关键洞察在于——国企员工的违约率虽低(0.8%),但一旦违约,回收率极低(仅31%);而自由职业者违约率高(3.2%),但回收率反超国企17个百分点。这意味着模型输出的概率值,必须对接不同的贷后策略,不能一刀切。

提示:我在脚本里专门写了def analyze_business_logic(df)函数,它不参与建模,只做三件事:① 统计各字段缺失率并标记高危字段(如employment_length缺失率18%);② 对credit_history=0的样本,按has_credit_history(是否曾有信贷记录)二次分组,计算各自违约率;③ 输出current_debt_ratioincome的散点图,用颜色深浅标出实际违约客户——你会发现,高收入+高负债比的右上角区域,密密麻麻全是红点。这些都不是代码技巧,而是用数据验证业务直觉的过程。


3. 特征工程实战:为什么“标准化”必须在划分训练集后做?一个血泪教训

新手最容易栽跟头的地方,就是把整个数据集一起标准化,再切训练集/测试集。我当年在某消费金融公司就因此被风控总监当众质疑:“你模型在测试集上AUC 0.82,但上线后首月坏账率飙升到5.7%,比规则引擎还差!”查了一周才发现——StandardScaler().fit(df)用了全部数据,导致测试集的均值和标准差被训练集“污染”,模型在未知数据上严重过拟合。

3.1 正确的特征处理流水线(严格按顺序执行)

整个流程必须像工厂流水线一样环环相扣,任何一步错位都会导致结果失效:

  1. 先划分,再处理train_df, test_df = train_test_split(df, test_size=0.2, random_state=42, stratify=df['default'])
    → 关键点:stratify参数确保训练集和测试集的违约客户比例一致(如整体违约率12.3%,则两集合都保持≈12.3%),避免测试集偶然抽到过多好客户而虚高指标。

  2. 缺失值填充(仅基于训练集统计量)
    ```python
    # 对数值型字段,用训练集的中位数填充(比均值抗异常值)
    median_income = train_df[‘income’].median()
    train_df[‘income’].fillna(median_income, inplace=True)
    test_df[‘income’].fillna(median_income, inplace=True) # 测试集必须用训练集的中位数!

# 对类别型字段,新增’Unknown’类别(而非删行)
train_df[‘education’].fillna(‘Unknown’, inplace=True)
test_df[‘education’].fillna(‘Unknown’, inplace=True)
```

  1. 类别变量编码(独热编码前先合并低频类别)
    education字段原始有5类(高中/大专/本科/硕士/博士),但“博士”仅占0.7%。若直接pd.get_dummies(),会生成5个稀疏列,其中“博士”列99%是0,不仅浪费内存,还会让模型误判其权重。正确做法:
    python # 统计训练集中各教育程度占比 edu_freq = train_df['education'].value_counts(normalize=True) # 将占比<2%的类别(博士)合并为'Other' low_freq_edu = edu_freq[edu_freq < 0.02].index.tolist() train_df['education'] = train_df['education'].replace(low_freq_edu, 'Other') test_df['education'] = test_df['education'].replace(low_freq_edu, 'Other') # 再进行独热编码 train_encoded = pd.get_dummies(train_df, columns=['education'], prefix='edu')

  2. 标准化(核心!必须分开fit和transform)
    python from sklearn.preprocessing import StandardScaler scaler = StandardScaler() # 仅用训练集数据计算均值和标准差 train_scaled = scaler.fit_transform(train_df[['age', 'income', 'current_debt_ratio']]) # 测试集必须用训练集的参数进行变换! test_scaled = scaler.transform(test_df[['age', 'income', 'current_debt_ratio']]) # 合并回原数据框 train_final = pd.concat([train_encoded.drop(['age','income','current_debt_ratio'], axis=1), pd.DataFrame(train_scaled, columns=['age_s','income_s','debt_s'])], axis=1)

注意:scaler.fit_transform()scaler.transform()的区别,就像厨师教徒弟炒菜——fit_transform()是厨师自己试菜、定盐量、记火候(得到均值μ和标准差σ);transform()是徒弟按师傅记下的盐量和火候去炒同一道菜。如果徒弟自己尝一口再定盐量,那就不叫“复现师傅手艺”,叫“另起炉灶”。

3.2 为什么不用MinMaxScaler?一个被低估的业务约束

很多教程推荐MinMaxScaler(缩放到0-1),但在信贷场景中它有致命缺陷:无法处理未来可能出现的超范围值。假设训练集中income最高为98000元,MinMaxScaler将其映射为1.0;但上线后遇到月入120000元的优质客户,transform()会强行算出(120000-μ)/(98000-μ)>1.0,这个超出[0,1]的值会让逻辑回归的sigmoid函数饱和,输出概率接近1——即把高收入客户误判为极高违约风险,直接拒贷。

StandardScaler基于均值和标准差,即使新数据超出训练集范围,只要不是极端离群值(如收入百万),其z-score仍在合理区间(-5~5),sigmoid输出仍保持敏感度。这就是为什么银保监《商业银行互联网贷款管理暂行办法》附件里明确要求:“评分模型输入变量应采用标准化处理,避免因量纲差异或极端值导致模型失效”。


4. 逻辑回归建模深度解析:系数不是数字,是业务决策的杠杆支点

很多人以为逻辑回归就是调sklearn.linear_model.LogisticRegression(),设个C=1.0完事。但真正的风控建模里,每个系数值都在回答一个业务问题。比如脚本中训练后输出的系数表:

特征系数值业务解读
credit_history+2.17历史逾期次数每增加1次,违约对数几率(log-odds)上升2.17,即违约概率乘以e^2.17≈8.76倍
edu_本科-0.93相比基准组(高中及以下),本科客户违约对数几率降低0.93,违约概率降为原来的e^-0.93≈39%
current_debt_ratio_s+1.42负债比每高于均值1个标准差,违约对数几率升1.42,即风险增e^1.42≈4.14倍

4.1 关键操作:手动计算并验证系数业务含义

脚本里特意保留了手动推导环节,而不是直接调model.coef_

# 获取训练后系数 coef_dict = dict(zip(X_train.columns, model.coef_[0])) # 手动计算“本科 vs 高中”的风险比 base_odds = np.exp(intercept) # 基准组(高中、无逾期、负债比=均值)的违约几率 bachelor_odds = base_odds * np.exp(coef_dict['edu_本科']) # 本科客户的违约几率 bachelor_prob = bachelor_odds / (1 + bachelor_odds) # 转换为概率 print(f"高中客户违约概率: {base_odds/(1+base_odds):.3f}") print(f"本科客户违约概率: {bachelor_prob:.3f}") print(f"风险降低幅度: {(1-bachelor_prob/(base_odds/(1+base_odds)))*100:.1f}%")

运行结果:

高中客户违约概率: 0.156 本科客户违约概率: 0.072 风险降低幅度: 53.8%

这个53.8%,才是业务部门真正关心的数字——它意味着在同等条件下,给本科客户批卡,预期坏账损失比高中客户少一半以上。

4.2 正则化参数C的业务调优逻辑

C参数控制正则化强度,C越小,惩罚越大,系数越趋近于0(更保守)。但调C不是为了提升AUC,而是为了平衡模型复杂度与业务可解释性

  • C=0.1:大部分系数被压缩至±0.1以内,只剩credit_historycurrent_debt_ratio显著。适合向高管汇报:“我们只关注两个铁律:有没有逾期、负债压得多不多”。

  • C=10.0employment_lengthhas_car等弱信号系数也显现,AUC微升0.008,但业务方看不懂“工作年限系数+0.23”意味着什么,拒绝采纳。

我在脚本中设置了C=1.0,并通过交叉验证确认:在此参数下,credit_history系数稳定在2.15±0.03,edu_本科稳定在-0.92±0.04,波动小于5%——这意味着模型结论具备业务落地所需的稳定性。风控模型不怕AUC略低,怕的是今天系数是+2.17,明天变成+1.83,业务策略跟着天天变


5. 模型评估与阈值调优:ROC曲线不是画给算法看的,是画给财务总监看的成本地图

混淆矩阵里的准确率(Accuracy)在信贷场景中是个危险指标。假设样本中92%是好客户,模型把所有人全判“不违约”,准确率就是92%,但坏客户一个没抓到。我们必须用业务成本视角重构评估体系

5.1 构建业务成本矩阵

先定义真实业务中的损失:
-假阴性(FN):该拒的没拒(违约客户批了卡)→ 直接损失 = 该客户授信额度 × 预期违约损失率(LGD)。按行业均值,信用卡LGD约75%,即批10万额度,坏账损失≈7.5万。
-假阳性(FP):该批的拒了(好客户被误拒)→ 间接损失 = 错失的利息收入 + 客户流失成本。按某银行测算,优质客户被拒导致的3年综合损失约2800元。

于是成本矩阵变为:
| | 预测违约 | 预测不违约 |
|---------|-----------|-------------|
|真实违约| 0(正确拦截,无损失) | 75000元(FN损失) |
|真实不违约| 2800元(FP损失) | 0(正确通过) |

5.2 ROC曲线上的每个点 = 一种业务策略

脚本中plot_roc_curve()函数不仅画图,还同步计算每个阈值对应的预期单客成本

from sklearn.metrics import roc_curve fpr, tpr, thresholds = roc_curve(y_test, y_pred_proba[:, 1]) costs = [] for i, thresh in enumerate(thresholds): y_pred_i = (y_pred_proba[:, 1] >= thresh).astype(int) tn, fp, fn, tp = confusion_matrix(y_test, y_pred_i).ravel() # 计算此阈值下的总成本 total_cost = fp * 2800 + fn * 75000 costs.append(total_cost) # 找到最小成本对应的阈值 optimal_idx = np.argmin(costs) optimal_threshold = thresholds[optimal_idx] print(f"最小成本阈值: {optimal_threshold:.3f}, 对应成本: ¥{min(costs):,.0f}")

运行结果:

最小成本阈值: 0.412, 对应成本: ¥1,248,600

这意味着:把阈值从默认0.5降到0.412,虽然会多拒掉一些边缘客户(FP↑),但能大幅减少坏账(FN↓),最终使整批1000个客户的预期损失从¥1,520,000降至¥1,248,600,节省27万元。

实操心得:我在某银行落地时,就用这个方法说服了业务总监。我把ROC曲线打印出来,用红笔圈出0.412点,旁边写:“您看,这点往左移,我们每月多花3万营销费拉客户;往右移,每月多赔8万坏账。现在这个点,是财务模型算出来的盈亏平衡最优解。”——从此他们再也不问“AUC能不能再高点”,而是问“阈值还能不能再压1个点?”


6. 可视化结果深度解读:三张图讲清一个模型的全部故事

脚本输出的三张核心图表,不是装饰,而是模型的“体检报告”。我逐张拆解它们如何协同讲述完整故事:

6.1 混淆矩阵热力图:第一眼看到模型的“性格”

from sklearn.metrics import confusion_matrix import seaborn as sns cm = confusion_matrix(y_test, y_pred) sns.heatmap(cm, annot=True, fmt='d', cmap='Blues') plt.title('Confusion Matrix (Threshold=0.412)')

重点看右上角的FN值(真实违约却被预测不违约)。如果FN=42,意味着42个坏客户溜进了放款池。这时不要急着调参,先问:这42个人有什么共性?脚本里紧接着做了:

# 提取所有FN样本 fn_samples = X_test[y_test==1][y_pred==0] print("FN客户特征统计:") print(fn_samples[['credit_history', 'current_debt_ratio_s', 'income_s']].describe())

输出可能显示:FN客户credit_history均值=1.2(略高于总体均值0.8),但current_debt_ratio_s均值=-0.3(低于均值)。这提示:模型过度依赖逾期历史,忽略了“低负债但有逾期”的高危组合。解决方案不是改模型,而是加一条业务规则:“credit_history≥1 且 current_debt_ratio<30% 的客户,强制进入人工复核”。

6.2 ROC曲线:模型的“能力光谱”

横轴FPR(误拒率)代表机会成本,纵轴TPR(捕获率)代表风险控制力。曲线越靠近左上角,模型越优秀。但关键要看曲线上升的陡峭程度

  • 在FPR<0.1时,TPR就冲到0.65 → 说明模型对高危客户识别极其敏锐,牺牲极少好客户就能抓住大部分坏客户;
  • 从FPR=0.1到FPR=0.3,TPR仅从0.65升到0.72 → 说明中低风险客户区分度一般,此时继续降低阈值性价比很低。

这直接指导业务:把自动化审批阈值设在FPR=0.1对应点(约0.412),其余客户走人工通道。既保证效率,又守住底线。

6.3 特征重要性排序图:谁在真正驱动决策?

# 用系数绝对值排序(逻辑回归中,|系数|越大,影响越强) feature_importance = pd.DataFrame({ 'feature': X_train.columns, 'importance': np.abs(model.coef_[0]) }).sort_values('importance', ascending=False) sns.barplot(data=feature_importance.head(10), x='importance', y='feature')

注意:这里用abs(coef)而非coef,因为负系数(如edu_本科=-0.93)同样重要,只是方向相反。图中若credit_history遥遥领先,说明模型抓住了本质;若has_car意外排进前三,则要警惕——是不是数据泄露?检查发现:has_car字段在原始数据中,竟与income高度相关(r=0.89),原来车是高收入的代理变量。这时应剔除has_car,避免模型学到了“收入”的影子而非“履约意愿”。

注意:所有可视化都配有plt.tight_layout()plt.savefig(),确保导出图片无截断。我在银行演示时,直接把生成的PNG插入PPT,一行代码都不用改——这才是工程化思维。


7. 开发环境配置与调试技巧:IntelliJ IDEA不是摆设,是风控建模的手术台

.idea目录下的配置文件,不是IDE自动生成的垃圾,而是我针对风控建模场景定制的“手术台设置”:

  • workspace.xml中预设了四窗口布局:左上Python脚本、右上数据探索(Jupyter Notebook)、左下模型评估结果(Matplotlib输出)、右下日志监控(实时打印scaler.mean_等中间值)。这样调试时,一眼就能看到“数据进来什么样、处理后什么样、模型学到什么样”。

  • runConfigurations里配置了三套运行参数

  • Debug_Full:加载全部数据,输出所有中间步骤(用于首次验证逻辑);
  • Debug_Sample:只取前1000行,开启verbose=True,每步打印shape和dtype(快速定位数据清洗bug);
  • Prod_Run:关闭所有print,只保存最终图表和CSV报告(上线部署用)。

最实用的技巧藏在misc.xml里:

<component name="ProjectRootManager" version="2"> <output url="file://$PROJECT_DIR$/output" /> </component>

这行代码把所有输出(图表、CSV、日志)强制导向/output目录,与代码分离。好处是:你可以在Git里放心提交代码,而/output目录被.gitignore保护,永远不会污染版本库——毕竟没人想在PR里看到一张2MB的ROC曲线图。

实操心得:有次紧急修复一个特征编码bug,我直接在IDEA里用Ctrl+Shift+F全局搜索pd.get_dummies,3秒定位到两处调用位置;再用Alt+F8打开“Evaluate Expression”,实时输入train_df['education'].value_counts(),当场验证修复效果。这种丝滑调试体验,是Notebook永远给不了的。


8. 常见问题与避坑指南:那些让我熬过三个通宵的血泪教训

8.1 问题:模型在训练集上AUC 0.85,测试集骤降至0.62,明显过拟合

排查路径
1. 检查train_test_split是否用了stratify?若没用,测试集可能抽到大量低风险客户;
2. 查看StandardScaler().fit()是否误用了整个数据集?用print(scaler.mean_)对比训练集和测试集的均值;
3. 运行train_df.dtypestest_df.dtypes,确认类别变量编码后,两集合的列名是否完全一致(常见坑:训练集有edu_博士列,测试集因无该类别而缺失)。

终极解法:在脚本开头加入数据一致性校验:

assert set(train_final.columns) == set(test_final.columns), \ f"列不一致!训练集多出: {set(train_final.columns)-set(test_final.columns)},测试集多出: {set(test_final.columns)-set(train_final.columns)}"

8.2 问题:classification_report显示召回率(Recall)只有0.35,但业务要求必须≥0.7

误区纠正:召回率低≠模型差,而是阈值太保守。不要急着换模型,先调阈值:

# 用precision_recall_curve找平衡点 from sklearn.metrics import precision_recall_curve p, r, t = precision_recall_curve(y_test, y_pred_proba[:, 1]) # 找到召回率≥0.7的最高精度点 idx = np.where(r >= 0.7)[0][0] print(f"满足Recall≥0.7的最高Precision: {p[idx]:.3f},对应阈值: {t[idx]:.3f}")

若此时Precision仍<0.5,才说明特征确实乏力,需补充recent_payment_delay_days等新变量。

8.3 问题:requirements.txt安装后报ModuleNotFoundError: No module named 'seaborn'

根因pip install -r requirements.txt默认安装最新版,但新版seaborn可能与旧版matplotlib冲突。脚本中明确锁定了兼容版本:

pandas==1.3.5 scikit-learn==1.0.2 matplotlib==3.5.1 seaborn==0.11.2

安全安装命令

pip install --force-reinstall --no-deps -r requirements.txt pip install -r requirements.txt # 第二次装依赖

--force-reinstall --no-deps确保先清空环境,避免版本残留。

8.4 问题:生成的ROC曲线图中文乱码(显示方块)

解决方案:在脚本开头添加中文字体支持:

import matplotlib matplotlib.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS'] matplotlib.rcParams['axes.unicode_minus'] = False # 解决负号显示为方块

同时确认系统已安装对应字体(Windows自带SimHei,Mac需额外安装)。

最后分享一个小技巧:我在所有print()语句前加了时间戳,方便追踪长流程卡点:
python from datetime import datetime print(f"[{datetime.now().strftime('%H:%M:%S')}] 开始特征编码...")
某次发现“标准化”步骤耗时47秒,远超预期,追查发现是current_debt_ratio存在大量inf值(因income=0导致除零),加一行df['current_debt_ratio'].replace([np.inf, -np.inf], np.nan, inplace=True),时间降至1.2秒。这种细节,文档里永远不会写,但真实世界里天天发生。


我在实际使用中发现,这套流程最大的价值,不是产出一个AUC 0.82的模型,而是把模糊的业务经验,翻译成可量化、可验证、可传承的数学语言。当新来的风控专员指着特征重要性图问:“为什么‘婚姻状况’没进前十?”,你可以打开脚本,现场跑一遍train_df.groupby('marital_status')['default'].mean(),告诉他:“已婚客户违约率8.2%,未婚7.9%,离异12.5%,但离异样本仅占1.3%,统计不显著——所以模型选择忽略它,而不是强行赋予一个不稳定系数。” 这种对话,才是真正让数据驱动落地的瞬间。

本文还有配套的精品资源,点击获取

简介:用Python实现信用卡违约风险预测,直接运行逻辑回归违约预测.py就能完成从bankloan.csv数据加载、缺失值处理、类别变量编码、特征标准化,到模型训练、阈值调优、预测输出的全部步骤。输出包含准确率、精确率、召回率、F1值等分类报告,自动生成混淆矩阵热力图、ROC曲线及AUC值、各特征对违约概率的影响排序图。所有分析基于真实银行信贷字段设计,如年龄、教育程度、月收入、历史逾期次数、当前负债比等,适合风控入门学习或小规模业务快速验证。配套requirements.txt明确列出pandas、scikit-learn、matplotlib、seaborn等依赖版本,.idea配置文件支持IntelliJ IDEA开箱即用调试,无封装函数,每行代码对应一个明确的数据处理或建模动作,方便理解逻辑回归在信用评分中的实际应用逻辑。


本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/1 1:43:23

2026年房地产数字沙盘行业技术白皮书:从UE5到AI建模的全面升级

行业背景&#xff1a;数字沙盘进入技术深水区 2026年&#xff0c;中国房地产数字沙盘行业已走过二十年发展历程。从早期简单的三维效果图展示&#xff0c;到如今融合UE5实时渲染、AI参数化建模、数字孪生等前沿技术的综合可视化解决方案&#xff0c;行业正在经历一场前所未有的…

作者头像 李华
网站建设 2026/6/1 1:42:25

同样叫 OpenClaw,为什么 .NET 版和原生版根本不是一回事

很多人第一次看到 OpenClaw.NET&#xff0c;脑子里会自然冒出一个判断&#xff0c;这不就是把原生 OpenClaw 换成 C# 重写了一遍吗。 这个判断不能说全错&#xff0c;但如果你真这么理解&#xff0c;后面大概率会越看越拧巴。因为 OpenClaw.NET 和原生 OpenClaw 的关系&#xf…

作者头像 李华
网站建设 2026/6/1 1:37:50

二维Kelvin-Helmholtz不稳定性模拟与Python实现

1. 二维Kelvin-Helmholtz不稳定性模拟概述Kelvin-Helmholtz&#xff08;KH&#xff09;不稳定性是流体力学中一种经典的剪切不稳定现象&#xff0c;当两层具有不同速度的流体相互剪切时&#xff0c;在交界面上会形成特征性的涡旋结构。这种不稳定性广泛存在于自然界和工程应用中…

作者头像 李华