2. 变量类型与分布分析:连续变量、离散变量、分类变量、时间变量的识别与分布可视化方法
在特征工程中,变量类型的准确识别是分箱与特征变换的前提。不同类型的变量对应不同的分布可视化方法与分箱策略。本章系统梳理四种核心变量类型,并给出对应的识别规则与可视化工具链。
2.1 变量类型分类体系
根据测量尺度与取值特性,变量可分为以下四类:
| 变量类型 | 取值特征 | 典型示例 | 数学表示 |
|---|---|---|---|
| 连续变量 | 无限取值,可带小数 | 年龄、收入、温度 | ℝ |
| 离散变量 | 有限整数取值,有顺序 | 购买次数、子女数量 | ℕ |
| 分类变量 | 有限类别,无顺序 | 性别、城市、产品类型 | 枚举 |
| 时间变量 | 时间戳或日期序列 | 注册日期、交易时间 | datetime |
识别口诀:连续看小数,离散数整数,分类无大小,时间有先后。
2.2 变量类型识别流程
实际数据集中,变量类型常被错误标注。建议按以下三步进行识别:
- 检查数据类型(dtype):
float64多为连续变量;int64需进一步判断;object多为分类或时间。 - 计算唯一值数量:唯一值 < 20 且为整数 → 离散变量;唯一值 > 50 且为浮点 → 连续变量。
- 语义验证:检查字段名与业务含义,确认是否应视为有序或无序。
import pandas as pd
def infer_variable_type(series):
dtype = series.dtype
n_unique = series.nunique()
n_total = len(series)
if pd.api.types.is_datetime64_any_dtype(series):
return 'time'
elif pd.api.types.is_float_dtype(dtype):
return 'continuous'
elif pd.api.types.is_integer_dtype(dtype):
return 'discrete' if n_unique < 20 else 'continuous'
else:
return 'categorical'
2.3 分布可视化方法
每种变量类型都有其最适配的可视化工具。下表总结了推荐图表类型与适用场景:
| 变量类型 | 推荐图表 | 关键参数 | 分析目标 |
|---|---|---|---|
| 连续变量 | 直方图 + KDE 曲线 | bins=30, kde=True | 偏度、峰度、异常值 |
| 离散变量 | 柱状图 + 频数表 | 统计每个整数值 | 分布集中趋势、零膨胀 |
| 分类变量 | 条形图 + 饼图 | 按频数降序排列 | 类别平衡性、稀有类别 |
| 时间变量 | 折线图 + 热力图 | 按日/周/月聚合 | 趋势、周期性、季节性 |
实践要点:连续变量直方图需注意 bin 宽度选择,过宽掩盖分布细节,过窄引入噪声。推荐使用 Freedman-Diaconis 规则自动计算 bin 数。
2.4 变量类型与分布关系图
下图展示了四种变量类型在数据空间中的分布形态与可视化映射关系:
2.5 分布分析实战代码
以下代码演示了四种变量类型的分布可视化实现:
import matplotlib.pyplot as plt
import seaborn as sns
def plot_distribution(df, column, var_type):
fig, ax = plt.subplots(1, 2, figsize=(12, 4))
if var_type == 'continuous':
sns.histplot(df[column], bins=30, kde=True, ax=ax[0])
ax[0].set_title(f'{column} 分布(直方图+KDE)')
sns.boxplot(x=df[column], ax=ax[1])
ax[1].set_title(f'{column} 箱线图')
elif var_type == 'discrete':
value_counts = df[column].value_counts().sort_index()
ax[0].bar(value_counts.index, value_counts.values)
ax[0].set_title(f'{column} 频数分布')
ax[1].axis('off')
ax[1].table(cellText=[[k, v] for k, v in value_counts.items()],
colLabels=['取值', '频数'], loc='center')
elif var_type == 'categorical':
value_counts = df[column].value_counts()
ax[0].barh(range(len(value_counts)), value_counts.values)
ax[0].set_yticks(range(len(value_counts)))
ax[0].set_yticklabels(value_counts.index)
ax[0].set_title(f'{column} 类别分布')
value_counts.plot.pie(autopct='%1.1f%%', ax=ax[1])
ax[1].set_ylabel('')
elif var_type == 'time':
df[column] = pd.to_datetime(df[column])
daily_counts = df.set_index(column).resample('D').size()
ax[0].plot(daily_counts.index, daily_counts.values)
ax[0].set_title(f'{column} 时间序列')
weekly_counts = df.set_index(column).resample('W').size()
ax[1].plot(weekly_counts.index, weekly_counts.values, color='orange')
ax[1].set_title(f'{column} 周聚合趋势')
plt.tight_layout()
return fig
2.6 变量类型对分箱策略的影响
不同变量类型在分箱时的处理逻辑差异显著,下表总结了各类型的分箱适配性:
| 变量类型 | 推荐分箱方法 | 注意事项 | 分箱后类型 |
|---|---|---|---|
| 连续变量 | 等距分箱、等频分箱、最优分箱 | 需处理异常值对边界的影响 | 有序分类 |
| 离散变量 | 按整数值直接分组 | 零值过多时考虑零膨胀处理 | 有序分类 |
| 分类变量 | 频数合并、业务合并 | 稀有类别需合并到“其他” | 无序分类 |
| 时间变量 | 按周期聚合(年/季/月/周) | 注意时区与节假日影响 | 有序分类 |
常见陷阱:将分类变量误判为连续变量进行等距分箱,会导致类别间距离无意义。例如“城市”编码为 1-100 后做等距分箱,会强行合并地理无关的城市。
2.7 分布形态快速诊断表
通过可视化结果快速判断分布形态,指导后续分箱策略选择:
| 分布形态 | 可视化特征 | 推荐分箱策略 | 典型变量 |
|---|---|---|---|
| 正态分布 | 钟形对称 | 等距分箱 | 身高、测量误差 |
| 右偏分布 | 长尾在右侧 | 等频分箱或对数变换后分箱 | 收入、房价 |
| 左偏分布 | 长尾在左侧 | 等频分箱 | 年龄(人口结构) |
| 双峰分布 | 两个峰值 | 聚类分箱 | 用户活跃度 |
| 均匀分布 | 各区间频数相近 | 等距分箱 | 随机数 |
| 幂律分布 | 大量小值、少量大值 | 对数分箱 | 网页访问量 |
2.8 变量类型转换与分布适配图
下图展示了变量类型识别后的转换路径与分布适配关系:
2.9 本章小结
- 变量类型识别是特征工程的第一步,错误识别会导致后续分箱策略失效。
- 连续变量使用直方图+KDE 分析分布形态,关注偏度与异常值。
- 离散变量使用柱状图+频数表,注意零膨胀与稀疏取值。
- 分类变量使用条形图+饼图,重点评估类别平衡性。
- 时间变量使用折线图+热力图,挖掘趋势与周期性。
- 分布形态直接决定分箱策略:正态→等距,偏态→等频或对数,双峰→聚类。