用ARIMA预测股票价格:Python实现与性能评估
创作时间:
2025-01-21 23:14:07
作者:
@小白创作中心
用ARIMA预测股票价格:Python实现与性能评估
时间序列预测在金融领域中具有重要意义,尤其是在股票价格的预测上。本文以 ARIMA 模型为例,探讨如何基于历史数据对股票涨跌额进行预测。由于 ARIMA 模型仅适用于单变量时间序列,本教程主要针对收盘价的变化趋势进行简单预测,并通过 AIC 和 BIC 两种模型选择标准进行性能比较。本文仅适合作为入门时间序列预测的作业示例。
教程目标
- 使用 Python 中的 statsmodels 库构建 ARIMA 模型,预测股票涨跌额。
- 通过 AIC 和 BIC 指标优化模型参数(通过遍历 (p, d, q) 参数组合,使用 AIC 和 BIC 指标选择最优模型)。
- 可视化预测结果并评估模型性能。
数据准备
在本教程中,我们假设你已经有一份本地 CSV 文件,其中包含股票的历史交易数据。股票代码、交易日期和收盘价的格式如下:
股票代码,交易日期,收盘价
000001.SZ,2019-01-02,8.50
请根据自己的数据进行相应调整。
import matplotlib.pyplot as plt
import pandas as pd
from pandas.plotting import autocorrelation_plot
from pyspark.sql import SparkSession
from pyspark.sql.functions import col, to_date
from sklearn.metrics import mean_squared_error
from statsmodels.tsa.statespace.sarimax import SARIMAX
# 读取本地 CSV 文件
pandas_df = pd.read_csv("000001.SZ.csv", header=0)
# 转换 '交易日期' 为 datetime 类型并按日期排序
pandas_df['交易日期'] = pd.to_datetime(pandas_df['交易日期'], errors='coerce')
pandas_df.sort_values('交易日期', inplace=True)
# 去除空值行
pandas_df = pandas_df.dropna()
# 特征列
features = ['收盘价']
data = pandas_df[features]
ticker = "000001.SZ" # 股票代码
# 画出训练集合股价图像
plt.rcParams["figure.figsize"] = (10, 7)
plt.style.use('ggplot')
data.plot()
plt.title(f'{ticker}股票收盘价', fontsize=16)
plt.ylabel('价格(元)', fontsize=14)
plt.legend(['收盘价'], prop={ 'size': 12})
plt.show()
# 绘制自相关图
autocorrelation_plot(data)
plt.title(f'{ticker}股票收盘价自相关图', fontsize=16)
plt.ylabel('自相关系数', fontsize=14)
plt.show()
# 将数据按时间分割
train_set = data[data.index < '2020-01-01']
test_set = data[data.index >= '2020-01-01']
print(train_set)
print(test_set)
plt.figure(figsize=(10, 5)) # 调整图像大小
plt.title(f'{ticker}股票收盘价', fontsize=16) # 使用中文楷体
plt.xlabel('交易日期', fontsize=14)
plt.ylabel('价格(元)', fontsize=14)
plt.plot(train_set, color='green', label='训练集') # 添加图例标签
plt.plot(test_set, color='red', label='测试集') # 添加图例标签
plt.xlim(train_set.index.min(), test_set.index.max()) # 只显示有数据的部分
plt.legend(prop={'size': 12}) # 自动显示定义的标签,确保图例使用中文字体
plt.show()
# 优化ARIMA模型
aic_p = []
bic_p = []
params = [] # 用于存储(p, d, q)参数
p = range(0, 6) # [0,1,2,3,4,5]
d = range(0, 2) # [0,1]
q = range(0, 6) # [0,1,2,3,4,5]
# 三个循环遍历所有(p, d, q)
for i in p:
for j in d:
for k in q:
model = ARIMA(train_set, order=(i, j, k)) # define ARIMA model
model_fit = model.fit() # fit the model
aic_temp = model_fit.aic # get aic score
bic_temp = model_fit.bic # get bic score
aic_p.append(aic_temp) # append aic score
bic_p.append(bic_temp) # append bic score
params.append((i, j, k)) # 存储参数
print(f'ARIMA model p={i}, d={j}, q={k} AIC={aic_temp}, BIC={bic_temp}') # 输出所有模型的AIC和BIC评分
# 找到AIC和BIC最小值的索引
min_aic_index = aic_p.index(min(aic_p))
min_bic_index = bic_p.index(min(bic_p))
# 绘制AIC图像
plt.figure(figsize=(12, 6))
plt.plot(range(len(aic_p)), aic_p, color='red', marker='o')
plt.annotate(f'({params[min_aic_index][0]},{params[min_aic_index][1]},{params[min_aic_index][2]})',
(min_aic_index, aic_p[min_aic_index]), textcoords="offset points", xytext=(0, 10), ha='center')
plt.title('AIC优化模型图', fontsize=16)
plt.xlabel('模型参数', fontsize=14)
plt.ylabel('AIC评分', fontsize=14)
plt.show()
# 绘制BIC图像
plt.figure(figsize=(12, 6))
plt.plot(range(len(bic_p)), bic_p, color='blue', marker='o')
plt.annotate(f'({params[min_bic_index][0]},{params[min_bic_index][1]},{params[min_bic_index][2]})',
(min_bic_index, bic_p[min_bic_index]), textcoords="offset points", xytext=(0, 10), ha='center')
plt.title('BIC优化模型图', fontsize=16)
plt.xlabel('模型参数', fontsize=14)
plt.ylabel('BIC评分', fontsize=14)
plt.show()
# 获取 AIC 和 BIC 最优参数
best_aic_params = params[min_aic_index]
best_bic_params = params[min_bic_index]
# 使用 AIC 最优参数拟合模型
model_aic = ARIMA(train_set, order=best_aic_params)
model_fit_aic = model_aic.fit()
# 使用 BIC 最优参数拟合模型
model_bic = ARIMA(train_set, order=best_bic_params)
model_fit_bic = model_bic.fit()
print(f"最佳 AIC 参数: p={best_aic_params[0]}, d={best_aic_params[1]}, q={best_aic_params[2]}")
print(f"最佳 BIC 参数: p={best_bic_params[0]}, d={best_bic_params[1]}, q={best_bic_params[2]}")
# 使用 AIC 最优参数预测
predictions_aic = []
past_aic = train_set['收盘价'].tolist()
for i in range(len(test_set)):
model = ARIMA(past_aic, order=best_aic_params)
model_fit = model.fit(start_params=model_fit_aic.params)
pred = model_fit.forecast()[0]
predictions_aic.append(pred)
past_aic.append(test_set.iloc[i, 0])
# 使用 BIC 最优参数预测
predictions_bic = []
past_bic = train_set['收盘价'].tolist()
for i in range(len(test_set)):
model = ARIMA(past_bic, order=best_bic_params)
model_fit = model.fit(start_params=model_fit_bic.params)
pred = model_fit.forecast()[0]
predictions_bic.append(pred)
past_bic.append(test_set.iloc[i, 0])
# 分别评估 AIC 和 BIC 模型的性能
from sklearn.metrics import mean_absolute_error, mean_absolute_percentage_error
# AIC:
mse_aic = mean_squared_error(test_set, predictions_aic)
mae_aic = mean_absolute_error(test_set, predictions_aic)
mape_aic = mean_absolute_percentage_error(test_set, predictions_aic)
print('Test MSE: {mse}'.format(mse=mse_aic))
print('Test MAE: {mae}'.format(mae=mae_aic))
print('Test MAPE: {mape:.2%}'.format(mape=mape_aic))
# BIC:
mse_bic = mean_squared_error(test_set, predictions_bic)
mae_bic = mean_absolute_error(test_set, predictions_bic)
mape_bic = mean_absolute_percentage_error(test_set, predictions_bic)
print('Test MSE: {mse}'.format(mse=mse_bic))
print('Test MAE: {mae}'.format(mae=mae_bic))
print('Test MAPE: {mape:.2%}'.format(mape=mape_bic))
plt.figure(figsize=(12, 6))
plt.plot(test_set.index, test_set, color='green', label='实际值')
plt.plot(test_set.index, predictions_aic, color='red', label='AIC 最优预测值')
plt.plot(test_set.index, predictions_bic, color='blue', label='BIC 最优预测值')
plt.title(f'{ticker}股票预测对比', fontsize=16)
plt.xlabel('日期', fontsize=14)
plt.ylabel('价格(元)', fontsize=14)
plt.legend(prop={'size': 12})
plt.show()
结果展示
- 通过绘制收盘价和自相关图观察数据趋势:
- 通过 AIC 和 BIC 曲线直观比较不同参数组合的性能:
- 预测结果对比图:
- 使用 MSE、MAE 和 MAPE 指标评估模型效果:
总结
通过本文,上述就是如何使用 ARIMA 模型进行时间序列预测,并通过 AIC 和 BIC 指标选择最优参数。最终的预测结果展示了 ARIMA 模型的基本能力,但需要注意的是:
ARIMA 模型适用于较规则的时间序列,可能无法很好地处理股票的复杂波动。本文仅作为作业示例,实际应用中需结合更复杂的模型(如深度学习)以提高预测效果。
本文原文来自CSDN
热门推荐
3个信号,说明孩子到了身高“猛涨期”,家长别错过机会
花的结构:由花冠、花萼、花托、花蕊组成
200个好听的狗狗名字,总有一款适合你家萌宠
解放军狙击步枪系统发展轨迹
思培考试写作五大秘诀:助你轻松斩获高分
5分钟读懂数仓分层(深入浅出,通俗易懂,建议收藏)
非洲跨境电商市场潜力:新兴市场机遇与挑战
《出走的决心》:那些被困住的母亲
新韩流:周五下班来中国
有自信的女人最美麗!5個方法有效提升自信心
JS Effect Preview
Excel表格标题制作:十种实用技巧让你的工作效率翻倍
地下车位投资价值探讨:购买地下车位的必要性与实用性
光遇潜海季地图入口位置详解
葡萄生长中常见的缺素症状及解决技巧
低成本创业必读:如何选择3-5万元区间的微型小货车?
无花果种植时间与生长周期的详细介绍(了解无花果的成长规律,做好种植准备)
广州地铁26号线佛山段启动环评,顺德CBD或直达广州市中心
美联储降息将推迟?购房者如何应对通胀高压下的2025美国房产市场
房屋交房后出现质量问题应如何处理?
沿河citywalk,打卡超多景点,还有夜游彩蛋哦!
右手手相代表什么,右手相怎么看
一分为四,终于眼镜王蛇还是被分成了4个种群
橙子和桔子哪个含钾高?
详解八字命局中的不同组合及其影响
眼镜王蛇被重新划分为 4 个物种,其中一种来自西高止山脉
猫咪耳朵肿了一个大包像气球一样,该怎么办?
中国城市建成区60强出炉,最大城市不再是上海,会是哪座城市呢?
物业巡更系统助力物业管理智能化升级实现安全与服务效率的新突破
从波动到粒子再到规范场论全面了解光的多面性