4、探索性数据分析(EDA):描述性统计与可视化

各位同学,欢迎来到资金流预测模型的第一章实战内容。今天咱们聊聊EDA——探索性数据分析。说白了,就是拿到数据后,先别急着建模,得先跟数据“聊聊天”,摸摸它的脾气秉性。

我个人习惯,拿到任何资金流数据,第一件事不是跑模型,而是做描述性统计和可视化。为什么?因为数据不会骗人,但脏数据会。我见过太多人上来就调参,结果模型跑出来一塌糊涂,回头一看,原来是数据里有几个异常值在捣乱。

核心观点:EDA不是走过场,它是建模的“体检报告”。跳过这一步,后面全是坑。

4.1 描述性统计:均值、中位数、标准差

描述性统计,就是给数据“量体温”。我们最常用的三个指标:均值、中位数、标准差。

  • 均值(Mean):所有数据加起来除以个数。它很敏感,一个极端值就能把它拉偏。
  • 中位数(Median):排序后中间那个数。它很稳健,极端值对它影响不大。
  • 标准差(Std):衡量数据波动大小。标准差越大,数据越“散”。

我在项目中遇到过这样的情况:某月资金流均值突然飙升,团队以为是业务爆发了。结果一查中位数,纹丝不动。再一查,原来是某笔大额异常交易。你看,光看均值会误判,中位数才是“老实人”。

小技巧:当均值远大于中位数时,数据大概率右偏(有大的异常值)。反之,左偏。

下面是一个简单的Python代码示例,计算资金流数据的描述性统计:

import pandas as pd
import numpy as np

# 假设df是资金流数据,'amount'是金额列
df = pd.read_csv('cash_flow.csv')

mean_val = df['amount'].mean()
median_val = df['amount'].median()
std_val = df['amount'].std()

print(f"均值: {mean_val:.2f}")
print(f"中位数: {median_val:.2f}")
print(f"标准差: {std_val:.2f}")

# 快速判断数据分布
if mean_val > median_val * 1.5:
    print("警告:数据右偏严重,可能存在大额异常值")

4.2 可视化:折线图、柱状图、箱线图

光看数字不够直观,得画图。我常用的三种图:

  • 折线图:看趋势。资金流随时间怎么变化?是上升、下降,还是周期性波动?
  • 柱状图:看分布。哪个月份资金流最多?哪个季度最紧张?
  • 箱线图:看异常。哪些数据点离群?有没有需要处理的极端值?

嗯,这里要注意:折线图适合连续时间序列,柱状图适合分类对比。别搞混了。

我曾经犯过一个低级错误:用折线图展示月度汇总数据,结果因为月份之间没有连续性,折线图看起来像锯齿,完全看不出规律。后来换成柱状图,一目了然。

import matplotlib.pyplot as plt
import seaborn as sns

# 折线图:查看资金流随时间趋势
plt.figure(figsize=(12, 5))
plt.plot(df['date'], df['amount'], marker='o', linestyle='-', color='#4A90D9')
plt.title('资金流时间序列趋势')
plt.xlabel('日期')
plt.ylabel('金额')
plt.xticks(rotation=45)
plt.grid(True, alpha=0.3)
plt.show()

# 箱线图:查看异常值
plt.figure(figsize=(8, 5))
sns.boxplot(y=df['amount'], color='#E74C3C')
plt.title('资金流箱线图 - 异常值检测')
plt.ylabel('金额')
plt.show()

4.3 季节性模式识别

资金流数据,十有八九有季节性。比如零售行业,年底是旺季;旅游行业,暑假是高峰。识别季节性,能帮我们做更准的预测。

怎么识别?我一般用两种方法:

  1. 按月份/季度聚合:计算每个月的平均资金流,看看有没有重复的“峰”和“谷”。
  2. 自相关图(ACF):看数据与自身滞后期的相关性。如果滞后12个月(年周期)相关性高,说明有年度季节性。
避坑指南:我曾经以为所有季节性都是12个月周期。结果有个项目,数据是周粒度,季节性周期是7天。所以,先搞清楚数据粒度,再谈季节性。
# 按月份聚合,查看季节性
df['month'] = pd.to_datetime(df['date']).dt.month
monthly_avg = df.groupby('month')['amount'].mean()

plt.figure(figsize=(10, 5))
plt.bar(monthly_avg.index, monthly_avg.values, color='#2ECC71')
plt.title('月度平均资金流 - 季节性模式')
plt.xlabel('月份')
plt.ylabel('平均金额')
plt.xticks(range(1, 13))
plt.show()

4.4 趋势分析

趋势,就是长期方向。资金流是整体在增长,还是在萎缩?这个判断直接影响业务决策。

我常用的趋势分析方法:

  • 移动平均:平滑短期波动,看清长期方向。比如用12个月移动平均。
  • 线性回归:拟合一条直线,看斜率是正还是负。

你想想看,如果资金流趋势是下降的,你还按增长去备货,那不是找死吗?所以趋势分析必须做。

# 计算12个月移动平均
df['rolling_mean'] = df['amount'].rolling(window=12).mean()

plt.figure(figsize=(12, 5))
plt.plot(df['date'], df['amount'], alpha=0.5, label='原始数据')
plt.plot(df['date'], df['rolling_mean'], color='red', linewidth=2, label='12个月移动平均')
plt.title('资金流趋势分析 - 移动平均')
plt.xlabel('日期')
plt.ylabel('金额')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

4.5 本章知识体系

下面这张图,是我自己总结的EDA核心逻辑。你把它记在心里,以后做任何资金流分析,按这个流程走,基本不会漏东西。

资金流EDA核心流程 1. 数据加载 2. 描述性统计 3. 可视化 4. 模式 季节性模式识别 趋势分析 输出:数据质量报告 + 建模建议
我的经验:EDA不是一次性的。建模过程中发现问题,随时回来再做EDA。我有个项目,模型效果差,回头一看,原来是数据分布变了,季节性周期也变了。重新做EDA后,模型准确率提升了15%。
警告:不要过度解读EDA结果。比如看到两个变量相关,就以为是因果关系。相关不等于因果,这个坑我踩过不止一次。

好了,这一章的内容就到这里。记住,EDA是建模的基石,地基不牢,楼盖得再高也得塌。下一章,我们会聊数据预处理——怎么清洗数据、处理缺失值和异常值。到时候见。


专注资料整理