全国大学生数学建模比赛中,时间序列分析是一种重要的方法。以下是对时间序列在该比赛中的详细解读:
一、时间序列的概念
时间序列是按时间顺序排列的一组数据。在数学建模中,时间序列数据通常反映了某个现象随时间的变化情况。例如,股票价格的历史数据、气温的逐天记录、销售额的逐月数据等都是时间序列。
二、时间序列分析的目的
- 预测未来值:通过对历史数据的分析,建立合适的模型来预测未来的时间序列值。这在很多实际问题中都非常重要,比如预测产品的销售量、股票价格走势等。
- 了解数据的特征:分析时间序列的趋势、季节性、周期性等特征,以便更好地理解所研究的现象。
- 评估模型的有效性:通过对模型的评估,确定其在预测和解释时间序列数据方面的准确性和可靠性。
三、时间序列分析的步骤
-
数据收集与预处理
- 收集相关的时间序列数据,并进行初步的检查和清理,确保数据的准确性和完整性。
- 可能需要对数据进行平稳化处理,去除趋势和季节性等因素,以便更好地进行建模。
-
模型选择与建立
- 根据时间序列的特征和问题的要求,选择合适的时间序列模型。常见的模型包括自回归模型(AR)、移动平均模型(MA)、自回归移动平均模型(ARMA)、自回归积分移动平均模型(ARIMA)等。
- 确定模型的参数,可以通过最小二乘法、极大似然估计等方法进行估计。
-
模型评估与诊断
- 对建立的模型进行评估,常用的评估指标包括均方根误差(RMSE)、平均绝对误差(MAE)、平均绝对百分比误差(MAPE)等。
- 进行模型诊断,检查模型是否满足假设条件,如残差是否为白噪声等。
-
预测与应用
- 使用经过评估和诊断的模型进行预测,得到未来时间序列的值。
- 根据预测结果,为实际问题提供决策支持。
四、时间序列分析的注意事项
- 数据质量:确保时间序列数据的质量是进行有效分析的基础。要注意数据的准确性、完整性和一致性。
- 模型选择:不同的时间序列模型适用于不同的情况,要根据数据的特征和问题的要求选择合适的模型。
- 模型假设:在建立时间序列模型时,要注意模型的假设条件,并进行适当的诊断和检验。
- 预测局限性:时间序列预测存在一定的局限性,预测结果只是基于历史数据的一种估计,实际情况可能会发生变化。
- 结果解释:对时间序列分析的结果要进行合理的解释,结合实际问题的背景和知识,避免单纯依赖数学模型。
数据例样:
"Month","Sales" "1-01",266.0 "1-02",145.9 "1-03",183.1 "1-04",119.3 "1-05",180.3 "1-06",168.5 "1-07",231.8 "1-08",224.5 "1-09",192.8 "1-10",122.9 "1-11",336.5 "1-12",185.9 "2-01",194.3 "2-02",149.5 "2-03",210.1 "2-04",273.3 "2-05",191.4 "2-06",287.0 "2-07",226.0 "2-08",303.6 "2-09",289.9 "2-10",421.6 "2-11",264.5 "2-12",342.3 "3-01",339.7 "3-02",440.4 "3-03",315.9 "3-04",439.3 "3-05",401.3 "3-06",437.4 "3-07",575.5 "3-08",407.6 "3-09",682.0 "3-10",475.3 "3-11",581.3 "3-12",646.9
分析代码:
一、数据读取与预处理
data = pd.read_csv('shampoo.csv')
data['Month'] = pd.to_datetime(data['Month'], format='%m-%d')
data['Month'] = pd.to_datetime(data['Month'], format='%y-%m', yearfirst=True).dt.strftime('2024-%m')
print(data)
data.set_index('Month', inplace=True)
这段代码首先从 “shampoo.csv” 文件中读取数据并存储在data
这个DataFrame
中。然后对 “Month” 列进行两次格式转换,第一次将其转为日期类型,第二次将格式转换为 “2024-% m” 的形式,并将 “Month” 列设置为索引,方便后续基于时间的操作。
二、绘制原始时序图及平稳性检测
- 绘制时序图
data.plot(figsize=(10, 6))
plt.xlabel('Month')
plt.ylabel('Sales')
plt.title('Time Series of Sales')
plt.show()
通过调用data.plot()
绘制了原始数据的时序图,设置了图形的大小为(10, 6)
,并添加了横轴标签 “Month”、纵轴标签 “Sales” 和标题 “Time Series of Sales”,最后显示图形,以便直观地观察销售额随时间的变化情况。
- 绘制自相关图和偏相关图
plot_acf(data, lags=9)
plt.title('Autocorrelation Plot')
plt.show()plot_pacf(data, lags=9)
plt.title('Partial Autocorrelation Plot')
plt.show()
分别绘制了原始数据的自相关图和偏相关图,设置滞后阶数为 9,通过这两个图可以初步分析时间序列的自相关性和偏自相关性,为选择合适的时间序列模型提供参考。
- ADF 检验
adf_result = adfuller(data['Sales'])
print('ADF Statistic:', adf_result[0])
print('p-value:', adf_result[1])
print('Critical Values:', adf_result[4])
进行了 ADF(Augmented Dickey-Fuller)检验,以判断原始时间序列数据的平稳性。输出了检验统计量、p 值和临界值,通常如果 p 值小于一定的显著性水平(如 0.05),则可以认为序列是平稳的。
三、差分处理及再次检测平稳性
- 差分处理
diff_data = data.diff().dropna()
对原始数据进行一阶差分处理,并去除产生的缺失值。差分可以消除时间序列中的趋势和季节性,使序列更趋于平稳。
- 绘制差分后的时序图
diff_data.plot(figsize=(10, 6))
plt.xlabel('Month')
plt.ylabel('Sales (Differenced)')
plt.title('Differenced Time Series of Sales')
plt.show()
绘制差分后数据的时序图,观察差分后的序列变化情况,此时的纵轴标签变为 “Sales (Differenced)”,标题也相应地变为 “Differenced Time Series of Sales”。
- 绘制差分后的自相关图和偏相关图
plot_acf(diff_data, lags=9)
plt.title('Autocorrelation Plot (Differenced)')
plt.show()plot_pacf(diff_data, lags=9)
plt.title('Partial Autocorrelation Plot (Differenced)')
plt.show()
再次绘制差分后数据的自相关图和偏相关图,以进一步分析差分后序列的相关性特征。
- ADF 检验(差分后)
adf_result_diff = adfuller(diff_data['Sales'])
print('ADF Statistic (Differenced):', adf_result_diff[0])
print('p-value (Differenced):', adf_result_diff[1])
print('Critical Values (Differenced):', adf_result_diff[4])
对差分后的序列进行 ADF 检验,确认差分后的序列是否平稳。输出了差分后的检验统计量、p 值和临界值。
四、使用 ARIMA 模型建模与预测
- 建模
model = ARIMA(data, order=(1, 1, 1))
model_fit = model.fit()
使用ARIMA
模型对原始数据进行建模,指定模型的阶数为(1, 1, 1)
,即自回归阶数为 1、差分阶数为 1、移动平均阶数为 1。然后对模型进行拟合。
- 打印模型概要信息
print(model_fit.summary())
输出模型的概要信息,包括模型的参数估计、标准误差、t 值、p 值等,这些信息可以帮助评估模型的有效性和可靠性。
- 预测未来销售额
forecast_steps = 5
forecast = model_fit.forecast(steps=5)
last_month = data.index[-1]
future_months = pd.date_range(start=last_month, periods=forecast_steps + 1, freq='M')[1:]
forecast_df = pd.DataFrame({'Month': future_months, 'Forecasted Sales': forecast})
print('Forecasted Sales for the next 5 months:')
print(forecast_df)
设置要预测的未来步数为 5,使用拟合好的模型进行预测,得到未来 5 个月的销售额预测值。然后生成未来几个月的日期,创建一个包含日期和预测销售额的DataFrame
,最后输出预测结果,为决策提供参考。
完整代码:
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.tsa.arima.model import ARIMA
import io
# 读取数据并进行预处理
# 将字符串转换为DataFrame
data = pd.read_csv('shampoo.csv')# 将'Month'列转换为日期类型
data['Month'] = pd.to_datetime(data['Month'], format='%m-%d')
# 将'Month'列转换为日期类型,并设置年份为2024年
data['Month'] = pd.to_datetime(data['Month'], format='%y-%m', yearfirst=True).dt.strftime('2024-%m')
print(data)
# 将日期列设置为索引
data.set_index('Month', inplace=True)# 绘制时序图
data.plot(figsize=(10, 6))
plt.xlabel('Month')
plt.ylabel('Sales')
plt.title('Time Series of Sales')
plt.show()# 检测序列的平稳性
# 自相关图
plot_acf(data, lags=9)
plt.title('Autocorrelation Plot')
plt.show()# 偏相关图
plot_pacf(data, lags=9)
plt.title('Partial Autocorrelation Plot')
plt.show()# ADF检验
adf_result = adfuller(data['Sales'])
print('ADF Statistic:', adf_result[0])
print('p-value:', adf_result[1])
print('Critical Values:', adf_result[4])# 差分处理
diff_data = data.diff().dropna()# 绘制差分后的时序图
diff_data.plot(figsize=(10, 6))
plt.xlabel('Month')
plt.ylabel('Sales (Differenced)')
plt.title('Differenced Time Series of Sales')
plt.show()# 差分后的序列平稳性检测
# 自相关图
plot_acf(diff_data, lags=9)
plt.title('Autocorrelation Plot (Differenced)')
plt.show()# 偏相关图
plot_pacf(diff_data, lags=9)
plt.title('Partial Autocorrelation Plot (Differenced)')
plt.show()# ADF检验
adf_result_diff = adfuller(diff_data['Sales'])
print('ADF Statistic (Differenced):', adf_result_diff[0])
print('p-value (Differenced):', adf_result_diff[1])
print('Critical Values (Differenced):', adf_result_diff[4])# 使用ARIMA模型建模
model = ARIMA(data, order=(1, 1, 1))
model_fit = model.fit()# 打印模型的概要信息
print(model_fit.summary())# 预测未来5个月的销售额
forecast_steps = 5
forecast = model_fit.forecast(steps=5)
# 生成未来几个月的日期
last_month = data.index[-1]
future_months = pd.date_range(start=last_month, periods=forecast_steps + 1, freq='M')[1:]# 创建包含日期和预测销售额的DataFrame
forecast_df = pd.DataFrame({'Month': future_months, 'Forecasted Sales': forecast})# 输出预测结果
print('Forecasted Sales for the next 5 months:')
print(forecast_df)