时间序列预测模型实战案例(二)(Holt-Winter)(Python)结合K-折交叉验证进行时间序列预测实现企业级预测精度(包括运行代码以及代码讲解)

这篇具有很好参考价值的文章主要介绍了时间序列预测模型实战案例(二)(Holt-Winter)(Python)结合K-折交叉验证进行时间序列预测实现企业级预测精度(包括运行代码以及代码讲解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

引言

数据格式

运行代码 

Holt-Winters模型主体

程序入口

参数讲解

开始训练

预测结果


 文章来源地址https://www.toymoban.com/news/detail-751784.html

引言

话不多说上来先上预测精度分析图,其中MAE的误差大概在0.11,以下数据均是预测未知数据,而不是训练数据的预测图。

holt-winters,时间序列预测专栏,机器学习,bug,人工智能,python,深度学习

 

开始之前我们先来简单了解一下Holt-Winters模型

Holt-Winters模型,也称为三重指数平滑模型,是一种经典的时间序列预测模型,用于处理具有趋势和季节性的时间序列数据。

Holt-Winters模型基于指数平滑法,通过对历史数据进行加权平均来预测未来的值。它使用三个指数平滑系数来估计未来的趋势、季节性和平稳项,从而可以对未来的值进行预测。

Holt-Winters模型的三个指数平滑系数分别为:α、β和γ。其中,α表示对当前观测值的加权系数,β表示对趋势的加权系数,γ表示对季节性的加权系数。这些系数可以通过利用K-折交叉验证最小化平均绝对误差或平均平方误差来确定。

Holt-Winters模型大致可以分为三种类型:加法模型、乘法模型和季节性模型。加法模型适用于季节性变化的幅度相对稳定的情况,乘法模型适用于季节性变化的幅度随着趋势的变化而变化的情况,季节性模型则适用于季节性变化的周期相对稳定的情况。

本文主要选择一种模型来进行实现(季节性模型)同时利用K-折交叉验证法来确定其中三个平滑系数α、β和γ以验证最好的系数,从而达到最高的预测精度极限。

下面来接介绍一下什么是K-折交叉验证

K-折交叉验证(K-fold cross-validation)是一种常用的模型评估方法,用于评估机器学习模型的性能和泛化能力。它将原始数据集分成K个子集,称为“折叠”(fold),其中K-1个子集用于训练模型,1个子集用于测试模型。这个过程重复K次,每个子集都会轮流作为测试集,最终得到K个模型的性能评估结果,这些结果可以平均或加权平均得到模型的最终性能评估结果。

K-折交叉验证的优点是可以有效地利用数据集,减少因数据划分不合理而引入的偏差,提高模型的泛化能力。同时,K-折交叉验证可以避免过拟合和欠拟合等问题,提高模型的稳定性和可靠性。

数据格式

在正式开始之前需要先了解一下,holt-winter模型是单元变量预测模型,所以其只接受单个时间变量的时间序列预测,所以其数据只需要一列即可,就是你需要预测的数据我们这里拿官方的数据ETTh1来进行举例 

holt-winters,时间序列预测专栏,机器学习,bug,人工智能,python,深度学习

数据是这种格式即可,当然你也可以只有OT一列数据也可以,但是你要确保你的数据要符合时间序列,因为你的顺序不能够打乱,因为我们需要时间date这一列主要是为了确保数据是有序的,当然如果你确定你的数据是有序的你也可以只读取进来一列数据即可!!! 

运行代码 

Holt-Winters模型主体

大家可以新建一个py文件将以下所有代码复制进去加上你的数据即可运行出结果!!

import pandas as pd
import numpy as np
from scipy.optimize import minimize  # 优化函数
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import TimeSeriesSplit


class HoltWinters:
    def __init__(self, series, slen, alpha, beta, gamma, n_preds, scaling_factor=1.96):
        self.series = series
        self.slen = slen
        self.alpha = alpha
        self.beta = beta
        self.gamma = gamma
        self.n_preds = n_preds
        self.scaling_factor = scaling_factor

    def initial_trend(self):
        """
        初始化趋势,使用第一个原始数据周期内的数据
        依据现有的数据,除非输入的原始数据发生变化,否则为常数
        :return: 初始化的趋势
        """
        sum = 0.0
        for i in range(self.slen):
            sum += float(self.series[i + self.slen] - self.series[i]) / self.slen
        return sum / self.slen

    def initial_seasonal_components(self):
        """
        初始化季节性参数
        :return: 季节性对于当周期平均值的平均变化值
        """
        seasonals = {}
        season_averages = []
        # 现有数据的周期个数
        n_seasons = int(len(self.series) / self.slen)
        # let's calculate season averages
        # 最后一个周期会有稍微的影响,但影响不大
        # 每个周期平均值,从第一个周期开始,共有n个周期的数据
        for j in range(n_seasons):
            season_averages.append(sum(self.series[self.slen * j:self.slen * j + self.slen]) / float(self.slen))
        # let's calculate initial values
        # 周期中第i天的季节性增长(对比周期内的平均值)
        # 数据个数为一个周期的长度,index为一个周期内的第几个值,从0开始
        # 与原始数据相关,并不是一个固定值
        for i in range(self.slen):
            sum_of_vals_over_avg = 0.0
            for j in range(n_seasons):
                sum_of_vals_over_avg += self.series[self.slen * j + i] - season_averages[j]
            seasonals[i] = sum_of_vals_over_avg / n_seasons
        return seasonals

    def triple_exponential_smoothing(self):
        """
        三次指数平滑
        :return:
        """
        # 预测结果
        self.result = []
        # 平滑值
        self.Smooth = []
        # 季节性
        self.Season = []
        # 趋势性
        self.Trend = []
        # 预测标准差
        self.PredictedDeviation = []
        self.UpperBond = []
        self.LowerBond = []

        # 对于当周期的平均值,每一时刻的平均变化值,为初始值
        seasonals = self.initial_seasonal_components()

        for i in range(len(self.series) + self.n_preds):
            if i == 0:  # components initialization
                smooth = self.series[0]
                trend = self.initial_trend()
                self.result.append(self.series[0])
                self.Smooth.append(smooth)
                self.Trend.append(trend)
                self.Season.append(seasonals[i % self.slen])

                self.PredictedDeviation.append(0)

                self.UpperBond.append(self.result[0] +
                                      self.scaling_factor *
                                      self.PredictedDeviation[0])

                self.LowerBond.append(self.result[0] -
                                      self.scaling_factor *
                                      self.PredictedDeviation[0])
                continue

            if i >= len(self.series):  # predicting
                m = i - len(self.series) + 1
                self.result.append((smooth + m * trend) + seasonals[i % self.slen])
                # self.result.append(max(0,min(1, (smooth + m * trend) + seasonals[i % self.slen])))

                # when predicting we increase uncertainty on each step
                # 每一步增加预测的波动性
                self.PredictedDeviation.append(self.PredictedDeviation[-1] * 1.01)

            else:
                val = self.series[i]
                last_smooth, smooth = smooth, self.alpha * (val - seasonals[i % self.slen]) + (1 - self.alpha) * (
                        smooth + trend)
                trend = self.beta * (smooth - last_smooth) + (1 - self.beta) * trend
                seasonals[i % self.slen] = self.gamma * (val - smooth) + (1 - self.gamma) * seasonals[i % self.slen]
                self.result.append(smooth + trend + seasonals[i % self.slen])
                # self.result.append(max(0,min(1, smooth + trend + seasonals[i % self.slen])))

                # Deviation is calculated according to Brutlag algorithm.
                self.PredictedDeviation.append(self.gamma * np.abs(self.series[i] - self.result[i])
                                               + (1 - self.gamma) * self.PredictedDeviation[-1])

            self.UpperBond.append(self.result[-1] +
                                  self.scaling_factor *
                                  self.PredictedDeviation[-1])

            self.LowerBond.append(self.result[-1] -
                                  self.scaling_factor *
                                  self.PredictedDeviation[-1])

            self.Smooth.append(smooth)
            self.Trend.append(trend)
            self.Season.append(seasonals[i % self.slen])

def timeseriesCVscore(params, series, loss_function=mean_squared_error, slen=7):
    """
        Returns error on CV

        params - vector of parameters for optimization
        series - dataset with timeseries
        slen - season length for Holt-Winters model
    """
    # errors array
    errors = []

    values = series.values
    alpha, beta, gamma = params

    # set the number of folds for cross-validation
    # tscv = TimeSeriesSplit(n_splits=50, test_size=4)
    tscv = TimeSeriesSplit(n_splits=5, test_size=4)

    # iterating over folds, train model on each, forecast and calculate error
    for train, test in tscv.split(values):
        model = HoltWinters(series=values[train], slen=slen,
                            alpha=alpha, beta=beta, gamma=gamma, n_preds=len(test))
        model.triple_exponential_smoothing()

        predictions = model.result[-len(test):]
        actual = values[test]
        error = loss_function(predictions, actual)
        errors.append(error)

    return np.mean(np.array(errors))  # 返回了一个损失函数的平均值

以上的部分就是Holt-Winters的程序内部,其中有一些个人阅读时候的个人理解,大家可以在阅读时候进行一个参考,

程序入口

下面的代码就是程序的入口,我们复制粘贴到文件的最后面即可,下面我将介绍其中每一行的具体含义!!

if __name__ == '__main__':
    data = pd.read_csv('')
    # initializing model parameters alpha, beta and gamma
    cycle = '在这里输入你数据的周期'
    pre_len = '这里输入你要预测未来多久的数据'
    # Minimizing the loss function
    opt = minimize(timeseriesCVscore, x0=[0, 0, 0],
                   args=(data, mean_squared_error,),
                   method="TNC", bounds=((0, 1), (0, 1), (0, 1))
                   )
    # Take optimal values...
    alpha, beta, gamma = opt.x
    model = HoltWinters(data, slen=cycle,
                        alpha=alpha,
                        beta=beta,
                        gamma=gamma,
                        n_preds=pre_len, scaling_factor=2)
    model.triple_exponential_smoothing()
    print(model.result)

 

参数讲解

 首先data = pd.read_csv('')这一行很好理解就是读取你的数据,首先要求你的数据需要是csv格式的文件,然后读取来的数据要满足第二节所述的数据格式(如果你的文件是其他格式你也可以更换类似于read_excel()即可)

    data = pd.read_csv('')

当我们将数据读取进来之后,我们可以对数据进行一个按照时间排序的操作(如果你的数据只有目标值列而没有时间列则忽略掉本段代码) 这一段代码如果你们没有也可以运行如果需要排序则可以自己复制粘贴到对应位置即可

    data.sort_values(by=['date'], inplace=True)

之后的两行,这两行是一个是你数据拥有的周期性,因为holt-winter模型主要的参数还是你数据的一个周期来预测未来某一时段的数据,所有你要知道你数据所拥有的周期性,可以通过数据建模的方式或者根据你的经验来分析(如果大家不会可以评论区留言我可以给大家出用powerbi,matplotlib,excel来建模从而分析数据的教程)

    cycle = '在这里输入你数据的周期'
    pre_len = '这里输入你要预测未来多久的数据'

 这一段代码如果大家了解深度学习就可以理解为模型训练的一个过程,其中

timeseriesCVscore是一个K-折交叉验证的方法来求出损失值最小的方法,

x0就是Holt-Winters模型的三个参数α、β和γ我们初始时将其设置为0

args=(data,mean_squared_error) 其中data就是你们读取进来的数据, mean-squared_error就是一个军方损失函数,就是用前面的K-折交叉验证来求这一损失函数的最小值

method='TNC'就是模型训练的从而收敛的方法,其有很多选项如下大家可以多做实验从而得到一个最好损失结果,

- 'Nelder-Mead' :ref:`(see here) <optimize.minimize-neldermead>`
- 'Powell' :ref:`(see here) <optimize.minimize-powell>`
- 'CG' :ref:`(see here) <optimize.minimize-cg>`
- 'BFGS' :ref:`(see here) <optimize.minimize-bfgs>`
- 'Newton-CG' :ref:`(see here) <optimize.minimize-newtoncg>`
- 'L-BFGS-B' :ref:`(see here) <optimize.minimize-lbfgsb>`
- 'TNC' :ref:`(see here) <optimize.minimize-tnc>`
- 'COBYLA' :ref:`(see here) <optimize.minimize-cobyla>`
- 'SLSQP' :ref:`(see here) <optimize.minimize-slsqp>`
- 'trust-constr':ref:`(see here) <optimize.minimize-trustconstr>`
- 'dogleg' :ref:`(see here) <optimize.minimize-dogleg>`
- 'trust-ncg' :ref:`(see here) <optimize.minimize-trustncg>`
- 'trust-exact' :ref:`(see here) <optimize.minimize-trustexact>`
- 'trust-krylov' :ref:`(see here) <optimize.minimize-trustkrylov>`

每一个方法都不一样,不同的数据也可能适合不同的方法大家可以多尝试尝试, 

bounds就是限制α、β和γ的范围其通常都是位于0-1之间的一个数字,我们限制其一下不要让其超出范围!

    opt = minimize(timeseriesCVscore, x0=[0, 0, 0],
                   args=(data, mean_squared_error,),
                   method="TNC", bounds=((0, 1), (0, 1), (0, 1))
                   )

之后的代码就是将我们训练好的三个参数α、β和γ取出来

    alpha, beta, gamma = opt.x

 下面的代码就是正式到我们预测的部分了,其中的大部分参数我们都已经讲过了,除了其中的scaling_factor大家可以将其理解为一个平滑的参数,之后就是我们对输出结果作了一个三指数的平滑操作可以让数据更加平滑从而提高精度!!!

    model = HoltWinters(data, slen=cycle,
                        alpha=alpha,
                        beta=beta,
                        gamma=gamma,
                        n_preds=pre_len, scaling_factor=2)
    model.triple_exponential_smoothing()

最后我们打印一下结果即可

    print(model.result)

 

 

开始训练

将上述准备工作全部做完以后我们就可以运行我们的程序开始训练了!

运行你们保存代码的文件,控制台就会输出训练过程

holt-winters,时间序列预测专栏,机器学习,bug,人工智能,python,深度学习 我这里选用的method是L-BFGS-B这个对于我的数据而言我能拿到更高的精度,其控制台输出如上图所示,直到其最终收敛!

holt-winters,时间序列预测专栏,机器学习,bug,人工智能,python,深度学习

可以看到控制台收敛以后打印出了 α、β和γ三个参数,其中α=0.38537304、β=0和γ=0.89117814

α表示对当前观测值的加权系数,β表示对趋势的加权系数,γ表示对季节性的加权系数。

 

预测结果

holt-winters,时间序列预测专栏,机器学习,bug,人工智能,python,深度学习

我将所有的结果输出下来并进行了保存到本地的csv文件中并用excel画出了如图可以看出预测值和真实值之间的误差还是有一定误差的!

holt-winters,时间序列预测专栏,机器学习,bug,人工智能,python,深度学习

这个图可以看出我们的误差MAE大部分都集中在0-0.1之间预测效果还是可以的!

到此Holt-Winters模型的使用就讲解完了!!!!!希望大家都能运行出一个好的结果! 

其它时间序列预测模型讲解

后期我会讲一些最新的预测模型包括transform, Informer,TPA-LSTM,ARIMA,XGBOOST,Holt-winter,移动平均法等等一系列关于时间序列预测的模型,包括深度学习和机器学习方向的模型我都会讲,你可以根据需求选取适合你自己的模型进行预测,如果有需要可以+个关注,包括本次模型我自己的代码和数据大家有需要我也会放出百度网盘下载链接!!

-----------------------------------------------------MTS-Mixers------------------------------------------------------------

【全网首发】(MTS-Mixers)(Python)(Pytorch)最新由华为发布的时间序列预测模型实战案例(一)(包括代码讲解)实现企业级预测精度包括官方代码BUG修复Transform模型

--------------------------------------------------------LSTM-----------------------------------------------------------------

 时间序列预测模型实战案例(三)(LSTM)(Python)(深度学习)时间序列预测(包括运行代码以及代码讲解)

如果大家有不懂的也可以评论区留言一些报错什么的大家可以讨论讨论看到我也会给大家解答如何解决!
 

 

到了这里,关于时间序列预测模型实战案例(二)(Holt-Winter)(Python)结合K-折交叉验证进行时间序列预测实现企业级预测精度(包括运行代码以及代码讲解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 机器学习——时间序列ARIMA模型(三):AR、MA、ARMA、ARIMA模型定义及公式介绍及股价预测案例代码

    使用自身的数据进行预测,且只适用于预测与自身前期相关的现象。 注意:需满足具有平稳性的要求,需满足自相关性,自相关系数需大于0.5。 p阶自回归公式: y t = μ + ∑ i = 1 p γ i y t − i + e t y_{t}=μ+sum_{i=1}^pgamma_{i}y_{t-i}+e_{t} y t ​ = μ + i = 1 ∑ p ​ γ i ​ y t − i ​ + e

    2024年02月02日
    浏览(60)
  • LSTM 时间序列预测+股票预测案例(Pytorch版)

    数据特征 Date:日期 Open:开盘价 High:最高价 Low:最低价 Close:收盘价 Adj Close:调整后的收盘价 Volume:交易量 数据链接: 链接: https://pan.baidu.com/s/1rX_S3Jaz4zJVMKPW2BLdLA?pwd=hi55 提取码: hi55 对收盘价(Close)单特征进行预测 利用前n天的数据预测第n+1天的数据。 1. 导入数据 2. 将股票

    2024年02月11日
    浏览(45)
  • 深度学习时间序列预测项目案例数据集介绍

    💥项目专栏:【深度学习时间序列预测案例】零基础入门经典深度学习时间序列预测项目实战(附代码+数据集+原理介绍) 🌈 本专栏使用的数据集为 风速预测的时间序列数据 ,该数据集包含一个气象站内嵌入的5个天气变量传感器阵列的 6574 个每日平均样本。该设备位于油

    2023年04月15日
    浏览(46)
  • 时间序列预测 | Matlab鲸鱼算法(WOA)优化极限梯度提升树XGBoost时间序列预测,WOA-XGBoost时间序列预测模型,单列数据输入模型

    效果一览 文章概述 鲸鱼算法(WOA)优化极限梯度提升树XGBoost时间序列预测,WOA-XGBoost时间序列预测模型,单列数据输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码

    2024年02月13日
    浏览(79)
  • 时间序列预测 | Matlab灰狼算法(GWO)优化极限梯度提升树XGBoost时间序列预测,GWO-XGBoost时间序列预测模型,单列数据输入模型

    效果一览 文章概述 时间序列预测 | Matlab灰狼算法(GWO)优化极限梯度提升树XGBoost时间序列预测,GWO-XGBoost时间序列预测模型,单列数据输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码

    2024年02月13日
    浏览(53)
  • 时间序列预测 | Matlab自回归差分移动平均模型ARIMA时间序列预测

    效果一览 文章概述 时间序列预测 | Matlab自回归差分移动平均模型ARIMA时间序列预测,单列数据输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码

    2024年02月13日
    浏览(53)
  • Python数据分析案例11——灰色预测法预测时间序列数据

    本次案例来自2022华为杯第E题,第2小问。给定了2012.01-2022.03的土壤湿度的月度数据,需要预测2022.04-2023.12的土壤湿度的月度数据。典型的时间序列预测。 传统的时间序列预测肯定是ARIMA模型,可以参考我之前的文章。Python统计学10——时间序列分析自回归模型(ARIMA) 现在流行的

    2024年02月06日
    浏览(61)
  • 数据分析实战│时间序列预测

    时间序列预测问题是一类常见的数据分析问题。数据中往往包含时间标签,这类问题往往根据过去一段时间的数据,建立能够比较精确地反映序列中所包含的动态依存关系的数学模型,并对未来的数据进行预测。 本案例给出二战时期的某气象站温度记录值,通过分析之前的天

    2024年02月11日
    浏览(49)
  • 数学建模系列-预测模型(三)时间序列预测模型

    目录 前言 1 时间序列定义 1.1 朴素法 1.2 简单平均法 1.3 移动平均法 1.4 指数平滑法 1.4.1 一次指数平滑  1.4.2 二次指数平滑 1.4.3 三次指数平滑 1.5 AR模型 1.6 MA模型 1.7 ARMA模型 1.8 ARIMA模型 1.9 SARIMA模型         时间序列的目的:进行预测, 根据已有的时间序列数据预测未来

    2024年02月07日
    浏览(49)
  • 【数值预测案例】(5) LSTM 时间序列气温数据预测,附TensorFlow完整代码

    大家好,今天和各位分享一下如何使用循环神经网络 LSTM 完成有多个特征的气温预测。上一节中我介绍了 LSTM 的单个特征的预测,感兴趣的可以看一下:https://blog.csdn.net/dgvv4/article/details/124349963 我使用GPU加速计算,没有GPU的朋友可以把调用GPU的代码段去掉。 数据集地址:h

    2024年01月18日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包