前言

股票市场数据是典型的时间序列数据,价格、成交量、涨跌幅等指标随时间连续变化,背后暗藏市场波动规律。本文基于 Python 全套工具链,完成一份完整的股票数据分析项目:从数据读取、清洗预处理、多维度可视化探索,再到线性回归ARIMA两大模型搭建、效果对比,最后实现未来短期股价预测。全程附核心代码、结果解读与踩坑总结,适合数据分析入门、金融量化初学者参考学习。

一、项目整体介绍

1.1 项目目标

依托股票历史交易数据,完成全流程时间序列分析:

  1. 探查数据质量,完成数据清洗与标准化预处理;
  2. 通过折线图、K 线图、柱状图、直方图可视化股价、均线、成交量、涨跌幅分布;
  3. 搭建线性回归、ARIMA 时间序列模型对收盘价进行预测;
  4. 对比两个模型预测效果,并基于最优模型预测未来 10 个交易日股价。

1.2 开发环境与数据集

  • 开发工具:Python 3.x、Jupyter Notebook
  • 核心依赖库pandas(数据处理)、numpy(数值计算)、matplotlib(可视化)、pyecharts(交互式 K 线图)、sklearn(机器学习模型)、statsmodels(ARIMA 时间序列模型)
  • 数据集股价数据.xlsx,共 611 条交易数据,包含日期、开盘价、收盘价、最高价、最低价、成交量、涨跌幅、5/10/20 日均线等 14 个字段,数据完整无缺失值。

二、阶段一:数据导入与基础探查

数据分析第一步永远是认识数据,我们先读取数据、查看基本信息、检查缺失值,判断数据是否可用。

2.1 导入库与全局配置

绘图前提前配置字体,解决 Matplotlib 中文乱码、负号显示异常问题:

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

2.2 读取数据并基础探查

python

运行

# 读取Excel数据
df = pd.read_excel("股价数据.xlsx")

# 查看前5行数据,确认加载成功
print("数据前5行:")
print(df.head())

# 查看数据类型、行数、字段数
print("\n数据基本信息:")
df.info()

# 统计全列缺失值(判断数据质量)
print("\n各字段缺失值统计:")
print(df.isnull().sum())

2.3 结果解读

  1. 数据集共611 行 14 列date为文本类型,其余 13 个字段均为浮点型;
  2. 全字段缺失值均为 0,数据完整性良好,无需做缺失值填充;
  3. 原始数据日期为倒序排列(最新日期在前),后续需要按时间正序重排。

三、阶段二:数据预处理与特征筛选

原始股票数据存在时间格式不规范、顺序颠倒、冗余字段过多问题,必须预处理后才能用于时间序列分析。

3.1 核心预处理代码

python

运行

# 1. 将日期列转为标准datetime时间格式(时间序列必备)
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)

# 查看预处理后数据
print(df.head())

3.2 预处理说明

  1. 时间格式转换pd.to_datetime 是时间序列分析的基础,后续绘图、建模均依赖标准时间格式;
  2. 时间排序:股票时间序列要求数据按时间递增排列,否则会破坏时序逻辑,导致模型失效;
  3. 特征筛选:剔除price_changev_ma5等冗余字段,仅保留股价、成交量、涨跌幅、均线等核心指标,降低计算开销。

四、阶段三:探索性数据分析(EDA)+ 可视化

可视化是挖掘数据规律最直观的方式,本项目完成四类经典金融图表绘制,全方位解读股票走势。

4.1 收盘价与均线走势折线图

均线(MA)是股票技术分析核心指标,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.legend()
plt.title('收盘价与均线走势图')
plt.grid(alpha=0.3)
plt.show()

解读:收盘价紧贴均线波动,整体走势平稳,短期均线与中长期均线交叉频繁,反映股价存在阶段性震荡。

4.2 交互式 K 线图(pyecharts)

K 线图直观展示每日开盘、收盘、最高、最低价格,结合交互工具可缩放、查看单日详情。

python

运行

from pyecharts.charts import Kline
from pyecharts import options as opts

