声明:
- 本文是系列课程的第三课
- 本文是对机器学习网站课程的翻译
- 尊重原作者,尊重知识分享
用Python进行时间序列可视化
时间序列本身的特性决定了它很容易被可视化,特别适用于折线图。然而,还有一些其他方法可以可视化时间序列,而且会展现时间序列其他方面的信息。我们对要分析的时间序列了解的越多,建立的预测模型就会越好,所以要好好学习这节课~
通过本文,你将了解:
- 如何通过折线图、滞后图(lag plots)和自相关图,研究时间序列的暂态特性。
- 如何用矩形图和密度图研究时间序列的值的分布特征。
- 如何用箱型图和热力图剖析时间序列的内在分布。
时间序列可视化
可视化分析发现原始数据中的诸如趋势、循环、季节性等特征,对后面模型的选择有重要的帮助作用。Unfortunately,在进行时间序列可视化分析时,大量的新手止步于线性图。下面,我们将会介绍6中不同的可视化方法:
- Line Plots 线形图
- Histograms and Density Plots 矩形图和密度图
- Box and Whisker Plots 箱型图
- Heat Maps热力图
- Lag Plot or Scatter Plots 滞后散点图
- Autocorrelation Plots 自相关图
Minimum Daily Temperatures (MDT) Dataset
该数据集记录澳大利亚城市墨尔本与1981年-1990年间日最低气温,通3650个观测值,下载地址。
温馨提示:在加载前,记得将文件中的“?”和一些注释脚本去掉。
from pandas import Series
from matplotlib import pyplot
series = Series.from_csv('daily-minimum-temperatures.csv', header=0)
print(series.head())
'''输出:
Date
1981-01-01 20.7
1981-01-02 17.9
1981-01-03 18.8
1981-01-04 14.6
1981-01-05 15.8
Name: Temp, dtype: float64
'''
1. 折线图
from pandas import Series
from matplotlib import pyplot
series = Series.from_csv('daily-minimum-temperatures.csv', header=0)
series.plot()
pyplot.show()

我们也可以调整折线图的风格(style),例如用电代替线,并换个颜色。
from pandas import Series
from matplotlib import pyplot
series = Series.from_csv('daily-minimum-temperatures.csv', header=0)
series.plot(style='k.') # 注意参数style
pyplot.show()

可以发现,将10年的数据描绘在一张图中有些拥挤,若能将数据按照相同的时间间隔(如日,月,年)展示在多个图中,将大大提高可视化效果。
Minimum Daily Temperatures dataset有时间的数据。我们将它按年分割,分别作图:
from pandas import Series
from pandas import DataFrame
from pandas import TimeGrouper
from matplotlib import pyplot
series = Series.from_csv('daily-minimum-temperatures.csv', header=0)
groups = series.groupby(TimeGrouper('A'))
years = DataFrame()
for name, group in groups:
years[name.year] = group.values
years.plot(subplots=True, legend=False)
pyplot.show()

2. 矩形图和密度图
另一个重要的可视化方法就是用矩形图来观察原始数据的分布,意味着此时我们不需要考虑时间序列的顺序。
有些时间序列预测的方法必须假设原始数据服从特定的分布(如钟型分布或正态分布)。这些分布可以通过统计学中假设检验的方法来验证,更可取的方法是通过可视化直接观察。
MDT数据集的矩形图表示:
from pandas import Series
from matplotlib import pyplot
series = Series.from_csv('daily-minimum_temperatures.csv', header=0)
series.hist()
pyplot.show()

将矩形图中各个矩形定点用平滑的曲线连接,就变成了密度图。
from pandas import Series
from matplotlib import pyplot
series = Series.from_csv('daily-minimum-temperatures.csv', header=0)
series.plot(kind='kde')
pyplot.show()

MDT数据集的分布有一点点不对称,接近高斯分布。
3. 箱图
矩形图可以描绘数据整体的分布,下面介绍的箱型图能展示更多的分布信息。
- 箱图的箱型框下边界是25%分位点,上边界是75分位点,中间的线是50%分位点。
- 箱图上下的虚线表示超出4分位点的一般点。
- 箱图中的+描绘的是远离整体分布的异常点。
我们可以在一幅图中为每一年都画一个箱型图。
from pandas import Series
from pandas import DataFrame
from pandas import TimeGrouper
from matplotlib import pyplot
series = Series.from_csv('daily-minimum-temperatures.csv', header=0)
groups = series.groupby(TimeGrouper('A'))
years = DataFrame()
for name, group in groups:
years[name.year] = group.values
years.boxplot()
pyplot.show()

