时间序列分析_co2的预测分析

分析目的:

根据时间序列反映出来发展过程和趋势,建立ARIMA模型,预测下一段时间可能达到的水平。

字段说明

date:时间
co2: 二氧化碳

1.导入数据

import pandas as pd
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')
data = sm.datasets.co2.load_pandas()
Mauna_Loa_CO2 =pd.read_csv('./Mauna_Loa_CO2 .csv')
Mauna_Loa_CO2.head()
date co2
0 1958/3/29 316.1
1 1958/4/5 317.3
2 1958/4/12 317.6
3 1958/4/19 317.5
4 1958/4/26 316.4

2.数据探索



Mauna_Loa_CO2.info()


<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2284 entries, 0 to 2283
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   date    2284 non-null   object 
 1   co2     2225 non-null   float64
dtypes: float64(1), object(1)
memory usage: 35.8+ KB



Mauna_Loa_CO2.isnull().any()


date    False
co2      True
dtype: bool


Mauna_Loa_CO2_Miss=Mauna_Loa_CO2.fillna(method='ffill')
Mauna_Loa_CO2_Miss.info()


<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2284 entries, 0 to 2283
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   date    2284 non-null   object 
 1   co2     2284 non-null   float64
dtypes: float64(1), object(1)
memory usage: 35.8+ KB


Mauna_Loa_CO2_Miss.isnull().any()


date    False
co2     False
dtype: bool


import pandas as pd
Mauna_Loa_CO2_Miss['date']=pd.to_datetime(Mauna_Loa_CO2_Miss['date'])
Mauna_Loa_CO2_Miss.set_index('date',inplace=True)

Mauna_Loa_CO2_Miss_Mon=Mauna_Loa_CO2_Miss['co2'].resample('MS').mean()
Mauna_Loa_CO2_Miss_Mon2=pd.DataFrame(Mauna_Loa_CO2_Miss_Mon)
Mauna_Loa_CO2_Miss_Mon2.head()


co2 date
1958-03-01 316.100
1958-04-01 317.200
1958-05-01 317.420
1958-06-01 317.900
1958-07-01 315.625


import matplotlib.pyplot as plt
Mauna_Loa_CO2_Miss.plot(figsize=(15, 6))
plt.title("CO2 Trend") 
plt.xlabel("Month") 
plt.ylabel("CO2") 
plt.show()


output_14_0.png


from statsmodels.tsa.seasonal import seasonal_decompose
from pylab import rcParams
rcParams['figure.figsize'] = 11, 9
decomposition = sm.tsa.seasonal_decompose(Mauna_Loa_CO2_Miss_Mon2, model='additive')
fig = decomposition.plot()
plt.show()


output_15_0.png

3.序列平稳性检验



get_ipython().run_line_magic('matplotlib', 'inline')
import pandas as pd
from statsmodels.tsa.stattools import adfuller
import matplotlib.pyplot as plt
def test_stationarity(timeseries):
    #计算均值与方差
    rolmean = timeseries.rolling(window=12).mean()
    rolstd = timeseries.rolling(window=12).std()
    #绘制图形:
    fig = plt.figure(figsize=(12, 8))
    orig = plt.plot(timeseries, color='blue',label='Original')
    mean = plt.plot(rolmean, color='red', label='Rolling Mean')
    std = plt.plot(rolstd, color='black', label = 'Rolling Std')
    plt.legend(loc='best')# 使用自动最佳的图例显示位置
    plt.title('Rolling Mean & Standard Deviation')
    plt.xlabel("Month") #添加X轴说明
    plt.ylabel("CO2") #添加Y轴说明
    plt.show()#观察是否平稳
    print('ADF检验结果:')
    #进行ADF检验
    print('Results of Dickey-Fuller Test:')
# 使用减小AIC的办法估算ADF测试所需的滞后数
    dftest = adfuller(timeseries, autolag='AIC')
    # 将ADF测试结果、显著性概率、所用的滞后数和所用的观测数打印出来
    dfoutput = pd.Series(dftest[0:4], index=['Test Statistic','p-value','#Lags Used','Number of Observations Used'])
    for key,value in dftest[4].items():
        dfoutput['Critical Value (%s)'%key] = value
    print(dfoutput)
test_stationarity(Mauna_Loa_CO2_Miss_Mon2['co2'])


