4. 数据可视化与探索:Matplotlib/Seaborn绘制时间序列图、ACF/PACF图解读

数据可视化,说白了就是让数据开口说话。你想想看,一堆数字摆在那,你很难看出门道。但画成图,趋势、周期、异常点,一眼就能揪出来。

我个人习惯,拿到时间序列数据后,第一件事不是跑模型,而是画图。先看原始序列图,再看自相关和偏自相关图。这三张图,基本能告诉你80%的信息。

4.1 原始时间序列图:第一印象

原始序列图,就是把时间作为横轴,数值作为纵轴,把点连成线。这是最基础,也是最直观的图。

我建议你用Matplotlib来画。它灵活,可控性强。Seaborn虽然好看,但有时候自定义起来反而麻烦。

import matplotlib.pyplot as plt
import pandas as pd

# 假设你有一个DataFrame,索引是时间
df = pd.read_csv('sales_data.csv', parse_dates=['date'], index_col='date')

plt.figure(figsize=(12, 5))
plt.plot(df.index, df['sales'], color='#2E86AB', linewidth=1.5)
plt.title('每日销售额时间序列', fontsize=14)
plt.xlabel('日期')
plt.ylabel('销售额(元)')
plt.grid(True, alpha=0.3)
plt.show()

嗯,这里要注意:时间索引一定要是datetime类型。我遇到过好几次,有人把日期当字符串传进去,结果横轴乱序,图完全没法看。

看原始序列图,重点看什么?

  • 趋势:整体是上升、下降,还是平稳?
  • 季节性:有没有明显的周期性波动?比如每年夏天销量高,冬天低。
  • 异常点:有没有突然的尖峰或低谷?可能是数据错误,也可能是突发事件。
  • 方差变化:波动幅度是否随时间变化?如果波动越来越大,可能需要做对数变换。

我的小技巧:如果数据点太多(比如每分钟一条),画出来会密密麻麻。这时候可以先用resample()降采样,比如按天或按周聚合,再看整体趋势。

4.2 ACF与PACF:揭开时间依赖的面纱

原始序列图看的是「值」的变化。但时间序列分析的核心,是看「值之间的关系」。具体来说,就是当前时刻的值,跟过去哪些时刻的值有关。

这时候就要请出ACF(自相关函数)和PACF(偏自相关函数)了。

4.2.1 ACF图:看总体的相关性

ACF衡量的是:当前时刻的值,与滞后k期的值之间的相关性。注意,这里包含间接影响。比如,t时刻与t-2时刻的相关性,可能有一部分是通过t-1时刻传递过去的。

我用Seaborn画ACF图,因为它默认带置信区间,方便判断相关性是否显著。

from statsmodels.graphics.tsaplots import plot_acf
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 4))
plot_acf(df['sales'], lags=30, alpha=0.05)
plt.title('销售额的ACF图')
plt.xlabel('滞后阶数')
plt.ylabel('自相关系数')
plt.show()

ACF图怎么看?

  • 如果ACF在滞后几阶后迅速衰减到0附近,说明序列可能是平稳的。
  • 如果ACF衰减很慢,拖尾很长,说明序列可能有趋势或非平稳性。
  • 如果ACF在某个滞后阶数上突然跳出置信区间,说明那个滞后阶数有显著相关性。

我曾经踩过的坑:有一次,我看到ACF图在滞后12阶处有个很高的尖峰,以为模型需要包含12阶滞后。后来才发现,数据是月度数据,那个尖峰只是季节性周期。所以,一定要结合业务背景看ACF,别光看统计显著性。

4.2.2 PACF图:看直接的相关性

PACF剔除了中间变量的影响,只保留「直接」的相关性。比如,PACF在滞后2阶处显著,说明t时刻与t-2时刻有直接关系,而不是通过t-1传递的。

from statsmodels.graphics.tsaplots import plot_pacf

plt.figure(figsize=(10, 4))
plot_pacf(df['sales'], lags=30, alpha=0.05, method='ywm')
plt.title('销售额的PACF图')
plt.xlabel('滞后阶数')
plt.ylabel('偏自相关系数')
plt.show()

PACF图怎么看?

  • 如果PACF在p阶后截尾(突然降到0附近),说明AR模型的阶数可能是p。
  • 如果PACF拖尾,说明可能更适合用MA模型。

ACF与PACF的经典组合判断

模型 ACF PACF
AR(p) 拖尾(逐渐衰减) p阶后截尾
MA(q) q阶后截尾 拖尾(逐渐衰减)
ARMA(p,q) 拖尾 拖尾

4.3 用Seaborn画更漂亮的图

Matplotlib是基础,但Seaborn能让图更好看,尤其适合做探索性分析时快速出图。

import seaborn as sns

# 设置Seaborn风格
sns.set_style('whitegrid')
sns.set_palette('husl')

# 画原始序列图
plt.figure(figsize=(12, 5))
sns.lineplot(data=df, x=df.index, y='sales')
plt.title('销售额时间序列 (Seaborn版)')
plt.show()

我个人习惯,正式报告用Seaborn,因为配色和样式更专业。但调试模型时,我还是用Matplotlib,因为改起来快。

4.4 本章知识体系

下面这张图,帮你理清数据可视化与探索的核心逻辑:

时间序列数据可视化与探索 原始序列图 ACF图 PACF图 趋势 / 季节性 / 异常 总体相关性(含间接) 直接相关性(剔除间接) 综合判断:平稳性 / 模型定阶 AR模型阶数p / MA模型阶数q 是否需要差分 / 是否需要季节模型 三图联动,缺一不可

4.5 实战中的避坑指南

讲完理论,说点实战中容易踩的坑。

避坑1:别只看ACF/PACF的绝对值

有一次,我看到ACF在滞后1阶处是0.3,觉得相关性不高。但后来发现,样本量很大(10000个点),0.3已经非常显著了。记住:显著性要看置信区间,不是看数值大小

避坑2:差分后的ACF/PACF会变

我曾经对非平稳序列做了一阶差分,然后看ACF。结果发现ACF在滞后1阶处变成了负值,而且很显著。当时我以为是数据有问题,后来才明白:差分本身会引入负的自相关,这是正常的。

避坑3:季节性数据要画季节图

如果你有月度数据,我建议你画一个「按月份分组的箱线图」。这样能直观看到,每年哪个月份高,哪个月份低。ACF图虽然也能看出季节性,但不如箱线图直观。

# 画季节箱线图
df['month'] = df.index.month
sns.boxplot(data=df, x='month', y='sales')
plt.title('各月份销售额分布')
plt.show()

好了,数据可视化这块就讲这么多。记住:图是给你自己看的,不是给别人看的。画图的目的,是帮你理解数据,而不是为了好看。所以,怎么有效怎么来。


公众号:蓝海资料掘金营,微信deep3321