Python时间序列分析纯新手教程
时间序列分析是一种用于研究和预测时间序列数据的统计学方法,通常进行时间序列分析需要以下步骤:
1.确定分析目的和数据范围:首先需要明确进行时间序列分析的目的和分析的数据范围,例如分析某个地区的气温变化趋势,需要收集的时间序列数据范围可以是数年或者数十年。
2.数据采集和处理:收集相应时间序列数据,并进行必要的数据清洗和预处理,例如去除异常值、缺失值等。
3.时序图观察:绘制时序图,对数据的基本特征和趋势进行初步观察和分析,如检查数据是否平稳、趋势是否存在等。
4.时间序列分解:将时间序列数据分解为长期趋势、季节性变化和随机波动等不同成分,以便更好地了解数据的基本特征和规律。
5.模型建立:根据数据的特点和分析目的选择合适的时间序列模型,例如ARIMA模型、季节性ARIMA模型、指数平滑模型等。
6.模型诊断和验证:对建立好的模型进行检验和评估,检查其拟合效果和预测精度,并对模型进行必要的修正和优化。
7.预测和应用:利用已经建立好的模型对未来的时间序列数据进行预测和应用,例如可以预测未来的趋势、周期性变化和随机波动等,也可以进行决策支持和风险评估等。
#寻找数据:
如果自己手上没有可以分析的相关数据,考虑从以下渠道获取:
1.厂商:如果相关课题使用的是商业机械、用具,可以向制造商或供应商请求相关的数据。通常,制造商会在其官方网站上提供相应的技术文档;
2.研究论文:可以在学术数据库(如Google Scholar或PubMed)中查找有关研究论文;
3.开放数据集:有些组织或研究机构会公开发布数据集供研究使用;
4.实验室测试:如果具有实验室资源,可以自己进行实验,收集所需数据。请注意使用一些标准化测试方法,以确保数据的可比性和可重复性。
我参考的是开源网站kaggle(Kaggle: Your Machine Learning and Data Science Community)的数据集。
ref:https://www.kaggle.com/datasets/rohanrao/nifty50-stock-market-data
数据是印度NSE NIFTY 50 指数中 50 只股票的历史价格和交易量。所有数据集都是按天计算的,每只股票的定价和交易价值都分布在 .cvs 文件中,还有一个元数据文件,其中包含一些关于股票本身的宏观信息。
#数据导入
# Data and package Import
#Data Source - Kaggle - https://www.kaggle.com/rohanrao/nifty50-stock-market-data
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.arima_model import ARMA
TempData = pd.read_csv('HCLTECH.csv')
TempData.head(30)
上述代码用于导入需要使用的Python包和数据。首先使用pandas
库导入pd
别名,matplotlib
库导入plt
别名,以及statsmodels
库中的ARMA
模型。然后使用pd.read_csv()
函数读取名为HCLTECH.csv
的数据文件,并将其存储到名为TempData
的数据框中。
Pandas是一个开源的Python库,提供了高性能、易于使用的数据结构和数据分析工具。它主要用于处理和分析结构化数据,如表格、时间序列等。Pandas提供两种主要数据结构:Series和DataFrame。Series是一种类似于数组的数据结构,它只有一列数据和一个索引。DataFrame是一个类似于表格的数据结构,它有多行多列的数据,每列可以有不同的数据类型,并且也有一个行索引和列索引。使用Pandas可以轻松地读取、写入和处理各种文件格式的数据,如CSV、Excel、SQL数据库等。它也提供了强大的数据操作功能,如切片、筛选、聚合、重塑等。Pandas还支持对数据进行可视化处理,可以使用Matplotlib等可视化库进行数据可视化。
Statsmodels是一个Python库,它提供了各种统计模型和数据分析工具,包括线性回归、时间序列分析、非参数方法、最大似然估计、广义线性模型等。Statsmodels主要用于统计分析、建模和预测等方面的工作,可以帮助用户对数据进行探索性分析、建立模型、进行推断和预测。它提供了多种模型,包括线性回归、逻辑回归、时间序列分析、ARIMA、VAR等等。此外,Statsmodels还提供了多种统计方法,如假设检验、方差分析、协方差分析等。Statsmodels的优点是具有良好的文档、易于学习和使用,并且提供了丰富的统计模型和分析工具,可以帮助用户完成从数据分析到建模和预测的全过程。它还可以和NumPy、Pandas、Matplotlib等其他Python库进行配合使用,提供更为完整和灵活的数据分析和可视化功能。
#数据清洗
#Data Cleaning
HCLTechStockData = TempData.dropna()
HCLTechStockData.index = pd.to_datetime(HCLTechStockData.Date)
HCLTechStockData = HCLTechStockData["Prev Close"]['2013-01-01':'2013-10-2']
HCLTechStockData.describe()
上述代码包括三个步骤:首先,使用dropna()
函数删除数据框TempData
中的所有缺失值,并将处理后的数据存储在名为HCLTechStockData
的新数据框中。接着,使用pd.to_datetime()
方法将HCLTechStockData
数据框中的Date
列转换为时间戳,并将其作为新的索引。拉取CVS表格中从2013年1月1日到2013年10月2日之间的Prev Close
列,并将其存储在HCLTechStockData
数据框中,使用describe()
输出HCLTechStockData
数据框中的统计信息。得到分析数据的样本数量,平均值,标准差等如下图。这些数据有助于快速了解数据的分布和统计特征,以便更好地进行数据预处理和分析。得到结果如下:
#绘制时序线形图
#Data Exploration
plt.figure(figsize=(16,7))
fig = plt.figure(1)
ax1 = fig.add_subplot(111)
ax1.set_xlabel('Time Frame')
ax1.set_ylabel('Stock Price for HCLTECH')
ax1.plot(HCLTechStockData)
通常情况下,时间序列线形图可以显示以下信息:
-
股票价格的变化趋势:时间序列线形图可以展示股票价格随时间的变化趋势,因此我们可以了解到该股票的价格变化是上涨、下跌还是波动较为剧烈。
-
高低价格区间:时间序列线形图上的纵坐标表示价格,因此我们可以直观地了解到该股票的价格区间范围,以及价格的高低情况。
-
可能的趋势和周期:时间序列线形图还可以显示可能的趋势和周期,从而帮助我们判断该股票的走势是否存在一定的周期性或趋势性。
-
价格波动的大小:通过观察时间序列线形图上的价格波动情况,我们可以了解到该股票价格波动的大小和频率,以及波动的原因和影响因素。
#数据处理
# Checking stationarity
# Method 1 - Rolling Statistics
# Method 2 - Duckey fuller
#Determing rolling statistics
rolLmean = HCLTechStockData.rolling(12).mean()
rolLstd = HCLTechStockData.rolling(12).std()
plt.figure(figsize=(16,7))
fig = plt.figure(1)
#Plot rolling statistics:
orig = plt.plot(HCLTechStockData, color='blue',label='Original')
mean = plt.plot(rolLmean, color='red', label='Rolling Mean')
std = plt.plot(rolLstd, color='black', label = 'Rolling Std')
plt.legend(loc='best')
plt.title('Rolling Mean & Standard Deviation')
plt.show(block=False)
# making Series Stationary
#Transformation
plt.figure(figsize=(16,7))
fig = plt.figure(1)
import numpy as np
ts_log = np.log(HCLTechStockData)
plt.plot(ts_log)
通过 Pandas 库中的 rolling() 函数确定上述数据的滚动统计信息,时间序列数据中的滚动统计信息是指在一定时间窗口内计算出的数据的统计信息。这种统计方法通常用于分析时间序列数据的趋势和周期性,并且可以提供更加稳定的数据分析结果。其次,为了处理数据的非线性特征,以及减小数据的波动性,进而提高预测的准确性,对上述时间序列数据进行对数变换。
#Decomposition 序列分解
from statsmodels.tsa.seasonal import seasonal_decompose
decomposition = seasonal_decompose(ts_log,period=1,model = 'multiplicative')
trend = decomposition.trend
seasonal = decomposition.seasonal
residual = decomposition.resid
plt.figure(figsize=(16,7))
fig = plt.figure(1)
plt.subplot(411)
plt.plot(ts_log, label='Original')
plt.legend(loc='best')
plt.subplot(412)
plt.plot(trend, label='Trend')
plt.legend(loc='best')
plt.subplot(413)
plt.plot(seasonal,label='Seasonality')
plt.legend(loc='best')
plt.subplot(414)
plt.plot(residual, label='Residuals')
plt.legend(loc='best')
上述代码的作用是将时间序列分解为趋势、季节性和残差三个部分,对时间序列进行分解,分解为趋势、季节性和残差是为了更好地理解和描述时间序列数据的结构和特征。具体来说,时间序列可以分解为三个部分:
-
趋势:时间序列在长期内的变化趋势,例如上升或下降趋势。趋势反映了时间序列的长期趋势和基本走势,可以帮助我们了解时间序列的增长或下降规律。
-
季节性:时间序列在周期性变化中的规律性,例如每年的季节性变化或者每周的周期性变化。季节性反映了时间序列在短期内的波动规律,可以帮助我们了解时间序列在不同时间段内的表现。
-
残差:时间序列除趋势和季节性成分外的随机波动部分。残差反映了时间序列在趋势和季节性影响下的剩余波动,可以帮助我们了解时间序列中随机波动的性质和大小。
通过将时间序列分解为趋势、季节性和残差三个部分,可以更好地分析和预测时间序列的行为和特征,例如判断时间序列的长期趋势、周期性变化和波动幅度等。此外,对时间序列进行分解还可以帮助我们更好地理解时间序列的结构和性质,为进一步的数据分析和建模提供基础。
# differencing 对数据进行一阶差分
plt.figure(figsize=(16,7))
fig = plt.figure(1)
ts_log_diff = ts_log - ts_log.shift()
plt.plot(ts_log_diff)
#Determing rolling statistics
rolLmean = ts_log_diff.rolling(12).mean()
rolLstd = ts_log_diff.rolling(12).std()
#Plot rolling statistics:
orig = plt.plot(ts_log_diff, color='blue',label='Original')
mean = plt.plot(rolLmean, color='red', label='Rolling Mean')
std = plt.plot(rolLstd, color='black', label = 'Rolling Std')
plt.legend(loc='best')
plt.title('Rolling Mean & Standard Deviation')
plt.show(block=False)
为了更好地理解时间序列的趋势和波动情况,绘制一阶差分序列和滚动均值、滚动标准差的图形,对原始时间序列进行一阶差分处理的主要目的是为了消除趋势性,并更好地揭示数据中的周期性和季节性。具体而言,一阶差分可以通过计算相邻时间点之间的差异来消除数据中的趋势成分。对原始时间序列进行一阶差分可以更好地捕捉到数据中的周期性和季节性,使得数据更加平稳,一阶差分处理是时间序列预处理中常用的一种方法。
#计算自相关函数(ACF)和偏自相关函数(PACF)
HCLTechStockData.sort_index(inplace= True)
from statsmodels.tsa.stattools import acf, pacf
lag_acf = acf(ts_log_diff, nlags=20)
lag_pacf = pacf(ts_log_diff, nlags=20)
import statsmodels.api as sm
fig = plt.figure(figsize=(12,8))
ax1 = fig.add_subplot(211)
fig = sm.graphics.tsa.plot_acf(ts_log_diff.dropna(),lags=40,ax=ax1)
ax2 = fig.add_subplot(212)
fig = sm.graphics.tsa.plot_pacf(ts_log_diff.dropna(),lags=40,ax=ax2)
对一阶差分后的时间序列进行自相关函数(ACF)和偏自相关函数(PACF)的计算是为了识别适合的自回归移动平均(ARMA)模型,并用于进行时间序列预测。具体而言,ACF和PACF是用来识别时间序列数据中的自相关和偏自相关性质的。自相关函数(ACF)是一个反映时间序列与其自身滞后版本之间关系的统计量。ACF可以告诉我们一个滞后时间点和其后续滞后时间点之间的相关性。通过ACF,我们可以看到时间序列中不同滞后期的自相关性,这可以帮助我们判断时间序列是否存在自相关性。如果时间序列存在自相关性,我们可以考虑使用自回归模型(AR模型)进行建模。偏自相关函数(PACF)是一个反映时间序列在移除其它变量影响后与其自身滞后版本之间关系的统计量。PACF可以帮助我们识别时间序列中的偏自相关性质,也就是在已经考虑了其它变量的影响后,两个滞后时间点之间的相关性。通过PACF,我们可以看到时间序列在考虑其它变量影响后,不同滞后期的偏自相关性。如果时间序列存在偏自相关性,我们可以考虑使用移动平均模型(MA模型)进行建模。
#建立模型、预测、修正
#建立ARIMA模型
#from statsmodels.tsa.arima_model import ARIMA
from statsmodels.tsa.arima.model import ARIMA
type(ts_log_diff)
#ts_log_diff.dropna()
ts_log_diff = ts_log_diff[~ts_log_diff.isnull()]
plt.figure(figsize=(16,8))
#ts_log_diff.dropna(inplace=True)
model = ARIMA(ts_log_diff, order=(0,1,0))
results_ARIMA = model.fit()
plt.plot(ts_log_diff)
plt.plot(results_ARIMA.fittedvalues, color='red')
#模型拟合 预测
ARIMA_diff_predictions = pd.Series(results_ARIMA.fittedvalues, copy=True)
print(ARIMA_diff_predictions.head())
ARIMA_diff_predictions_cumsum = ARIMA_diff_predictions.cumsum()
print(ARIMA_diff_predictions_cumsum.head())
ARIMA_log_prediction = pd.Series(ts_log.iloc[0], index=ts_log.index)
ARIMA_log_prediction = ARIMA_log_prediction.add(ARIMA_diff_predictions_cumsum,fill_value=0)
ARIMA_log_prediction.head()
plt.figure(figsize=(12,8))
predictions_ARIMA = np.exp(ARIMA_log_prediction)
plt.plot(HCLTechStockData)
plt.plot(predictions_ARIMA)
plt.title('RMSE: %.4f'% np.sqrt(sum((predictions_ARIMA-HCLTechStockData)**2)/len(HCLTechStockData)))
ARIMA 模型中包括 AR(p)、MA(q) 和差分(d) 三个参数,分别表示自回归阶数、移动平均阶数和差分次数。ARIMA 模型通常用于处理平稳和非平稳时间序列,并具有较高的准确性。 AR 阶数 p=2、差分阶数 d=1、MA 阶数 q=2,原始的时间序列为蓝色,ARIMA 模型的拟合值为红色。
从上述两张图可以看出,预测趋势基本满足,但是一些剧烈的波动并未全部反应出来,均方根误差也较大,考虑对模型进行修正。
可参考的修正方法:1.调整模型参数:ARIMA模型的参数包括AR和MA的阶数,以及差分次数等。通过调整这些参数,可以改善模型的拟合效果。通常可以使用网格搜索等方法来确定最优参数组合。2.增加历史数据:ARIMA模型的预测精度往往受到历史数据的影响。如果历史数据不足或者与未来数据有较大的差异,就会影响ARIMA模型的预测精度。因此,可以尝试增加历史数据,以提高ARIMA模型的预测精度。3.增加外部变量:ARIMA模型是一种时间序列模型,往往无法考虑到其他外部变量的影响。如果预测目标受到其他因素的影响,可以增加外部变量来提高ARIMA模型的预测精度。4.使用其他模型:如果ARIMA模型的预测精度仍然较低,可以尝试使用其他的时间序列模型或者机器学习模型来进行预测,如VAR、LSTM等。这些模型可以考虑到更多的因素,从而提高预测精度。
这里采用网格搜索的方法,使用pmdarima库中的auto_arima函数自动拟合ARIMA模型来对输入的时间序列进行建模,得到最适合数据的模型。
显示(0,1,0)为最佳参数,但是已经不属于 ARIMA模型,考虑数据跨度过大问题:纵坐标700-1100,实际上应该是数据的单位选择还有调整的空间,需要进一步讨论。
以上,是我时序作业的流水账记录。
参考:https://www.youtube.com/watch?v=MVsKaYzEggY
作者:lmyuuuu