大家好,欢迎来到IT知识分享网。
原文地址:点这里
常规来说,EDA有一些通用方法,如直方图观察频率分布情况,散点图观察不同列的相关关系,折线图观察趋势变化等,这里不做赘述,下面重点将介绍针对时间序列的特殊方法。
针对时间序列的特殊方法
对于一个时间序列数据,我们要问的第一个问题是它是否反映一个平稳的系统。平稳性的评估很重要,因为这让我们知道在多大程序上历史数据可以用来预测未来数据。确认了平稳性后,我们要接着探索时间序列是否存在一些内部动态关系(例如季节性变化),也叫自相关性,这能解释未来数据和历史数据之间有多紧密的关联性。最后,我们需要确保我们找到的关联是真正的因果关系,而不是虚假的相关性。
理解平稳性
许多时间序列的统计学模型都是依赖于时间序列是平稳的这一前提条件,通常来说,一个平稳的时间序列指的是这个时间序列在一段时间内具有稳定的统计值,如均值,方差。由于我们对于一个数据是否平稳是有自己的直觉的,所以在实践的过程中要谨防过于依赖直觉而被直觉所欺骗
为此我们引入了一些统计上的假设检验来测试一个时间序列数据的平稳性。
其中Augmented Dickey Fuller Test (ADF Test) 是最常使用的一种方法,ADF test也是单位根检验(unit root test)的一种。单位根是一个使得时间序列非平稳的一个特征,从技术上说,在下面的公式中如果alpha=1,那么我们说存在单位根。
其中Yt,Yt-1分别表示t时刻和t-1时刻的时间序列值,Xe表示外生变量,E表示误差项。
从直觉上我们可以理解为,只有当alpha<1时,整个时间序列的趋势才是有可能出现逆转的。而ADF test就是对alpha值的假设检验,它的原假设是alpha =1,即原假设成立,则时间序列非平稳。
但是我们需要记住,ADF test不是一个永远行之有效的方法,它存在一些不足:
- 对于区分近似单位根(near unit roots)和单位根不是很有效
- 当数据点很少时,容易出现假阳性的问题
- 大多数测试不会检测所有导致非平稳的因素,例如有些测试只是检验均值或方差两者之一是否平稳,有些测试只是检验总体分布。因此在使用任何假设检验时都要先充分理解数据的特点和检验的限制因素
此外还有一种Kwiatkowski-Phillips-Schmidt-Shin (KPSS) test也是常用的时间序列平稳性假设检验,它和ADF的区别是KPSS的原假设是关于平稳过程,而ADF的原假设是关于单位根。
时间序列平稳性的重要性在于:
- 大量的统计学模型基于平稳性的假设
- 对于一个应用于非平稳时间序列的模型,它的准确性和模型指标会随着时间序列本身变化而变化,从而造成模型本身不稳定。
下面看实例:
数据的平稳性验证
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller
import pandas as pd
import numpy as np
x = [1, 2, 3, 4, 5, 6, 7]
y = [1, 4, 9, 12, 17, 20, 27]
s = pd.Series(y, index=x)
plt.plot(s)
plt.show()
result = adfuller(s, autolag='AIC')
print(f'ADF Statistic: {result[0]}')
print(f'n_lags: {result[1]}')
print(f'p_value: {result[1]}')
# ADF Statistic: 1.7320508075688825
# n_lags: 0.9982042849867909
# p_value: 0.9982042849867909
# p值及其接近1,很难拒绝原假设,表示有很大的概率存在单位根,时间序列非平稳
series1 = np.random.randn(100)
plt.plot(series1)
plt.show()
result1 = adfuller(series1,autolag='AIC')
print(f'ADF Statistic:{result1[0]}')
print(f'p-value:{result1[1]}')
# ADF Statistic:-10.22365215833778
# p-value:5.2450722013097415e-18
# p值远小于0.05,表示拒绝原假设,即时间序列是平稳的
寻找自相关
自相关是时间序列的一个重要概念,指的是时间序列中某一个时刻的值和另一个时刻的值具有一定的相关性。举例来说,有一个每天更新的气温数据,你可能会发现每年5月15号和8月15号的气温存在某种关联,当年5月15号更热,则对应的8月15号也更热。当然还有一种可能性是这种关联性趋近于0, 知道5月15号的气温并不会给你任何关于8月15号气温的信息。
为了进一步探索自相关,需要引入两个函数,自相关函数和偏自相关函数来描述这一现象。
The autocorrelation function
自相关(acf)函数描述的是一组时间序列和它前面间隔n个时刻的一组时间序列之前的相关性。
关于acf有一些重要的事实:
- 对几个周期性序列的和计算acf,和分别计算每个周期性序列的acf再相加,结果是一样的
- 所有时间序列在间隔lag=0时的acf值都为1,也就是时间序列和它本身之前具有完全的正相关性
- 一个完全的白噪声序列,它在任何间隔处的acf都近似于0
- 对于任何一个时间序列,它在5%的置信度下的acf值不显著为0的置信区间临界值为其中
T为样本量,d为时间间隔,从公式中可以得出,随着时间间隔d的增大,置信区间也是在不断增大的,也就是说距离越远的相关性越不可信
The partial autocorrelation function
偏自相关(pacf)函数描述的是一组时间序列和它前面间隔n个时刻的一组时间序列之前的偏相关性。这里的偏相关性可以从本质上理解为去除了样本之间的干涉,也就是更早时刻的相关性影响。
举例来说,计算时间间隔3的pacf是去除了时间间隔小于3的样本的影响,而只计算由于时间间隔为3时的时间序列之间的相关性,因为时间间隔为1和2的样本的影响已经在前面的pacf函数中计算过了。通过之后python实战的例子可以帮助我们理解这个概念。
关于pacf也有一些有趣的事实:
- 对于周期性时间序列,pacf会迅速趋近于0,,而不是像acf一样呈现周期性,因此pacf没有太多冗余信息存在。这对于我们判断要收集多长时间序列才能获取足够多的信息具有很大的帮助。
- pacf的置信区间临界值和acf相同
下面看例子:
import matplotlib.pyplot as plt
import pandas as pd
from statsmodels.graphics.tsaplots import plot_acf,plot_pacf
# 导入气温数据
series = pd.read_csv('..\\srouce\\daily-min-temperatures.csv',header=0,index_col=0,parse_dates=True,squeeze=True)
# 画出最低气温时间序列
plt.plot(series)
plt.show()
# 画出acf函数
# 蓝色底色区域内画出的是95%置信区间,数据落在蓝色区域内表示在统计学意义上在x轴的时间间隔下具有自相关性
plot_acf(series)
plt.show()
# 画出pacf函数
plot_pacf(series)
plt.show()
# 构造一个非平稳线性增长时间序列
x = np.linspace(1, 100, 100)
plt.plot(x)
plt.show()
plot_acf(x)
plt.show()
plot_pacf(x)
plt.show()
# 从这个例子可以看到,从lag>=2开始,pacf值几乎都等于0
虚假相关性
时间序列分析的新人分析师通常会从标准的探索性数据开始实践,例如将两个变量相互绘制并计算它们的相关性。当他们注意到变量之间非常强的相关性时,会非常兴奋。但是当分析师向其他人展示他们的发现,会意识到这一切都没有意义。有人会质疑指出相关性有些过于高了,并且当新人分析师尝试用更多变量重新运行他们的分析时,会发现更多变量之间也具有惊人的高相关性。但实际上我们都清楚,现实生活中有不可能有这么多真正的高相关性。
这个情况非常像计量经济学的早期历史。在 19 世纪,当经济学家第一次开始思考商业周期的概念时,他们去寻找影响周期的外部驱动因素,例如太阳黑子(11 年的周期)或各种气象周期(例如 4 年的降水周期)。他们总是得到非常积极和高度相关的结果,即使他们并没有因果关系来解释这些结果。这些都是所谓的虚假相关性。
具有潜在趋势的数据很可能产生虚假的相关性,例如碳排放量的上升和变暖的全球气温之间的相关性。 除了趋势之外,时间序列的其他一些共同特征也会引入虚假相关性:
- 季节性,例如考虑夏天热狗消费量和溺水死亡人数的相关性
- 随着时间的推移,状态变化引起的数据水平或斜率变化
- 累计数量的相关性,这被许多行业广泛用于人为制造更强相关性的技巧
因此在实践中发现极强相关性的时候一定要结合行业经验仔细验证,不能盲目相信数据上的结果。
这个网站http://tylervigen.com/spurious-correlations,记录了许多虚假相关性的例子,表面上看起来相关关系都惊人的高。
例如这个美国在科技领域的花费和自杀率之间的时间序列相关性。
常用的可视化图表
可视化是数据探索的一个重要工具,相比于数据本身,使用图表能让我们更容易发现数字背后的信息,帮助我们理解数据,例如某一个变量的行为,或是总体时间分布的特点。
一维数据可视化可以帮助理解个体的独立时间分布特点,二维数据可视化可以帮助理解某个变量值同时在时间轴和另一个变量维度上的轨迹特征,而对于三维数据可视化,虽然可以在更高的维度上观察数据,但是在可视化领域其实不太推荐使用这类图表,因为在视觉上不清晰,容易造成误导。
1D 可视化
一种常用的一维可视化形式是甘特图,在项目管理中较为常见,下面的这个可视化例子是展示了不同任务在时间轴上的起始分布和工作量。
import plotly.express as px
import pandas as pd
job = pd.read_csv('..\\srouce\\data\\job.csv')
job.start = job.start.astype('datetime64')
job.finish = job.finish.astype('datetime64')
fig = px.timeline(job, x_start='start', x_end='finish', y='task')
fig.show()
2D 可视化
二维可视化可以展现更多信息,下面就以美国航空乘客数据来展示常用的可视化图表。
对于时间序列数据,折线图很自然是最适合的表现形式之一,以年份为分类变量,可以展示在一年中的各个月份下航空乘客的变化关系,发现无论在哪一年,几乎都呈现夏季航空出行量最高的规律。
如果换一种方式绘制折线图,以月份为分类变量,年份为X轴,可以看出1949-1960这十多年间是航空业大发展的时期,整体的航空出行量都在显著增加。
还有一种常见的二维可视化方式是热力图,将原始数据拆成年和月两个维度,同样可以清楚直观地看出航空出行在时间维度上的规律。
import plotly.express as px
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# 2D
air = pd.read_csv('..\\srouce\\data\\AirPassengers.csv', parse_dates=['date'])
air['year'] = air['date'].dt.year
air['month'] = air['date'].dt.month
palette = sns.color_palette('hls', 12)
fig = sns.lineplot(x='month', y='value', data=air, hue='year', palette=palette)
fig.set_xticks(range(1, 13))
fig.set_xticklabels(["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"])
plt.show()
fig = sns.lineplot(x='year', y='value', data=air, hue='month', palette=palette)
plt.show()
air_mat = air.pivot(index='year', columns='month', values='value')
sns.heatmap(data=air_mat, annot=True, fmt='d', linewidths=0.5)
plt.show()
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/32097.html