ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

信用卡数据集分析预测实战:从特征处理到模型调参全流程

信用卡数据集分析预测实战:从特征处理到模型调参全流程 简介面向机器学习和数据分析初学者的信用卡场景实战包围绕信用卡申请审批预测与欺诈识别两个核心任务展开。包内共7个文件包含5份Python源代码、1份readme说明文档和1个CSV格式的信用卡数据集约34.81 KB压缩包整体18KB代码基于pandas、numpy、plotly.express、seaborn及sklearn常用模块编写注释清晰且可独立运行。源码分别覆盖数据预处理、基础分类建模如逻辑回归、基于PCA与K-means的异常客户识别、Isolation Forest欺诈检测以及LazyPredict快速模型对比等不同环节适合作为课堂作业或自学项目的参考实现。数据集为真实信用卡申请记录配合readme可快速了解字段含义与使用方式便于复现完整分析流程。目前已有96人学习下载适合希望从零跑通一个完整机器学习项目、并了解信用卡风控常见建模思路的学习者。1. 信用卡数据集分析预测这个 34.81 KB 的 zip 里装的是一场完整实战拿到一个叫“AI实战-信用卡数据集分析预测实例含5个源代码34.81 KB完整的数据集.zip”的包第一反应别被体积唬住。34.81 KB 解压出来大概率是几张 CSV 表格信用卡数据本身就是结构化字段几千条样本配上五个训练脚本足够把分类预测全流程走通。这个包解决的是最实际的问题怎么从一张带标签的信用卡数据表出发完成特征检查、模型训练、指标评估和结果解释而不是停留在调库层面。适合两类人。一类是想在简历上补一个“信用风险/欺诈预测”项目的新手照着脚本跑一遍就知道 train_test_split 到 confusion_matrix 之间发生了什么另一类是已经会跑模型但总被数据坑的熟手比如正负样本比例失衡、csv 编码乱掉、zip 伪加密解不开这类现场问题。下面按“解压摸底 → 跑源码 → 调参数 → 排错 → 验证”的顺序把这个 zip 包真正拆开讲透。2. 解压并摸底数据集34.81 KB 里装着什么哪些字段能进模型2.1 先别双击解压用命令核对文件清单我习惯先不急着解压用命令行看一下压缩包里的真实内容。Windows 上直接用 tar 命令就能列清单macOS/Linux 用 unzip -l不用装额外软件。# Windows 10/11 自带 tar 命令可以列 zip 内容 tar -tf AI实战-信用卡数据集分析预测实例含5个源代码34.81KB完整的数据集.zip # macOS / Linux 直接用 unzip unzip -l AI实战-信用卡数据集分析预测实例含5个源代码34.81KB完整的数据集.zip这一步能确认三件事包里是不是真的有 5 个源代码文件、数据文件是 csv 还是 xls、有没有夹带说明文档。tar -tf只列文件名不解压unzip -l会连带显示每个文件的压缩前后大小如果看到某个 csv 压缩后体积反常地小通常是这份数据做了抽样后面做交叉验证时心里要有数。确认清单没问题后执行解压我建议解压到纯英文路径下比如D:\credit_card_demo。中文路径在 pandas 读文件时偶尔会触发编码识别问题属于能避就避的坑。2.2 用 pandas 读入并做第一轮探查解压后核心文件一般是credit_card.csv或类似名字。我拿到任何表格数据的第一件事永远是读进来、看 shape、看 dtypes、看缺失值这四件事做完基本就知道这份数据能不能直接用。import pandas as pd df pd.read_csv(credit_card.csv, encodingutf-8) print(数据集形状:, df.shape) print(\n字段类型:) print(df.dtypes) print(\n缺失值统计:) print(df.isnull().sum()) print(\n描述性统计:) print(df.describe().T)逻辑说明read_csv的encoding参数是第一个可能翻车的地方很多从老系统导出的 csv 是 GBK 编码utf-8读不了会直接抛UnicodeDecodeError这时把参数改成gbk或gb18030再试。df.isnull().sum()能快速暴露空值列信用卡数据里常见的BILL_AMT、PAY_AMT系列字段偶尔存在空值后面要么删行要么用中位数填。describe().T转置后横向看每个字段的 min、max、mean重点盯有没有异常极值比如年龄列出现 200账单金额出现负数但实际业务上允许透支这类问题只有看分布才能发现。2.3 特征与标签的边界哪些列能进模型以最经典的小型信用卡评分数据为例字段通常包含三组账户信息额度、年龄、性别、教育程度、婚姻状态、历史还款表现过去几个月的还款状态 PAY_0 到 PAY_6、账单与消费金额BILL_AMT、PAY_AMT 各六期最后一列是目标标签常见命名是default.payment.next.month或is_fraud。先做个字段分组比直接全列灌进模型靠谱得多。字段分组典型列名处理方式账户信息LIMIT_BAL, AGE, SEX, EDUCATION, MARRIAGE保持数值Education/Marriage 可考虑转 category还款状态PAY_0 ~ PAY_6取值为 -2 到 8 的整数-2 表示无消费建议先保留原值后续看相关性再决定是否哑编码账单金额BILL_AMT1 ~ BILL_AMT6量纲差异大进模型前统一做标准化付款金额PAY_AMT1 ~ PAY_AMT6同上且含较多的 0 值标签列default.payment.next.month / is_fraud二分类标签1 表示逾期/欺诈0 表示正常一个实战中很容易犯的错是顺手把PAY_0到PAY_6当成普通数值直接塞进模型。还款状态的编码里包含有序信息-2 优于 -1 优于 0但相邻档位的实际距离并不是等距的sklearn 的树模型对这类字段不敏感还好逻辑回归就会引入奇怪的权重。我一贯的做法是先用df.corr()[标签列]看一眼相关性排序绝对值靠前的字段优先保无关的字段先删等模型效果不够再回头补特征不要一上来就搞 20 列全量硬怼。3. 跑通 5 个源代码从逻辑回归到 XGBoost 的完整命令3.1 教学包里最常见的 5 个模型脚本与执行顺序这类“5 个源代码”教学包的常见构成是 5 个独立 python 脚本每个对应一个经典分类模型按复杂度递增排列。常见做法是逻辑回归、KNN、决策树、随机森林、XGBoost或 LightGBM。有些包会把预处理抽成一个公共脚本其余四个模型脚本 import 它有些则每个脚本自己从头读到尾。后者跑起来简单但改前处理时得改五处属于典型的“能跑但难维护”。脚本文件常见命名模型作用train_lr.pyLogisticRegression基线模型跑得最快train_knn.pyKNeighborsClassifier看距离类方法在这个数据上的表现train_dt.pyDecisionTreeClassifier可解释性最强适合画树train_rf.pyRandomForestClassifier树模型集成的稳定基线train_xgb.pyXGBClassifier通常效果最好也是调参重点执行顺序没有硬性要求但我会从逻辑回归开始它训练快、结果稳定可以作为后续所有模型的“及格线”。如果随机森林连逻辑回归都打不过大概率是预处理或者数据泄漏的问题而不是模型不够强。3.2 跑通第一个脚本逻辑回归基线逻辑回归脚本是所有源码里最值得读的一个因为它会把数据切分、标准化、训练、评估一条龙走完后续模型脚本基本就是换模型名。import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report df pd.read_csv(credit_card.csv) # 假设标签列名为 default.payment.next.month按实际文件调整 X df.drop(columns[default.payment.next.month]) y df[default.payment.next.month] # 切分数据stratify 保证训练集和测试集的正负比例一致 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42, stratifyy ) # 标准化逻辑回归对特征量纲敏感这一步不能省 scaler StandardScaler() X_train scaler.fit_transform(X_train) X_test scaler.transform(X_test) # max_iter 默认 100特征多时经常不收敛调到 1000 并加大正则化 model LogisticRegression(max_iter1000, C0.1, solverliblinear) model.fit(X_train, y_train) print(classification_report(y_test, model.predict(X_test)))这段代码的关键点有三个。第一stratifyy是切分时必须写的参数信用卡数据通常只有一到两成是正样本不按比例分层切分测试集里正样本可能只剩几十条评估结果会剧烈波动。第二StandardScaler只能fit训练集测试集用同一个transform绝对不能在全部数据上 fit 后再切分那是典型的数据泄漏会让评估结果虚高。第三solverliblinear适合小数据集lbfgs在多特征下也稳定但liblinear对 L1/L2 正则支持更灵活新手不容易踩收敛警告。3.3 随机森林脚本看特征重要性比看准确率更有用随机森林脚本跑通后输出里最有价值的是feature_importances_它能直接回答“这份数据里哪些字段在决定结果”。别只盯着准确率那在类别不平衡的信用卡数据上经常是虚高的。from sklearn.ensemble import RandomForestClassifier rf RandomForestClassifier( n_estimators200, max_depth8, min_samples_leaf5, class_weightbalanced, random_state42, n_jobs-1 ) rf.fit(X_train, y_train) importances pd.Series(rf.feature_importances_, indexX.columns) print(特征重要性 Top 10:) print(importances.sort_values(ascendingFalse).head(10))max_depth8是给随机森林做限制的关键参数。信用卡数据字段不多但噪音不少不限制深度时树长到 20 多层训练集精确率接近 100%测试集表现一塌糊涂。min_samples_leaf5保证叶节点至少有 5 条样本进一步抑制过拟合。class_weightbalanced会自动按类别频率给少数类加权和逻辑回归里scale_pos_weight是同一思路对不平衡标签非常有效。特征重要性排序出来后对比一下之前df.corr()的结果两者是否一致能帮你判断模型有没有学到奇怪的关联。3.4 XGBoost 脚本与调参入口最后一个脚本通常是 XGBoost教学包里的写法往往比较朴素只设了n_estimators和learning_rate能跑出结果但离“调优”还有距离。我给一个能直接替换的版本。from xgboost import XGBClassifier xgb XGBClassifier( n_estimators300, learning_rate0.05, max_depth4, subsample0.8, colsample_bytree0.8, scale_pos_weight5, eval_metricauc, early_stopping_rounds50, random_state42 ) xgb.fit( X_train, y_train, eval_set[(X_test, y_test)], verboseFalse )scale_pos_weight是这个脚本里唯一需要你根据数据自己算的参数通用的经验公式是负样本数除以正样本数。如果训练集里标签 0 有 8000 条、标签 1 有 1600 条scale_pos_weight5基本是安全的起点。eval_metricauc比默认的logloss更适合信用卡场景因为 AUC 不依赖具体的分类阈值能反映模型把好坏样本分开的能力。early_stopping_rounds50配合eval_set会在测试集 AUC 连续 50 轮不再提升时提前停掉训练既防过拟合又省时间。如果包里给的脚本没有这几行自己补上即可XGBoost 的接口就是这么用的。值得多说一句很多教学脚本跑 XGBoost 前没有安装 xgboost 包直接import xgboost抛 ModuleNotFoundError。用 pip 装到当前环境即可后面排错章节会细说环境问题。4. 预测结果的两个关键参数scale_pos_weight 与 class_weight 怎么取值4.1 信用卡数据天然不平衡准确率是第一层伪装信用卡违约或欺诈数据里正样本比例通常在 2% 到 20% 之间意味着一个什么都不学的模型只要把全部样本预测为“正常”准确率也能到 80% 甚至 98%。这个数字会掩盖模型完全没用的真相。所以看脚本输出时不要只看 accuracy先看classification_report里的 precision、recall、f1-score再画混淆矩阵。from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay import matplotlib.pyplot as plt cm confusion_matrix(y_test, xgb.predict(X_test)) disp ConfusionMatrixDisplay(confusion_matrixcm) disp.plot() plt.show()混淆矩阵里四个格子各有含义真正例右下角是模型正确识别出的逾期客户假负例左下角是漏掉的逾期客户对信用卡风控来说漏掉一个坏客户的实际损失远大于把好客户误判为坏客户。教学包里的脚本一般只打印 accuracy你要做的就是把上面这段接到任一模型脚本后面才能真正看懂模型。4.2 scale_pos_weight 与 class_weight 的取值公式XGBoost 的scale_pos_weight和随机森林的class_weightbalanced是处理不平衡的两种风格前者是手动给一个权重倍率后者是自动按频率倒数加权。手算权重的方法很简单。# 计算正负样本比例用于 scale_pos_weight neg_count (y_train 0).sum() pos_count (y_train 1).sum() print(f负样本数: {neg_count}, 正样本数: {pos_count}) print(f推荐 scale_pos_weight: {neg_count / pos_count:.2f})假设输出负样本数: 5600, 正样本数: 1400那么推荐权重是 4.0。这个值不是一定要死板地用可以试试 3 到 6 之间的几个档位。调大权重会让模型更努力地抓住正样本召回率上升但精确率会下降找的是二者的平衡点。随机森林的class_weightbalanced则是 sklearn 自动算你只需要在参数里写下这个字符串内部就会按n_samples / (n_classes * np.bincount(y))分配权重不用手算。4.3 调参之后怎么看效果Precision-Recall 曲线信用卡数据上我一般不看 ROC 曲线而是看 Precision-Recall 曲线。原因是 ROC 曲线在正样本极少时容易给人“模型很强”的错觉PR 曲线直接度量“预测为正的样本里有多少是真的正”更贴近风控场景。教学包里基本不会有这段代码但值得自己补上。from sklearn.metrics import precision_recall_curve # 取预测概率而非类别 y_scores xgb.predict_proba(X_test)[:, 1] precision, recall, thresholds precision_recall_curve(y_test, y_scores) # 找 F1 最高的阈值 f1_scores 2 * precision * recall / (precision recall 1e-9) best_idx f1_scores.argmax() best_threshold thresholds[best_idx] print(f最优阈值: {best_threshold:.3f}, 对应 F1: {f1_scores[best_idx]:.3f}) # 用最优阈值重新预测 y_pred_adj (y_scores best_threshold).astype(int)这段代码的价值在于模型默认用 0.5 作为阈值但正样本只有两成时0.5 往往不是最优分割点。按 F1 最大化的思路选出阈值后预测结果通常会变化明显。教学包不会教你这一步但这才是“分析预测实例”真正产生业务价值的环节——把概率输出转成可执行的判断规则。5. 常见问题排查解压、编码、路径与模型报错的五个踩坑现场5.1 解压后“找不到源代码”扩展名被系统隐藏现象zip 解压后只看到一堆 python 文件图标文件名正常但双击打开的是记事本或者根本没看到 .py 后缀。原因Windows 资源管理器默认隐藏已知文件类型的扩展名python 文件在图标视图下看不出差别。这不是文件缺失是显示问题。解决在资源管理器里点击“查看”菜单勾选“文件扩展名”就能看到train_lr.py、train_xgb.py这些后缀。命令行里用dir或ls -la验证最直接文件在不在、多大、后缀是什么一眼看全。5.2 CSV 读进来全是乱码或抛 UnicodeDecodeError现象pd.read_csv(credit_card.csv)直接报错或者读进来了但中文列名全是“锟斤拷”式乱码。原因这份 csv 是 GBK/GB18030 编码保存的pandas 默认按 UTF-8 解码两者不匹配就报错或乱码。解决换编码参数重读。df pd.read_csv(credit_card.csv, encodinggbk) # 如果还有个别字符报错用 gb18030它是 GBK 的超集 df pd.read_csv(credit_card.csv, encodinggb18030)判断用哪种编码还有个技巧用chardet检测。import chardet with open(credit_card.csv, rb) as f: result chardet.detect(f.read(10000)) print(result[encoding]) # 大概率输出 GB2312 / GBK / UTF-85.3 明明安装了 sklearn一跑脚本就 ModuleNotFoundError现象python 脚本第一行import pandas as pd或import sklearn报 ModuleNotFoundError但你在另一个终端里 pip install 过这些库。原因环境错位。终端里执行的是系统 Python而 pip install 装进了 conda 的 base 环境或者 VSCode 里选了解释器 A终端里用的是 B。这在教学包里最常见因为包里的 README 不会替你做环境隔离。解决统一到同一环境。先确定当前 python 路径再原地装依赖。# 查看当前 python 和 pip 指向 python -c import sys; print(sys.executable) python -m pip list | findstr pandas python -m pip list | findstr scikit-learn # 缺什么装什么 python -m pip install pandas scikit-learn xgboost关键是用python -m pip而不是裸pip前者保证装进当前解释器的环境。建议读完整个 zip 包的脚本把所有 import 列出来一次性装齐别跑一个报一个。5.4 zip 显示有密码但双击却能打开伪加密坑现象解压时提示输入密码但包里资料明明没说有密码或者 7-Zip 能打开、系统自带解压却要求密码。原因这是 zip 伪加密。压缩包只修改了加密标志位数据本身没加密部分解压器见到标志位就要求密码但数据实际可以被直接读取。很多从网上下载的教学包用这个办法防搜索引擎直接索引内容属常见手段而非真加密。解决用 Python 的 zipfile 绕过标志位直接解压不需要密码。import zipfile zp zipfile.ZipFile(信用卡数据集分析预测.zip) # 伪加密包直接用 extractall 通常可行个别包要手动修正标志位 zp.extractall(credit_card_demo)如果extractall仍提示密码错误属于偶尔遇到的非标准实现改用 7-Zip 打开菜单里选择“提取”很多时候能直接解出来。这是处理这类资料的通用做法不是破解加密内容是真没加密。5.5 模型脚本报 KeyError: “名称为空的列”现象跑df.drop(columns[default.payment.next.month])时 KeyError查看列名发现有的列是Unnamed: 0或空字符串。原因csv 导出自带索引列或者表头第一行有多余逗号pandas 读入时把它当成列名。解决读入时指定索引列或直接删掉多余列。df pd.read_csv(credit_card.csv, index_col0) # 如果第一列是行号 # 或者读入后删掉未知列 df df.loc[:, ~df.columns.str.contains(Unnamed)]我的习惯是读入后先print(df.columns.tolist())把列名列表和业务字段对照一遍再往下写能省掉大半这种低级但耗时的报错。6. 一个验证技巧用 5 折交叉验证判断 34.81 KB 的数据量够不够6.1 小数据集上单次切分就是赌博34.81 KB 的数据集解压后大概几千到一万条样本这个量级下单次train_test_split的结果受随机种子影响很大。同一个模型random_state42时 AUC 是 0.78改成random_state2024可能掉到 0.72不一定是模型问题是测试集随机抽到了难点样本。我拿到小数据集的第一反应是不要再反复换 random_state 去凑好看的数字那是典型的自欺欺人。正确做法是看交叉验证的均值与方差。6.2 最小的 5 折交叉验证脚本用cross_val_score配合StratifiedKFold一行能拿到五次评估的结果分布。from sklearn.model_selection import StratifiedKFold, cross_val_score cv StratifiedKFold(n_splits5, shuffleTrue, random_state42) scores cross_val_score(rf, X, y, cvcv, scoringroc_auc) print(各折 AUC:, [f{s:.4f} for s in scores]) print(fAUC 均值: {scores.mean():.4f} ± {scores.std():.4f})scoringroc_auc是不平衡分类下最稳妥的选择不依赖阈值能反映排序能力。判断标准我一般看两点均值要高于 0.75 才算对这个数据集有效果标准差大于 0.05 说明数据量偏少或者特征不稳定这时候先不急着上复杂模型回头看特征工程和缺失值处理更实际。6.3 数据确实不够时的两个补救SMOTE 与概率阈值如果交叉验证结果不佳有两个实际手段。第一个是过采样少数类imblearn库里的 SMOTE 在小型数据集上表现稳定在交叉验证内部做才会避免数据泄漏。第二个是前文提过的概率阈值调整直接把predict_proba的输出配一个低于 0.5 的判定线往往比加更多模型参数更直接。from imblearn.over_sampling import SMOTE smote SMOTE(random_state42) X_resampled, y_resampled smote.fit_resample(X_train, y_train)我这个习惯是这几年踩坑踩出来的拿到任何教学包先跑交叉验证再谈调参而且永远保留第一次跑出的结果。那张初始打印的均值与标准差比后面任何花哨的模型都更能说明这份数据的真实质量。如果你手里的 zip 包跑完发现 AUC 只有 0.6 上下也别急着怀疑代码先回到第 2 章把字段分组和缺失值重新做一遍大概率是特征侧的问题。希望这份拆解帮到你按这个顺序把这 34.81 KB 的价值真正榨出来。本文还有配套的精品资源点击获取
返回列表