进行时间数据分析,预测’____up(m)'未来的趋势。
import pandas as pd
# 加载数据
data_csv = pd.read_csv('gps_CRIM.csv')
# 查看数据集信息、前几行数据和缺失值情况
data_csv.info(), data_csv.head(), data_csv.isna().sum()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3990 entries, 0 to 3989
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 YYMMMDD 3990 non-null object
1 u0(m) 3990 non-null int64
2 ____up(m) 3990 non-null float64
3 sig_u(m) 3990 non-null float64
dtypes: float64(2), int64(1), object(1)
memory usage: 124.8+ KB
(None,
YYMMMDD u0(m) ____up(m) sig_u(m)
0 2006-01-01 1147 0.439932 0.001941
1 2006-01-02 1147 0.355423 0.002419
2 2006-01-03 1147 0.332316 0.001952
3 2006-01-04 1147 0.365921 0.002795
4 2006-01-05 1147 0.377186 0.001961,
YYMMMDD 0
u0(m) 0
____up(m) 0
sig_u(m) 0
dtype: int64)
# 类型转换
data_csv['YYMMMDD'] = pd.to_datetime(data_csv['YYMMMDD'])
# 按照时间进行排序
data_csv.sort_values('YYMMMDD', inplace=True)
# 选用前1500条数据进行预测
real_data = data_csv[1500:1510]
data_csv = data_csv[:1500]
data_csv['YYMMMDD'].info(), data_csv['YYMMMDD'].head()
<class 'pandas.core.series.Series'>
Int64Index: 1500 entries, 0 to 1499
Series name: YYMMMDD
Non-Null Count Dtype
-------------- -----
1500 non-null datetime64[ns]
dtypes: datetime64[ns](1)
memory usage: 23.4 KB
(None,
0 2006-01-01
1 2006-01-02
2 2006-01-03
3 2006-01-04
4 2006-01-05
Name: YYMMMDD, dtype: datetime64[ns])
时序图
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
# 显示减号
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(12, 4))
# 绘制时序图
plt.plot(data_csv['YYMMMDD'], data_csv['____up(m)'])
plt.title('')
plt.xlabel('')
plt.ylabel('时间')
plt.show()
ACF
计算滞后n阶的自相关性。
acf(x=data_csv['____up(m)'], nlags=80)
from statsmodels.graphics.tsaplots import plot_acf
from statsmodels.tsa.stattools import acf
# 绘制自相关图
plot_acf(data_csv['____up(m)'], lags=80, alpha=1)
plt.show(), acf(x=data_csv['____up(m)'], nlags=80)
自相关系数在滞后50阶后出现截尾现象,q可以选择50。
也可以选择偏小一点的数值,防止计算量过大。
PACF
计算偏自相关性
pacf(x=data_csv['____up(m)'], nlags=50)
from statsmodels.graphics.tsaplots import plot_pacf
from statsmodels.tsa.stattools import pacf
# 绘制偏自相关图
plot_pacf(data_csv['____up(m)'], lags=50, alpha=1, title='Close')
plt.show(), pacf(x=data_csv['____up(m)'], nlags=50)
偏自相关系数在滞后11阶后出现拖尾现象,p可以选择11。
ADF检验
- ADF统计量越小,p值越接近0(小于0.05),时间序列越平稳。
- 进模数据一定要是平稳非白噪声序列,可通过差分、去噪等进行转换。
from statsmodels.tsa.stattools import adfuller
display(adfuller(data_csv['____up(m)']))
(-11.56998971018061,
3.1189970775789195e-21,
22,
1477,
{'1%': -3.434785139702456,
'5%': -2.863498825305098,
'10%': -2.5678128583805213},
-19.909683507237332)
白噪声检验
- 检验结果大于0.05认为是白噪声序列。
from statsmodels.stats.diagnostic import acorr_ljungbox
acorr_ljungbox(x=data_csv['____up(m)'])
lb_stat | lb_pvalue | |
---|---|---|
1 | 40.976821 | 1.540454e-10 |
2 | 74.828391 | 5.639250e-17 |
3 | 87.257463 | 8.501946e-19 |
4 | 89.847496 | 1.418735e-18 |
5 | 92.441779 | 2.061391e-18 |
6 | 95.043262 | 2.707965e-18 |
7 | 97.862170 | 2.979749e-18 |
8 | 109.913523 | 3.966516e-20 |
9 | 138.830044 | 1.798920e-25 |
10 | 151.714192 | 1.654455e-27 |
- ARIMA模型的参数 (p, d, q)
- p (AR阶数,Autoregressive Order): 表示模型中自回归项的阶数,即考虑多少个滞后时间点的值。如果p为2,那么模型将考虑过去两个时间点的值。
- d (差分阶数,Differencing Order): 表示进行差分的次数,即为使时间序列平稳而需要减去的阶数。平稳的时间序列在统计性质上是恒定的,差分可用于使非平稳的时间序列变得平稳。
- q (MA阶数,Moving Average Order): 表示模型中移动平均项的阶数,即考虑多少个滞后时间点的误差。
观察自相关函数(ACF)和偏自相关函数(PACF): 这两个函数提供了关于时间序列结构的信息。ACF表示序列与其过去的值之间的相关性,PACF显示了在去除之前滞后效应后,序列与当前值的相关性。根据这些函数的图形,可以选择p和q的值。
ARIMA模型
from statsmodels.tsa.arima.model import ARIMA
# 将时间作为索引
data_csv.set_index('YYMMMDD', inplace=True)
df = data_csv[['____up(m)']]
# 拟合ARIMA模型
order = (11, 0, 45)
model = ARIMA(df, order=order)
results = model.fit()
# 预测未来数据点
forecast_steps = 10
forecast = results.get_forecast(steps=forecast_steps)
pred_data = forecast.predicted_mean.values
# 获取预测值
pred_date = pd.date_range(start=data_csv.index.max(),
periods=forecast_steps+1, freq='D')[1:]
# 构建预测结果的DataFrame
pred_values = pd.DataFrame(data={'预测值': pred_data}, index=pred_date)
pred_values
预测值
2010-02-09 0.499128
2010-02-10 0.383708
2010-02-11 0.358357
2010-02-12 0.373567
2010-02-13 0.397197
2010-02-14 0.387956
2010-02-15 0.465801
2010-02-16 0.600334
2010-02-17 0.676649
2010-02-18 0.357798
可视化
plt.figure(figsize=(12, 4))
plt.plot(real_data.set_index('YYMMMDD')[['____up(m)']], 'o-', label='真实值')
plt.plot(pred_values, 'o-', label='预测值')
plt.legend()
plt.show()
信息准则自动计算
from pmdarima import auto_arima
from statsmodels.tsa.arima.model import ARIMA
# 使用AIC信息准则自动计算最佳的p, d, q参数
auto_model = auto_arima(df, information_criterion='aic')
# 得到最优的ARIMA模型参数
order = auto_model.order
# 拟合模型
model = ARIMA(df, order=order)
model_fit = model.fit()
# 预测未来10个时间点的值
forecast = model_fit.forecast(steps=10)
forecast
2010-02-09 0.483372
2010-02-10 0.596597
2010-02-11 0.534796
2010-02-12 0.345579
2010-02-13 0.094665
2010-02-14 0.519095
2010-02-15 0.271998
2010-02-16 0.229052
2010-02-17 0.361803
2010-02-18 0.346819
Freq: D, Name: predicted_mean, dtype: float64
plt.figure(figsize=(12, 4))
plt.plot(real_data.set_index('YYMMMDD')[['____up(m)']], 'o-', label='真实值')
plt.plot(forecast, 'o-', label='预测值')
plt.legend()
plt.show()