可以看出每年的最低气温分布变化较小。下面我们可视化1990年一年12个月的分布箱图。
from pandas import Series
from pandas import DataFrame
from pandas import TimeGrouper
from matplotlib import pyplot
from pandas import concat
series = Series.from_csv('daily-minimum-temperatures.csv', header=0)
one_year = series['1990']
groups = one_year.groupby(TimeGrouper('M'))
months = concat([DataFrame(x[1].values) for x in groups], axis=1)
months = DataFrame(months)
months.columns = range(1,13)
months.boxplot()
pyplot.show()

可以看出,最低气温在一年中随季节变化明显。
4. 热力图
在热力图中,我们用暖色调(黄色、红色)表示较大的值,用冷色调(蓝色、绿色)表示较小的值。
下面,我们描绘一个热力图,行代表年份,列代表日期。
from pandas import Series
from pandas import DataFrame
from pandas import TimeGrouper
from matplotlib import pyplot
series = Series.from_csv('daily-minimum-temperatures.csv', header=0)
groups = series.groupby(TimeGrouper('A'))
years = DataFrame()
for name, group in groups:
years[name.year] = group.values
years = years.T
pyplot.matshow(years, interpolation=None, aspect='auto')
pyplot.show()

接着我们为1990年的每个月单独搞一个热力图。
from pandas import Series
from pandas import DataFrame
from pandas import TimeGrouper
from matplotlib import pyplot
from pandas import concat
series = Series.from_csv('daily-minimum-temperatures.csv', header=0)
one_year = series['1990']
groups = one_year.groupby(TimeGrouper('M'))
months = concat([DataFrame(x[1].values) for x in groups], axis=1)
months = DataFrame(months)
months.columns = range(1,13)
pyplot.matshow(months, interpolation=None, aspect='auto')
pyplot.show()

图中空白部分是应为有些月份不足31天,在月末没有数据。
5. 滞后散点图
滞后散点图用来观察时间序列中的自相关关系,具体为:横坐标是所有原始数据值的坐标,纵坐标是原始数据滞后1或以上各时刻后的值的坐标。通过观察这个散点图中点的分布,可以得到时间序列前一时刻和当前时刻之间的自相关关系。
- 若散点图呈左下到右上的分布,正相关。
- 若干散点图呈左上到右下的分布,负相关。
- 散点图分布的越分散,自相关性越弱。
from pandas import Series
from matplotlib import pyplot
from pandas.tools.plotting import lag_plot
series = Series.from_csv('daily-minimum-temperatures.csv', header=0)
lag_plot(series)
pyplot.show()

有时候时间序列在不相邻的时刻之间存在相关关系,比如隔周、隔月等,下面我们分别对过去七天的时刻描绘滞后散点图。
from pandas import Series
from pandas import DataFrame
from pandas import concat
from matplotlib import pyplot
from pandas.plotting import scatter_matrix
series = Series.from_csv('daily-minimum-temperatures.csv', header=0)
values = DataFrame(series.values)
lags = 7
columns = [values]
for i in range(1, (lags + 1)):
columns.append(values.shift(i))
dataframe = concat(columns, axis=1)
columns = ['t+1']
for i in range(1, (lags + 1)):
columns.append('t-' + str(i))
dataframe.columns = columns
pyplot.figure(1)
for i in range(1, (lags + 1)):
ax = pyplot.subplot(240 + i)
ax.set_title('t+1 vs t-' + str(i))
pyplot.scatter(x=dataframe['t+1'].values, y=dataframe['t-' + str(i)].values)
pyplot.show()

6. 自相关图
我们可以量化观察值与其滞后之间关系的强度和类型。在统计中,这被称为相关性,并且在时间序列中针对滞后值进行计算时,称为自相关(自相关)。
计算两组数字之间的相关性值(如观测值及其lag1值)会得出-1和1之间的数字。此数字的符号分别表示负相关或正相关。接近0的值表示弱相关性,而接近-1或1的值表示强相关性。
可以为每个观测值和不同的滞后值计算相关值,称为相关系数。一旦计算出来,就可以创建一个图表来帮助更好地理解这种关系如何在滞后期间发生变化。
这种类型的图被称为自相关图,Pandas提供了内置的这种能力,称为autocorrelation_plot()
函数。
from pandas import Series
from matplotlib import pyplot
from pandas.tools.plotting import autocorrelation_plot
series = Series.from_csv('daily-minimum-temperatures.csv', header=0)
autocorrelation_plot(series)
pyplot.show()

上图,横坐标表示滞后的天数,滞后天数越多,相关性越弱,纵坐标表示相关值。我们可以看到,对于MDT数据集,我们可以看到强烈的负相关和正相关的周期:每年相同季节正相关,不同季节负相关。