# 组装K线四要素:开盘、收盘、最高、最低
kline_data = df[['open', 'close', 'high', 'low']].values.tolist()

kline = (
    Kline()
    .add_xaxis(df['date'].dt.strftime('%Y-%m-%d').tolist())
    .add_yaxis("股票K线图", kline_data)
    .set_global_opts(
        title_opts=opts.TitleOpts(title="股票K线走势图"),
        toolbox_opts=opts.ToolboxOpts(is_show=True)  # 开启工具箱:下载、缩放、数据查看
    )
)
# Jupyter中直接展示图表,普通py文件使用 kline.render("kline.html")
kline.render_notebook()

4.3 成交量柱状图

成交量反映市场交易活跃度,是判断股价涨跌动能的重要依据。

python

运行

plt.figure(figsize=(14, 6))
plt.bar(df['date'], df['volume'])
plt.title('股票成交量柱状图')
plt.xlabel('日期')
plt.ylabel('成交量')
plt.xticks(rotation=45)  # 日期旋转,避免重叠
plt.show()

解读:大部分交易日成交量处于中等水平,少数交易日出现放量(柱子骤增),对应股价短期大幅波动。

4.4 涨跌幅分布直方图

统计每日涨跌幅分布,判断股票整体波动特征。

python

运行

plt.figure(figsize=(14, 6))
# 绘制涨跌幅直方图,划分40个区间
plt.hist(df['p_change'], bins=40, alpha=0.7)
# 绘制红色虚线:涨跌分界线(0轴)
plt.axvline(0, color='red', linestyle='--', label='涨跌分界线')

plt.title('股票涨跌幅分布直方图')
plt.xlabel('涨跌幅(%)')
plt.ylabel('交易日数量')
plt.legend()
plt.grid(alpha=0.3, axis='y')
plt.show()

解读:涨跌幅近似正态分布,绝大多数交易日涨跌幅集中在 0 附近,极端大涨 / 大跌天数较少,说明该股票整体波动偏温和。

五、阶段四:构建时序数据集(建模前置准备)

时间序列预测需将原始数据转为监督学习格式:用历史特征预测当日收盘价,并划分训练集、测试集。

5.1 构造滞后特征 + 数据集划分

python

运行

# 构造滞后特征:前一日收盘价(金融时序经典特征)
df["close_lag1"] = df["close"].shift(1)
# shift会产生空值,删除空行
df = df.dropna()

# 划分数据集:前80%为训练集,后20%为测试集(时序数据禁止随机划分)
split_num = int(len(df) * 0.8)
train = df.iloc[:split_num]
test = df.iloc[split_num:]

# 定义特征列与预测标签
feature_cols = ["close_lag1", "open", "ma5"]  # 特征:前一日收盘价、开盘价、5日均线
X_train = train[feature_cols]
y_train = train["close"]  # 标签:当日收盘价
X_test = test[feature_cols]
y_test = test["close"]

print(f"训练集数据量:{len(train)} 条")
print(f"测试集数据量:{len(test)} 条")

重点提醒:时间序列数据绝对不能随机划分训练集 / 测试集,必须按时间顺序切割,模拟 “用历史预测未来” 的真实场景。

六、阶段五:模型一 线性回归预测

线性回归是入门级回归模型,运算简单、可解释性强,适合作为基准模型。

6.1 模型训练、预测与评估

python

运行

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score

# 定义模型评估函数(统一计算MAE、RMSE、R²)
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}")

# 训练线性回归模型
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()

6.2 模型结果

  • MAE(平均绝对误差):0.16
  • RMSE(均方根误差):0.21
  • R²(拟合优度):0.98

解读:R² 接近 1,说明线性回归模型拟合效果极佳,预测值与真实股价偏差很小。

七、阶段六:模型二 ARIMA 时间序列模型

ARIMA 是经典专业时间序列模型,专门处理时序数据的趋势、周期性,在金融预测中应用广泛。本项目采用滚动一步预测(工业界主流用法)。

7.1 ARIMA 模型训练与预测

python

运行

