3. 数据探索与可视化:加载行情数据、描述性统计、坏账率分布直方图、相关性热力图
在构建XGBoost坏账率哨兵模型之前,必须对原始行情数据进行系统性的探索与可视化分析。本章将引导你完成从数据加载、基础统计到分布特征与变量关系的全流程诊断,为后续特征工程与模型训练奠定可靠的数据基础。
3.1 加载行情数据
行情数据通常以CSV格式存储,包含时间戳、资产价格、交易量以及衍生指标。使用Pandas库加载数据时,需注意数据类型转换与缺失值标记。
import pandas as pd
import numpy as np
# 加载行情数据
df = pd.read_csv('market_data.csv', parse_dates=['timestamp'])
# 查看数据形状与前5行
print(f'数据集形状: {df.shape}')
print(df.head())
| 字段名 | 类型 | 说明 |
|---|---|---|
| timestamp | datetime | 交易时间戳 |
| close_price | float | 收盘价 |
| volume | int | 成交量 |
| volatility | float | 波动率(20日滚动) |
| default_flag | int | 坏账标签(0/1) |
实践要点:加载后立即检查
df.info() 确认每列非空值与数据类型,避免后续计算因类型错误而中断。
3.2 描述性统计
描述性统计能够快速揭示数据的集中趋势、离散程度与分布形态,是发现异常值与数据倾斜的第一步。
# 生成描述性统计表
desc = df.describe().T
desc['skew'] = df.skew(numeric_only=True)
desc['kurtosis'] = df.kurtosis(numeric_only=True)
print(desc[['mean','std','min','25%','50%','75%','max','skew','kurtosis']])
| 指标 | 均值 | 标准差 | 最小值 | 25%分位 | 中位数 | 75%分位 | 最大值 | 偏度 | 峰度 |
|---|---|---|---|---|---|---|---|---|---|
| close_price | 152.34 | 45.21 | 78.10 | 118.50 | 148.70 | 182.90 | 267.40 | 0.32 | -0.67 |
| volume | 2.15e6 | 1.87e6 | 1.20e4 | 6.80e5 | 1.62e6 | 3.01e6 | 9.85e6 | 1.74 | 3.82 |
| volatility | 0.023 | 0.015 | 0.004 | 0.012 | 0.019 | 0.031 | 0.089 | 1.21 | 1.95 |
| default_flag | 0.087 | 0.282 | 0.000 | 0.000 | 0.000 | 0.000 | 1.000 | 2.93 | 6.58 |
关键发现:坏账标签
default_flag 均值仅 0.087,偏度 2.93,峰度 6.58,呈现典型的类别不平衡特征。成交量与波动率均呈右偏分布,存在极端值,后续需考虑对数变换或分箱处理。
3.3 坏账率分布直方图
坏账率分布直方图直观展示正负样本的频数差异,帮助判断是否需要采用采样策略或调整损失函数权重。
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(8,5))
sns.histplot(data=df, x='default_flag', bins=2, discrete=True, shrink=0.6)
plt.xticks([0,1], ['正常 (0)', '坏账 (1)'])
plt.ylabel('样本数量')
plt.title('坏账率分布直方图')
plt.show()
注意:若坏账样本占比低于10%,直接使用原始数据训练XGBoost可能导致模型偏向多数类。建议在后续章节中采用
scale_pos_weight 参数或SMOTE过采样策略。
3.4 相关性热力图
相关性热力图用于量化各特征与坏账标签之间的线性关联强度,同时检测特征间的多重共线性问题。
# 计算相关系数矩阵
corr_matrix = df.corr(numeric_only=True)
# 绘制热力图
plt.figure(figsize=(10,8))
sns.heatmap(corr_matrix, annot=True, fmt='.2f', cmap='RdBu_r',
center=0, square=True, linewidths=0.5)
plt.title('行情特征与坏账标签相关性热力图')
plt.tight_layout()
plt.show()
3.5 数据探索总结与行动清单
基于上述探索性分析,整理出以下关键结论与后续行动项:
- 类别不平衡严重:坏账样本仅占8.7%,需在XGBoost中设置
scale_pos_weight = (正常样本数 / 坏账样本数)或采用过采样方法。 - 波动率是关键信号:volatility与坏账标签相关系数0.42,应作为重要特征保留,并考虑构造衍生特征如波动率突变率。
- 成交量存在长尾分布:偏度1.74,峰度3.82,建议进行对数变换
np.log1p(volume)以降低极端值影响。 - 多重共线性风险低:特征间最高相关系数为0.35(volume vs volatility),未超过0.7阈值,暂不需要做特征删除。
- 缺失值检查:描述性统计中未发现明显缺失,但仍需用
df.isnull().sum()逐列确认。
下一步行动:完成数据探索后,进入第4章“特征工程与数据预处理”,对波动率、成交量等关键特征进行变换与标准化,并构造时间窗口聚合特征,为XGBoost模型提供高质量输入。