基于 Python 股票时间序列分析与股价预测(可视化 + 线性回归 + ARIMA)
·
一、项目简介
本文利用Python对股票历史行情数据进行时间序列分析,完成数据清洗、多维度可视化(均线走势、K 线图、成交量、涨跌幅分布),并分别使用线性回归、ARIMA 时间序列模型实现收盘价预测,对比两种模型效果。
环境:Jupyter Notebook / Python 3.8+ 数据源:本地 Excel 股票行情数据(包含日期、开盘价、收盘价、最高价、最低价、成交量、涨跌幅、5/10/20 日均线等字段)
二、环境依赖安装
运行代码前,先安装所需第三方库,复制执行:
bash
运行
# 数据分析、绘图、Excel读取
pip install pandas numpy matplotlib openpyxl
# 交互式K线图
pip install pyecharts
# 机器学习、时间序列模型
pip install scikit-learn statsmodels
三、完整代码实现
3.1 导入库 + 读取并预处理数据
解决 Matplotlib 中文乱码、负号显示问题,读取 Excel 数据并做日期转换、排序、字段筛选。
python
运行
# 导入数据分析与绘图库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 解决图表中文、负号显示异常
plt.rcParams["font.family"] = "SimHei"
plt.rcParams["axes.unicode_minus"] = False
# 读取Excel股票数据(修改为你的文件路径)
df = pd.read_excel("D:\LXY\股价数据.xlsx")
# 查看前5行数据
df.head()
# 查看数据基本信息、缺失值
df.info()
df.isnull().sum()
# 1. 将日期列转为标准时间格式
df['date'] = pd.to_datetime(df['date'])
# 2. 按时间升序排序(时间序列必须保证时序正确)
df.sort_values(by='date', inplace=True)
# 3. 保留核心分析字段
df = df[['date', 'open', 'close', 'high', 'low', 'volume', 'p_change', 'ma5', 'ma10', 'ma20']]
# 4. 重置索引
df.reset_index(drop=True, inplace=True)
df.head()
3.2 绘制收盘价 + 5/10/20 日均线走势图
直观查看股价整体走势与均线趋势:
python
运行
plt.figure(figsize=(14,6))
# 绘制收盘价与三条均线
plt.plot(df['date'], df['close'], label='收盘价')
plt.plot(df['date'], df['ma5'], label='5日均线', linestyle='--')
plt.plot(df['date'], df['ma10'], label='10日均线', linestyle='--')
plt.plot(df['date'], df['ma20'], label='20日均线', linestyle='--')
# 图表美化
plt.grid(alpha=0.3)
plt.legend()
plt.title('收盘价与均线')
plt.show()
3.3 基于 pyecharts 绘制交互式 K 线图
K 线是股票分析核心图表,支持缩放、下载、还原等交互操作:
python
运行
from pyecharts.charts import Kline
from pyecharts import options as opts
# 构造K线数据:[开盘, 收盘, 最高, 最低]
y = df[['open','close','high','low']].values.tolist()
# 构建K线图
kline = (
Kline()
.add_xaxis(df['date'].tolist())
.add_yaxis('K线图', y)
.set_global_opts(
title_opts=opts.TitleOpts(title='股票K线图'),
toolbox_opts=opts.ToolboxOpts(is_show=True) # 开启工具箱
)
)
# Jupyter中直接展示;普通py文件使用 kline.render("股票K线图.html")
kline.render_notebook()
3.4 绘制成交量柱状图
分析成交量变化规律:
python
运行
plt.figure(figsize=(14,6))
plt.bar(df['date'], df['volume'])
plt.title('成交量柱状图')
plt.show()
3.5 绘制涨跌幅分布直方图
统计每日涨跌幅分布,红色虚线区分涨跌分界:
python
运行
plt.figure(figsize=(14,6))
# 绘制涨跌幅直方图,分为40个区间
plt.hist(df['p_change'], bins=40)
# 绘制涨跌分界线(0轴)
plt.axvline(0, color='red', linestyle='--', label='跌涨分界线')
plt.legend()
plt.title('涨跌幅直方图')
plt.show()
3.6 构造特征 + 划分训练集 / 测试集
构建滞后特征(前一日收盘价),按照时间顺序划分数据集(时序数据禁止随机打乱):
python
运行
# 构造滞后特征:前一日收盘价
df["close_lag1"] = df["close"].shift(1)
# 删除因偏移产生的空值
df = df.dropna()
# 按8:2划分训练集、测试集
split = int(len(df) * 0.8)
train = df.iloc[:split]
test = df.iloc[split:]
# 定义特征列与预测标签
feature_cols = ["close_lag1", "open", "ma5"]
X_train = train[feature_cols]
y_train = train["close"]
X_test = test[feature_cols]
y_test = test["close"]
# 输出数据集大小
print(f"训练集: {len(train)} 条 | 测试集: {len(test)} 条")
3.7 模型评估通用函数
封装 MAE、RMSE、R² 三大回归评价指标,复用至两个模型:
python
运行
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
def eval_model(y_true, y_pred):
"""模型评估函数"""
mae = mean_absolute_error(y_true, y_pred)
rmse = np.sqrt(mean_squared_error(y_true, y_pred))
r2 = r2_score(y_true, y_pred)
print(f"MAE(平均绝对误差): {mae:.2f}")
print(f"RMSE(均方根误差): {rmse:.2f}")
print(f"R²(拟合度): {r2:.2f}")
3.8 线性回归模型预测股价
使用线性回归做收盘价预测,并可视化真实值与预测值:
python
运行
from sklearn.linear_model import LinearRegression
# 初始化并训练模型
lr = LinearRegression()
lr.fit(X_train, y_train)
# 测试集预测
y_pred_lr = lr.predict(X_test)
# 模型评估
print("==== 线性回归模型评估 ====")
eval_model(y_test, y_pred_lr)
# 可视化:真实值 VS 预测值
plt.figure(figsize=(14, 6))
plt.plot(test["date"], y_test, label="真实收盘价", linewidth=2)
plt.plot(test["date"], y_pred_lr, label="线性回归预测", linestyle="--")
plt.title("线性回归预测结果")
plt.xlabel("日期")
plt.ylabel("股价")
plt.legend()
plt.grid(alpha=0.3)
plt.show()
3.9 ARIMA 时间序列模型滚动预测
采用滚动一步预测方式,适配经典时间序列预测场景:
python
运行
from statsmodels.tsa.arima.model import ARIMA
# 初始化历史数据与预测列表
history = list(train["close"])
predictions = []
# 滚动预测:逐行预测,动态更新历史数据
for i in range(len(test)):
# ARIMA(p,d,q) = (10,1,0)
model = ARIMA(history, order=(10,1,0))
model_fit = model.fit()
# 预测未来1个时间步
yhat = model_fit.forecast()[0]
predictions.append(yhat)
# 将当日真实值加入历史数据集
history.append(test["close"].iloc[i])
# 转为数组
y_pred_arima = np.array(predictions)
# 模型评估
print("\n==== ARIMA模型评估 ====")
eval_model(y_test, y_pred_arima)
# 可视化ARIMA预测效果
plt.figure(figsize=(14, 6))
plt.plot(test["date"], y_test, label="真实收盘价", linewidth=2)
plt.plot(test["date"], y_pred_arima, label="ARIMA预测", linestyle="--", color="orange")
plt.title("ARIMA时间序列预测结果")
plt.xlabel("日期")
plt.ylabel("股价")
plt.legend()
plt.grid(alpha=0.3)
plt.show()
四、结果分析
-
数据可视化
- 均线图可清晰观察短期、中期、长期股价趋势;
- K 线图支持交互式查看单日行情,是股票分析主流图表;
- 成交量与涨跌幅分布可以辅助判断市场活跃度与涨跌规律。
-
模型效果对比
- 线性回归:MAE、RMSE 更低,R² 接近 0.98,拟合效果优秀,运算速度快;
- ARIMA 模型:纯基于历史收盘价做时序预测,R² 为 0.97,效果略逊于线性回归,单步滚动预测耗时更长。
-
总结 针对该股票数据集,结合多特征的线性回归预测表现更优;纯时序 ARIMA 模型适合仅依赖历史序列、无额外特征的场景。
更多推荐
所有评论(0)