拍拍贷风控数据集7z解压与特征工程实战指南
简介:这份资源是拍拍贷风控大赛的实战数据集,面向金融风控方向的学习者、数据挖掘竞赛选手及信用评分建模从业者,用于练习用户违约预测与信用评估全流程。压缩包共176个文件,约37.37MB,以csv数据表为主,涵盖训练集主表、日志信息表等核心数据,另含jpg、png图片、html、js、css前端页面文件及ipynb笔记本、xlsx表格与md说明,便于直接开展特征工程与建模实验。目前已有1123人学习下载,热度较高。读者可借助其中的借款记录、还款状态、信贷评分等字段,完成数据清洗、特征提取、逻辑回归与随机森林等模型训练,并通过AUC-ROC等指标评估效果,同时结合时间序列与异常检测思路识别潜在欺诈行为,是理解风控策略与模型解释性的实用素材。
1. 拍拍贷风控大赛数据集到底装了什么:从 7z 压缩包到能跑的特征表
拿到「ppd拍拍贷风控大赛数据集.7z」这个文件的人,十有八九第一反应不是建模,而是先卡在解压这一步——Linux 上敲unzip报错,Windows 上双击半天没反应,或者解出来一堆乱码文件名。这个数据集本身是拍拍贷风控大赛公开的借贷行为数据,核心价值在于它把「用户申请借款时的多维特征」和「最终是否逾期」串成了一张能直接喂给模型的宽表。它解决的是信贷场景里最典型的问题:在放款前,用申请人提交的信息和历史行为,预测这个人未来会不会违约。适合谁?做信用评分卡、做 Kaggle 类结构化竞赛、或者想练手特征工程和类别不平衡处理的同学。但前提是,你得先把它从 7z 里完整、正确地掏出来,再搞清楚每一列到底在说什么,否则后面所有模型都是空中楼阁。这一章先把「这是什么、里面有什么、为什么值得花时间」讲透,后面再一步步落到解压、清洗、建模和避坑。
2. 先把 7z 拆开:Linux 与 Windows 下的解压命令和目录结构核对
2.1 为什么unzip解不开,7z 到底该怎么装
7z 不是 zip,它是 LZMA 压缩算法封装的一种归档格式,压缩率比普通 zip 高不少,但代价是很多系统默认不带解压工具。Linux 上最稳的做法是装p7zip-full,它提供7z和7za两个命令。Ubuntu/Debian 系直接:
sudo apt-get update sudo apt-get install -y p7zip-fullCentOS/RHEL 系用:
sudo yum install -y p7zip p7zip-plugins装完之后先别急着解,先看一眼压缩包里有什么:
7z l ppd拍拍贷风控大赛数据集.7zl是 list 的意思,它会列出所有条目、大小和压缩后大小。这一步很关键,因为有些 7z 包是分卷的,或者里面套了多层目录,直接解会散一地。确认结构后再解:
7z x ppd拍拍贷风控大赛数据集.7z -o./ppd_datax表示保留完整路径解压,-o指定输出目录,后面紧跟目录名,中间不要有空格。Windows 上如果不想装命令行工具,用 7-Zip 官方客户端右键「提取到当前文件夹」也行,但要注意:Windows 资源管理器对中文文件名和长路径的支持一直不太行,解压前最好把压缩包放到盘符根目录下的短路径里,比如D:\ppd\,避免解到一半报「路径过长」。
提示:如果
7z l看到文件名是乱码,说明压缩时用的编码和当前终端不一致。Linux 下可以试7z x -mcp=936指定 GBK 编码,或者用convmv转文件名编码后再解。
2.2 解压后先别建模,用三行命令核对文件完整性
解压完第一件事不是打开 Jupyter,而是核对文件数量和大小。常见做法是:
find ./ppd_data -type f | wc -l du -sh ./ppd_datafind统计文件个数,du -sh看总大小。如果压缩包在传输过程中断过,解压出来的文件可能不完整,7z 在解压时一般会报 CRC 错误,但有时候只是静默截断。更稳妥的方式是解压时加-t先测试:
7z t ppd拍拍贷风控大赛数据集.7zt是 test,它会逐个校验 CRC,不实际写盘。测试通过再解,能省掉很多「为什么读 CSV 读到一半报错」的破事。解压后的目录通常包含训练集、测试集和一份字段说明,字段说明可能是 txt 或 csv,先把它读出来,后面所有特征工程都靠它对齐列名。
2.3 目录里通常有什么:训练集、测试集与字段说明
拍拍贷这类风控竞赛数据集,结构一般比较固定:一个train.csv或类似命名的训练文件,包含特征列和标签列(通常叫target或status);一个test.csv,只有特征没有标签;外加一份columns.txt或field_desc.csv解释每个字段含义。字段大致分几类:用户基本信息(年龄、性别、学历)、借款信息(金额、期限、利率)、历史行为(过往借款次数、逾期次数)、以及第三方衍生特征(征信查询次数、社交关系等)。标签通常是二分类:0 表示正常还款,1 表示逾期或违约。
拿到字段说明后,建议先做一件事:把列名和说明对一遍,标出哪些是数值型、哪些是类别型、哪些是时间型。这一步不做,后面pd.read_csv读进来全是 object,模型直接罢工。可以用下面这段代码快速摸清底细:
import pandas as pd df = pd.read_csv('./ppd_data/train.csv') print(df.shape) print(df.dtypes.value_counts()) print(df.isnull().sum().sort_values(ascending=False).head(20))shape看行列数,dtypes看类型分布,isnull看缺失情况。风控数据缺失是常态,有些列缺失率能到 80% 以上,这些列要么直接丢,要么用特殊值填充后加一个「是否缺失」的指示列。别小看这个指示列,在信贷场景里,「没填」本身可能就是信号。
3. 把原始表变成模型能吃的特征:缺失值、类别编码与不平衡处理
3.1 缺失值不是敌人,先分清「真缺失」和「假缺失」
风控数据里的缺失分两种:一种是用户没填,比如学历、婚姻状况;另一种是系统没采集到,比如某些第三方数据源没返回。前者可以用众数或「未知」类别填充,后者更适合用中位数加缺失指示列。我一般会先跑一个缺失率分布:
missing = df.isnull().mean().sort_values(ascending=False) print(missing[missing > 0])然后按阈值处理:缺失率超过 70% 的列,除非字段说明里明确说它很重要,否则先丢;30% 到 70% 之间的,填充后加指示列;低于 30% 的,数值列用中位数、类别列用众数填。注意,填充一定要在划分训练集和验证集之后做,否则验证集的信息会泄漏到训练集里,线下 AUC 虚高,线上直接翻车。
3.2 类别特征怎么编码:独热、标签还是目标编码
风控数据里类别特征特别多,比如职业、地区、贷款用途。独热编码适合类别数少的列,比如性别、是否已婚;类别数一多,独热之后维度爆炸,树模型还好,线性模型直接崩。标签编码(Label Encoding)简单,但会引入不存在的顺序关系,树模型勉强能用,线性模型慎用。目标编码(Target Encoding)在风控里很常见,用目标变量的均值来替换类别,但必须做交叉验证下的平滑,否则过拟合到没边。
我一般用category_encoders库里的TargetEncoder,配合KFold做平滑:
from category_encoders import TargetEncoder from sklearn.model_selection import KFold encoder = TargetEncoder(cols=['job', 'region'], smoothing=10) df[['job_enc', 'region_enc']] = encoder.fit_transform(df[['job', 'region']], df['target'])smoothing参数控制平滑强度,值越大,类别均值越向全局均值靠拢,适合类别样本少的情况。编码完记得把原始类别列删掉,避免重复信息干扰模型。
3.3 正负样本不平衡:过采样、欠采样还是调权重
风控数据里逾期样本通常只占几个百分点,直接训练模型会偏向多数类,预测出来全是 0,AUC 看着还行,但召回率惨不忍睹。常见做法有三种:过采样(SMOTE)、欠采样、以及直接在模型里设class_weight='balanced'。我一般优先试class_weight,因为它不改变数据分布,只是让模型更关注少数类,实现也简单:
from sklearn.ensemble import RandomForestClassifier clf = RandomForestClassifier(n_estimators=300, class_weight='balanced', random_state=42) clf.fit(X_train, y_train)如果效果不够,再上 SMOTE,但要注意 SMOTE 只能在训练集上做,验证集和测试集绝对不能碰。另外,SMOTE 对高维稀疏数据效果一般,风控数据做完独热之后维度不低,用之前先降维或者只对数值列做。
3.4 用 LightGBM 跑一版基线:参数怎么设、结果怎么看
基线模型我习惯用 LightGBM,速度快、对缺失值和类别特征友好。最小可跑配置:
import lightgbm as lgb from sklearn.model_selection import train_test_split from sklearn.metrics import roc_auc_score X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42) model = lgb.LGBMClassifier( n_estimators=500, learning_rate=0.05, num_leaves=31, max_depth=-1, subsample=0.8, colsample_bytree=0.8, class_weight='balanced', random_state=42 ) model.fit(X_train, y_train, eval_set=[(X_val, y_val)], eval_metric='auc', callbacks=[lgb.early_stopping(50)]) pred = model.predict_proba(X_val)[:, 1] print('AUC:', roc_auc_score(y_val, pred))early_stopping(50)表示验证集 AUC 50 轮不提升就停,防止过拟合。num_leaves控制树复杂度,风控数据噪声大,别设太高,31 到 63 之间比较稳。跑完看 AUC,如果低于 0.7,先回头查特征工程,别急着调参。特征没做好,调参调到天荒地老也上不去。
4. 避坑与排查:解压、读数和建模阶段最容易翻车的五件事
4.1 解压报「Cannot open file as archive」
现象:7z x执行后直接报错,说文件不是归档。原因通常是下载不完整,或者文件头被改过。解决:先用file命令看文件类型,file ppd拍拍贷风控大赛数据集.7z,如果显示data而不是7-zip archive,说明文件坏了,重新下载。下载时用wget -c支持断点续传,别用浏览器下大文件。
4.2 读 CSV 时报编码错误
现象:pd.read_csv抛UnicodeDecodeError。原因:文件可能是 GBK 或 GB18030 编码,而 pandas 默认 UTF-8。解决:加encoding='gbk'或encoding='gb18030',如果还不行,用chardet检测:
import chardet with open('./ppd_data/train.csv', 'rb') as f: print(chardet.detect(f.read(100000)))拿到编码后再读。别用errors='ignore'硬吞,那样会丢字符,后面特征对不上。
4.3 训练集和测试集列数不一致
现象:训练时特征列有 200 个,预测时只有 198 个。原因:测试集里有些列在训练集里被删了,或者独热编码后列数对不上。解决:用sklearn的Pipeline把编码和模型串起来,保证训练和预测走同一套变换。或者手动对齐列:
test = test.reindex(columns=train.columns.drop('target'), fill_value=0)reindex会按训练集列顺序重排,缺失的列填 0。这一步不做,线上必炸。
4.4 线下 AUC 很高,线上惨不忍睹
现象:交叉验证 AUC 0.85,提交上去只有 0.6。原因:大概率是数据泄漏,比如在划分训练验证之前就做了填充或编码,或者用了未来信息。解决:把所有预处理步骤塞进Pipeline,用cross_val_score重新评估。另外检查有没有把target相关的列误当成特征,比如「历史逾期次数」如果是在放款后统计的,就不能用。
4.5 7z 解压后文件名乱码,导致路径读不到
现象:解压出来文件名是train.csv但实际是乱码,Python 读的时候报FileNotFoundError。原因:压缩时用了非 UTF-8 编码。解决:Linux 下用convmv -f gbk -t utf8 -r ./ppd_data批量转文件名编码,或者解压时加-mcp=936指定代码页。Windows 下用 7-Zip 的「名称编码」选项选 GBK 再解。
5. 从基线到提分:特征交叉、时间验证与一个可复现的提分技巧
5.1 风控里最值钱的特征往往来自交叉
单列特征跑完基线之后,下一步是交叉。风控场景里,「借款金额 / 月收入」比单独的金额和收入都有用,「历史逾期次数 / 历史借款次数」比两个原始计数更能反映习惯。我一般会先做几个业务上说得通的比值特征,再看模型重要性。代码很简单:
df['loan_income_ratio'] = df['loan_amount'] / (df['monthly_income'] + 1) df['overdue_ratio'] = df['history_overdue'] / (df['history_loan_count'] + 1) df['credit_age_ratio'] = df['credit_history_months'] / (df['age'] * 12 + 1)分母加 1 是防止除零。这三个特征在多数风控比赛里都能进重要性前二十。注意,交叉特征不要盲目堆,每加一个都要问:业务上说得通吗?如果说不通,模型学到了也是噪声。
5.2 用时间做验证比随机划分更靠谱
风控数据有时间属性,随机划分会让未来样本泄漏到训练集。更稳的做法是按时间切:用前 80% 的时间做训练,后 20% 做验证。如果数据里有loan_date或类似字段,先转成 datetime 再排序:
df['loan_date'] = pd.to_datetime(df['loan_date']) df = df.sort_values('loan_date') split_idx = int(len(df) * 0.8) train, val = df.iloc[:split_idx], df.iloc[split_idx:]这样验证集模拟的是「用历史预测未来」,更接近线上真实场景。如果时间验证 AUC 比随机验证低不少,别慌,那才是真实水平。
5.3 一个可复现的提分习惯:先固定随机种子,再谈调参
最后说一个我踩过无数次坑才养成的习惯:任何实验开始前,先把所有随机种子固定死。numpy、random、lightgbm、sklearn的random_state全部设成同一个值。不然你调了半天参,以为提升了 0.01,结果只是这次随机划分运气好。固定种子之后,每次改动只动一个变量,记录 AUC 变化。这个习惯看起来笨,但能让你清楚知道到底是哪个改动起了作用。风控建模没有银弹,只有一次次可复现的小步迭代。希望帮到你。
本文还有配套的精品资源,点击获取