Python统计实战:时间序列分析之简单指数平滑和Holt指数平滑

为了解决特定问题而进行的学习是提高效率的最佳途径。这种方法能够使我们专注于最相关的知识和技能,从而更快地掌握解决问题所需的能力。

(以下练习题来源于《统计学—基于Python》。请在Q群455547227下载原始数据。


练习题

下表是某只股票连续35个交易日的收盘价格(前3行和后3行)。

(1)分别采用m=5和m=10对收盘价格进行平滑,并绘制实际值和平滑值的图形进行比较。

(2)分别采用以下方法进行预测,并绘制预测图和残差图,对结果进行比较。

  • (a)简单指数平滑和Holt指数平滑;
  • (b)一元线性回归和指数曲线;
  • (c)二阶曲线和三阶曲线。

图形绘制与分析

鉴于篇幅原因,本文先就(1)题及(2a)题展开分析。

(1)计算m=5(5期移动平均)和m=10(10期移动平均)的移动平均

# 移动平均
import pandas as pd
df = pd.read_csv('exercise11_1.csv')
# df.head()
ma5 = df['收盘价'].rolling(window = 5, center = True).mean()  # 5期移动平均
ma10 = df['收盘价'].rolling(window = 10, center = True).mean()  # 10期移动平均
df_ma = pd.DataFrame({'时间':df['时间'], '收盘价':df['收盘价'], '5期移动平均':ma5, '10期移动平均':ma10})
round(df_ma,2)

显示前20行:

绘制实际值和平滑值的折线图

# 绘制实际值和平滑值的折线图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Songti SC']
plt.rcParams['axes.unicode_minus'] = Falseplt.figure(figsize = (8, 5.5))
l1, = plt.plot(df_ma['收盘价'], linestyle = '-', marker = 'o', linewidth = 0.8)
l2, = plt.plot(df_ma['5期移动平均'], linestyle = '-', marker = '+', linewidth = 0.8)
l3, = plt.plot(df_ma['10期移动平均'], linestyle = '-', marker = '*', linewidth = 0.8)
plt.xticks(range(0, 36, 2), df['时间'][::2])
plt.legend(handles = [l1, l2, l3], labels = ['收盘价','5期移动平均', '10期移动平均'], loc = 'best', prop = {'size':10})
plt.xlabel('时间', size = 12)
plt.ylabel('收盘价', size = 12)

分析:移动间隔越长,曲线就越平滑。在实际应用中,可根据数据的波动情况和分析目的合理选择移动间隔的长度。当数据量较大时,移动间隔可长一些。但如果数据是以固定长度的周期采集的,则移动间隔的长度最好与数据的采集周期一致,这样可以有效去除序列中的随机波动。比如,如果数据是按季节采集的,则移动间隔的长度应取4;如果数据是按月采集的,则移动间隔的长度应取12。

(2a)题的第一问要求进行简单指数平滑预测
  先建立模型并输出相关参数信息
# 简单指数平滑
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.holtwinters import SimpleExpSmoothing
plt.rcParams['font.sans-serif'] = ['Songti SC']
plt.rcParams['axes.unicode_minus'] = False
df = pd.read_csv('exercise11_1.csv')# df.index = pd.date_range(start = '1', end = '35', freq = 'AS')# 拟合简单指数平滑模型(alpha = 0.3)
model = SimpleExpSmoothing(df['收盘价']).fit(smoothing_level = 0.3, optimized = True)
model.params # 输出模型参数

注:Smoothing_level:0.3为事先指定的平滑系数。initial_level:33.82为系统确定的初始平滑值。
接下来绘制实际值和拟合值图
# 绘制实际值和拟合值图
df['price_ses'] = model.fittedvalues
plt.figure(figsize = (7, 4.5))
l1, = plt.plot(df['收盘价'], linestyle = '-', marker = 'o', linewidth = 0.8)
l2, = plt.plot(df['price_ses'], linestyle = '--', marker = '*', linewidth = 0.8)
plt.legend(handles = [l1, l2], labels = ['收盘价', '拟合值'], loc = 'best', prop = {'size': 10})
plt.xlabel('时间', size = 12)
plt.ylabel('收盘价', size = 12)

上图展示了收盘价的简单指数平滑的拟合效果,可以观察到预测模型看似较合适。后续观察残差图做出判断。
# 计算第36期的预测值
p_model = model.forecast(1) # 向后预测1期
p_model

计算结果:

绘制预测图和残差图

# 绘制预测图和残差图
import scipy
df = pd.read_csv('exercise11_1.csv')# 图(a)预测图
plt.subplots(1, 2, figsize = (11, 4))
plt.subplot(121)ax = df['收盘价'].plot(marker = 'o', linewidth = 0.8, color = 'black')  # 绘制实际值
ax.set_ylabel('收盘价', size = 12)
ax.set_xlabel('时间', size = 12)
model.forecast(1).plot(ax = ax, style = '--', marker = 'o', color = 'red')  # 绘制预测值# 计算置信区间并绘图
simulations = model.simulate(nsimulations = 2, repetitions = 1000, error = 'add', random_errors = scipy.stats.norm) # 重复模拟100次,模拟步长为2
random_errors = 'bootstrap'
low_CI_95 = p_model-1.96*simulations.std(axis = 1)
high_CI_95 = p_model+1.96*simulations.std(axis = 1)
low_CI_80 = p_model-1.28*simulations.std(axis = 1)
high_CI_80 = p_model+1.28*simulations.std(axis = 1)plt.fill_between([36], low_CI_95, high_CI_95, alpha = 0.3, color = 'grey', linewidth = 20)
plt.fill_between([36], low_CI_80, high_CI_80, alpha = 0.3, color = 'blue', linewidth = 20)
plt.xlim(-1, 36)
plt.title('(a)收盘价的简单指数平滑预测', size = 13)# 图(b)残差图
res = model.resid
plt.subplot(122)
plt.scatter(range(len(res)), res, marker = 'o')
plt.hlines(0, 0, 35, linestyle = '--', color = 'red')
plt.xticks(range(0, 35, 2), df['时间'][::2])
plt.xlabel('时间', size = 12)
plt.ylabel('残差', size = 12)
plt.title('(b)简单指数平滑预测残差', size = 13)plt.tight_layout()

分析:左图中的折线图是收盘价的实际值,红色圆点是第36期的预测值,蓝色和灰色区域是置信区间,其中的灰色区域是95%的置信区间,蓝色是区域是80%的置信区间。 右图的残差图显示,残差虽然围绕0轴波动,但是呈现出U型的形态,表明采用简单指数平滑预测模型可能是不合适的。

(2a)题的第二问要求进行Holt指数平滑预测

Holt指数平滑预测是以其提出者C.C.Holt 的名字命名的,通常简称 Holt 模型。当时间序列存在趋势成分时,简单指数平滑的预测值总是滞后于实际值。而Holt模型则改进了简单指数平滑模型,它将趋势成分也考虑造来,用平滑值对序列的线性趋势进行修正,建立线性平滑模型进行预测。

先建立模型并输出相关参数:

import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.holtwinters import SimpleExpSmoothing, ExponentialSmoothing, Holt
plt.rcParams['font.sans-serif'] = ['Songti SC']
plt.rcParams['axes.unicode_minus'] = Falsedf = pd.read_csv('exercise11_1.csv')# 拟合Holt指数平滑模型(model_h)
model_h = Holt(df['收盘价']).fit(optimized = True)
model_h.params # 输出模型系数

注:smoothing_level为系统确定的平滑指数α(反映随机成分);smoothing_trend为系统确定的平滑系数β(反映趋势成分);initial_level为初始平滑值;initial_trend为初始趋势值。

 绘制实际值和拟合值图

# 绘制实际值和拟合值图
df['收盘价_holt'] = model_h.fittedvalues
plt.figure(figsize = (7, 4.5))
l1, = plt.plot(df['收盘价'], linestyle = '-', marker = 'o', linewidth = 1) # 实际值
l2, = plt.plot(df['收盘价_holt'], linestyle = '--', marker = '^', linewidth = 1) # 拟合值
plt.legend(handles = [l1, l2], labels = ['收盘价', '拟合值'], loc = 'best', prop = {'size': 10})
plt.xlabel('时间', size = 12)
plt.ylabel('收盘价', size = 12)
plt.title('收盘价的Holt指数平滑拟合', size = 13)

上图展示了收盘价的Holt指数平滑的拟合效果,从拟合值和实际值的接近程度来看,预测模型比较理想。

# 计算第36期的预测值
model_h.forecast(1)

计算结果:

可以发现其计算结果与简单指数平滑预测是不同的。

接下来绘制预测图和残差图:

# 绘制预测图和残差图
import scipy
df = pd.read_csv('exercise11_1.csv')# 图(a)预测图
plt.subplots(1, 2, figsize = (11, 4))
plt.subplot(121)ax = df['收盘价'].plot(marker = 'o', linewidth = 0.8, color = 'black')  # 绘制实际值
ax.set_ylabel('收盘价', size = 12)
ax.set_xlabel('时间', size = 12)
model_h.forecast(1).plot(ax = ax, style = '--', marker = 'o', color = 'red')  # 绘制预测值# 计算置信区间并绘图
simulations = model_h.simulate(nsimulations = 2, repetitions = 1000, error = 'add', random_errors = scipy.stats.norm) # 重复模拟100次,模拟步长为2
#random_errors = 'bootstrap'
low_CI_95 = model_h.forecast(1)-1.96*simulations.std(axis = 1)
high_CI_95 = model_h.forecast(1)+1.96*simulations.std(axis = 1)
low_CI_80 = model_h.forecast(1)-1.28*simulations.std(axis = 1)
high_CI_80 = model_h.forecast(1)+1.28*simulations.std(axis = 1)plt.fill_between([36], low_CI_95, high_CI_95, alpha = 0.3, color = 'grey', linewidth = 20)
plt.fill_between([36], low_CI_80, high_CI_80, alpha = 0.3, color = 'blue', linewidth = 20)
plt.xlim(-1, 36)
plt.title('(a)收盘价的Holt指数平滑预测', size = 13)# 图(b)残差图
plt.subplot(122)
res = model_h.resid
plt.scatter(range(len(res)), res, marker = 'o')
plt.hlines(0, 0, 35, linestyle = '--', color = 'red')
plt.xticks(range(0, 35, 2), df['时间'][::2])
plt.xlabel('时间', size = 12)
plt.ylabel('残差', size = 12)
plt.title('(b)Holt指数平滑预测残差', size = 13)plt.tight_layout()

分析:左图中的折线是收盘价的实际值,红色圆点是第36期的预测值,灰色和蓝色区域是置信区间,其中灰色区域是95%的置信区间,蓝色区域是80%的置信区间。 右图的残差图显示,残差围绕0轴随机波动,无固定的模型,表明采用Holt指数平滑预测模型是合适的。


都读到这里了,不妨关注、点赞一下吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/40205.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二维平面无中心点的聚类算法

问题描述 二维平面上有许多点p(x , y),按照彼此之间的欧式距离进行分为若干个集合。若点p1(x1, y1)与点p(x2, y2)之间距离小于d,则认为二者是邻居。 算法思路 给数据集的点进行编号,顺序遍历这些点,找出当前点的邻居,记住已经遍…

模具监视器的选择要点介绍

模具监视器的选择要点涉及多个方面,以确保其能够满足实际生产需求并提高生产效率。以下是一些关键的选择要点: 一、性能和稳定性 监控精度:选择模具监视器时,首先要考虑其监控精度,包括温度、压力、注射速度等参数的…

Debezium系列之:JVM参数详解和Debezium集群JVM监控看板制作

Debezium系列之:JVM参数详解和Debezium集群JVM监控看板制作 一、JVM参数详解1.jvm_memory_bytes_used2.jvm_memory_bytes_committed3.jvm_memory_bytes_max4.jvm_memory_bytes_init5.jvm_memory_pool_bytes_used6.jvm_memory_pool_bytes_committed7.jvm_memory_pool_bytes_max…

金属3D打印如何精准选材

随着3D打印技术的飞跃发展,模具制造领域迎来了前所未有的创新机遇。在众多3D打印技术中,SLM金属3D打印以其精度高、复杂结构成型能力,成为众多行业的优选。然而,金属打印材料,如何精准选择,以最大化满足项目…

linux 内核打印log太多咋办?

有时候发现,linux 内核打印太多消息了,对有用消息造成了干扰,如果你一个个源文件去关闭打印太麻烦了,有没有一种更方便的方式来关闭这些消息呢? 对这个需求,内核提供了一个强大而又灵活的方式,…

开源 WAF 解析:选择最适合你的防护利器

前言 随着网络安全风险的增加,Web 应用防火墙(WAF)成为保护网站和应用程序免受攻击的关键工具。在众多的选择中,开源 WAF 以其灵活性、可定制性和成本效益备受青睐。本文将深入探讨几种主流开源 WAF 解决方案,帮助你选…

用html+css设计一个列表清单小卡片

目录 简介: 效果图: 源代码: 可能的问题: 简介: 这个HTML代码片段是一个简单的列表清单设计。它包含一个卡片元素(class为"card"),内部包含一个无序列表(ul),列表项(li)前面有一个特殊的符号(△)。整个卡片元素设计成300px宽,150px高,具有圆角边…

从0-1配置一个ROS项目

目标:从0-1配置一个ROS项目,实现hello,world打印,在此基础上进行功能开发。 步骤1:创建工作空间: mkdir -p ros_workspace/src cd ros_workspace对工作空间进行初始化: catkin_make source devel/setup.…

20.【C语言】初识结构体(重要)

定义&#xff1a;由一批数据组合而成的结构型数据 作用&#xff1a;描述复杂对象&#xff0c;创建新的类型 格式&#xff1a; struct 对象 { …… } 介绍. 用法&#xff1a;结构体变量.成员变量 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> struct hotal…

代码随想录训练营Day57

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、X的平方根二、有效的完全平方数 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 今天是跟着代码随想录刷题的第57天&#xff0c;继…

Prompt-Free Diffusion: Taking “Text” out of Text-to-Image Diffusion Models

CVPR2024 SHI Labshttps://arxiv.org/pdf/2305.16223https://github.com/SHI-Labs/Prompt-Free-Diffusion 问题引入 在SD模型的基础之上&#xff0c;去掉text prompt&#xff0c;使用reference image作为生成图片语义的指导&#xff0c;optional structure image作为生成图片…

安装Linux虚拟机

点击创建新的虚拟机 选择高级 系统自定义推荐 选择稍后安装 选择Linux 虚拟机命名并且选择创建位置 系统自定义 系统自定义推荐 系统自定义推荐 选择安装好的iOS文件 点击完成 选择编辑虚拟机设置 进入后选择第一个Install red hat enterprise 选择常用语言 设置…

2024.8月28号杭州电商博览会,在杭州国博举办

2024杭州电商新渠道博览会暨集脉电商节 时间&#xff1a;2024年08月28-30日 地点&#xff1a;杭州国际博览中心&#xff08;G20&#xff09; 主办单位&#xff1a;浙江集脉展览有限公司、杭州华维展览有限公司 承办单位&#xff1a;浙江集脉展览有限公司 报名参展&#xf…

测试几个 ocr 对日语的识别情况

测试几个 ocr 对日语的识别情况 1. EasyOCR2. PaddleOCR3. Deepdoc&#xff08;识别pdf中图片&#xff09;4. Deepdoc&#xff08;识别pdf中文字&#xff09;5. Nvidia neva-22b6. Claude 3.5 sonnet 识别图片中的文字7. Claude 3.5 sonnet 识别 pdf 中表格8. OpenAI gpt-4o 识…

网页计算器的实现

简介 该项目实现了一个功能完备、交互友好的网页计算器应用。只使用了 HTML、CSS 和 JavaScript &#xff0c;用于检验web前端基础水平。 开发环境&#xff1a;Visual Studio Code开发工具&#xff1a;HTML5、CSS3、JavaScript实现效果 功能设计和模块划分 显示模块&#…

Bean类的设计规范:Bean规范

Bean规范 类要求必须含有无参&#xff0c;公共的构造方法属性必须私有化&#xff0c;然后提供公共的 set 和 get 方法

anaconda命令大全

目录 查看所有虚拟环境查看某虚拟环境安装的包创建虚拟环境激活创建好的虚拟环境回到之前的环境删除创建的虚拟环境查看conda所在的位置、虚拟环境位置等信息conda修改虚拟环境所在的位置 查看所有虚拟环境 conda env list查看某虚拟环境安装的包 激活要查看的虚拟环境之后&a…

Android 性能优化之启动优化

文章目录 Android 性能优化之启动优化启动状态冷启动温启动热启动 耗时检测检测手段TraceView使用方式缺点 Systrace环境配置使用方式TraceView和Systrace比较 AOP统计耗时环境配置使用 优化白屏优化异步加载优化环境配置使用 延迟加载优化AppStartup 源码下载 Android 性能优化…

Reid系列论文学习——无人机场景下基于 Transformer 的轻量化行人重识别

今天介绍的一篇论文是针对无人机场景下的行人重识别&#xff0c;论文题目为&#xff1a;"无人机场景下基于 Transformer 的轻量化行人重识别"。该论文针对无人机场景下行人呈现多角度多尺度的特点、以及传统CNN网络在行人重识别任务中受限于感受野和下采样导致的无法…

力扣1895.最大的幻方

力扣1895.最大的幻方 求前缀和暴力枚举幻方边长 求行列前缀和 class Solution {public:int largestMagicSquare(vector<vector<int>>& grid) {int n grid.size() , m grid[0].size();vector<vector<int>> rowsum(n,vector<int>(m));for…