output_17_0.png
ADF检验结果:
Results of Dickey-Fuller Test:
Test Statistic                   2.140106
p-value                          0.998829
#Lags Used                      15.000000
Number of Observations Used    510.000000
Critical Value (1%)             -3.443237
Critical Value (5%)             -2.867224
Critical Value (10%)            -2.569797
dtype: float64

4.序列变换



Mauna_Loa_CO2_Miss_Mon2['first_difference'] =Mauna_Loa_CO2_Miss_Mon2['co2'].diff(1)  
test_stationarity(Mauna_Loa_CO2_Miss_Mon2['first_difference'].dropna(inplace=False))


output_19_0.png
ADF检验结果:
Results of Dickey-Fuller Test:
Test Statistic                  -4.824703
p-value                          0.000049
#Lags Used                      19.000000
Number of Observations Used    505.000000
Critical Value (1%)             -3.443366
Critical Value (5%)             -2.867280
Critical Value (10%)            -2.569827
dtype: float64

5.白噪音检验



Mauna_Loa_CO2_Miss_Mon2['seasonal_difference'] = Mauna_Loa_CO2_Miss_Mon2['first_difference'].diff(12)  
test_stationarity(Mauna_Loa_CO2_Miss_Mon2['seasonal_difference'].dropna(inplace=False))




from statsmodels.stats.diagnostic import acorr_ljungbox 
print(acorr_ljungbox(Mauna_Loa_CO2_Miss_Mon2['seasonal_difference'].iloc[13:], lags=1))


6.确定参数



fig = plt.figure(figsize=(12,8))
ax1 = fig.add_subplot(211)
fig = sm.graphics.tsa.plot_acf(Mauna_Loa_CO2_Miss_Mon2['seasonal_difference'].iloc[13:], lags=40, ax=ax1) 
#从13开始是因为做季节性差分时window是12
ax2 = fig.add_subplot(212)
fig = sm.graphics.tsa.plot_pacf(Mauna_Loa_CO2_Miss_Mon2['seasonal_difference'].iloc[13:], lags=40, ax=ax2)




import warnings
import itertools
import numpy as np

import pandas as pd
p = d = q = range(0, 2)
pdq = list(itertools.product(p, d, q))
seasonal_pdq = [(x[0], x[1], x[2], 12) 
for x in list(itertools.product(p, d, q))]
warnings.filterwarnings("ignore") 
# specify to ignore warning messages
AIC_Value = []
for param in pdq:
    for param_seasonal in seasonal_pdq:
        try:
            mod = sm.tsa.statespace.SARIMAX(Mauna_Loa_CO2_Miss_Mon2['co2'],
                                            order=param,
                                            seasonal_order=param_seasonal,
                                            enforce_stationarity=False,
                                            enforce_invertibility=False)
            results = mod.fit()
            AIC_Value.append(results.aic)
            print('ARIMA{}x{}12 - AIC:{}'.format(param, param_seasonal, results.aic))
        except:
            continue


7.模型结果



mod = sm.tsa.statespace.SARIMAX(Mauna_Loa_CO2_Miss_Mon2['co2'],
                                order=(1, 1, 1),
                                seasonal_order=(1, 1, 1, 12),
                                enforce_stationarity=False,
                                enforce_invertibility=False)
results = mod.fit()
print(results.summary().tables[1])




results.plot_diagnostics(figsize=(15, 12))
plt.show()




pred = results.get_prediction(start=pd.to_datetime('1995-01-01'), dynamic=False)
pred_ci = pred.conf_int()
ax = Mauna_Loa_CO2_Miss_Mon2['1990':].plot(label='observed')
ax.set_ylim(350, 380)
pred.predicted_mean.plot(ax=ax, label='One-step ahead Forecast', alpha=.7)
ax.fill_between(pred_ci.index,
                pred_ci.iloc[:, 0],
                pred_ci.iloc[:, 1], color='r', alpha=.9)
ax.set_xlabel('Date')
ax.set_ylabel('CO2 Levels')
plt.legend()
plt.show()


8.总结

残差图的分布基本为标准正态分布,拟合残差基本为白噪音,其拟合效果比较好。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,639评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,277评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,221评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,474评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,570评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,816评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,957评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,718评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,176评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,511评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,646评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,322评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,934评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,755评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,987评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,358评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,514评论 2 348

推荐阅读更多精彩内容