from statsmodels.tsa.arima.model import ARIMA

# 初始化历史数据与预测列表
history = list(train["close"])
predictions = []

# 滚动预测:逐个预测测试集每一日股价
for i in range(len(test)):
    # 构建ARIMA模型,阶数 order=(10,1,0)
    model = ARIMA(history, order=(10, 1, 0))
    model_fit = model.fit()
    # 预测下一日股价
    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()

八、阶段七:双模型对比 + 未来 10 日股价预测

8.1 双模型效果同图对比

python

运行

plt.figure(figsize=(15, 6))
plt.plot(test["date"], y_test, label="真实收盘价", linewidth=2)
plt.plot(test["date"], y_pred_lr, label="线性回归", linestyle="--")
plt.plot(test["date"], y_pred_arima, label="ARIMA", linestyle="--", color="red")
plt.title("线性回归 & ARIMA 模型预测效果对比")
plt.legend()
plt.grid(alpha=0.3)
plt.show()

对比结论:两个模型均能精准跟随股价趋势,线性回归拟合略优,ARIMA 对小幅波动捕捉更细腻。

8.2 基于 ARIMA 预测未来 10 个交易日股价

选用 ARIMA 模型对全量数据训练,预测短期未来走势:

python

运行

# 全量收盘价数据训练模型
full_series = df["close"]
final_arima = ARIMA(full_series, order=(5, 1, 0)).fit()

# 预测未来10步(10个交易日)
future_pred = final_arima.get_forecast(steps=10).predicted_mean

# 输出预测结果
print("\n===== 未来10个交易日收盘价预测 =====")
for idx, price in enumerate(future_pred, 1):
    print(f"第{idx}天预测收盘价:{price:.2f} 元")

预测结果摘要:未来 10 日股价整体在 12.25~12.42 元区间小幅震荡,无大幅涨跌趋势。

补充说明:代码运行出现ValueWarning属于正常现象,原因是数据索引未指定时间频率,不影响预测结果

九、项目总结与经验分享

9.1 项目整体复盘

  1. 数据层面:本次股票数据质量优秀,无缺失值、无明显异常值,仅需完成时间格式转换、排序、特征筛选即可投入使用;
  2. 可视化层面:折线图、K 线图、柱状图、直方图四大图表,分别从趋势、价格区间、交易活跃度、波动分布四个维度完成数据解读,覆盖金融分析基础场景;
  3. 模型层面
    • 线性回归:简单高效、拟合度高,适合快速建模、基准对比;
    • ARIMA:专业时序模型,适配时间序列特性,滚动预测更贴合真实预测场景;
  4. 预测结论:该股票历史走势平稳,短期未来 10 个交易日以窄幅震荡为主,大涨大跌概率较低。

9.2 踩坑与避坑指南

  1. 时间序列数据禁止随机划分训练集和测试集,必须按时间顺序切割;
  2. Matplotlib 绘图务必提前配置中文字体,否则标题、图例出现乱码;
  3. 使用shift()构造滞后特征后,必须删除空值,否则模型报错;
  4. ARIMA 模型阶数order(p,d,q)需要根据数据调试,不同股票数据最优阶数不同。

9.3 拓展方向(进阶学习)

  1. 引入 LSTM、Prophet 等深度学习 / 工业级时序模型,提升复杂行情预测精度;
  2. 新增 MACD、RSI、布林带等更多金融技术指标作为特征;
  3. 构建量价相关性分析、风险波动率分析,丰富分析维度;
  4. 结合多支股票数据,做板块联动分析。

十、写在最后

用 Python 做股票时间序列分析,是数据分析 + 金融知识结合的经典实战案例。本项目从基础的数据处理到模型落地,完整还原了企业中时序数据分析的工作流程。对于初学者而言,既能巩固pandas、可视化、机器学习基础,也能初步理解金融数据分析的逻辑。

⚠️ 温馨提示:本文所有分析、预测结果均基于历史模拟数据,仅用于技术学习与代码练习,不构成任何投资建议。股市有风险,投资需谨慎。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