Python 中的朴素时间序列预测2025年3月5日 | 阅读 12 分钟 朴素预测法是需求预测中最简单的形式之一,常被销售和财务部门使用。该方法基于简单原则:它假设未来需求最好由最近一个实际销售周期的模式来建模。换句话说,它假设下一期的需求将与上一期的需求相同。 关于朴素时间序列预测的工作朴素预测法遵循一个简单的原则:它预测下一期的需求将与上一期(最近一期)的需求相同。换句话说,下一期要预测的值是固定的,并且固定为前一期的实际观测值。该方法基于这样的假设:最近的周期对未来的时间周期最相关,并且不会发生其他变化。 如何计算朴素预测?朴素预测计算:朴素预测非常简单,几乎可以用 Excel 表格模板完成。方法是输入特定时期(例如,可以是一年或几个季度的月度数据)的实际销售数据,例如最近两年。 为了对后续的每个时期进行预测,您只需将前一期的销售数据用作当前时期的预测。例如,如果数据是按月间隔的,那么预测当前年份一月份的销售额,将使用前一年一月份的销售数据。 误差计算和方差分析:由于朴素预测技术很简单,并且不考虑可能影响预测的几个因素,因此通过衡量预测偏差或预测值与实际销售额之间的差异来评估预测的可信度非常重要。 该公式有助于确定预测值与实际销售额的偏离程度。
方差解读
季节性朴素预测季节性是您的销售数据在很长一段时间内可能出现的一种现象;您很可能会发现数据是周期性的,并且有与季节相关的趋势。例如,一家生产毛衣的公司在年末最后一个季度到新年伊始可能会经历巨大的需求,而在年中到年末可能会需求较低。另一方面,专注于销售太阳裙的商家可能会发现它们在温暖的月份受欢迎,而在寒冷的月份则不受欢迎。 季节性朴素预测基本上基于朴素预测法,但将季节性纳入了该过程。这种方法根据销售数据的季节性特点调整预测,因此有可能为一年中的不同季节提供更好的预测。 窗口平均预测窗口平均模型的工作方式非常基本;它首先定义一个窗口大小,然后,对于每个时间序列,计算最近窗口大小个点的平均值。关键在于要清楚,这种方法实际上考虑了“窗口”中的最近观测值(数量固定),并计算其平均值。然后,此值用于根据当前数据集中的值来预测数据集的下一个值。 这种方法对于去除时间序列数据中的噪声特别有用,从而在短时期内揭示趋势。这意味着,通过对窗口内的值进行平均,该模型能够减少由于个体值出现不规则变化而对模型产生的影响。因此,它可以提供更少波动且更准确的未来预测,这在数据波动性很高的情况下可能很有帮助。 尽管窗口平均模型相对简单,但它可以在各种时间序列分析应用中用于过滤噪声并生成基本预测。然而,它不考虑长期季节性或趋势,因此更适用于相对平衡的序列或作为其他模型的一部分。 季节性窗口平均预测季节性朴素模型是通过扩展简单的朴素方法而开发的,在该方法中,预测值是通过前一个周期中同一季节的上一个值来确定的。季节性朴素与纯朴素模型不同,它使用前一个相同季节的周期进行预测。在此模型中,强烈的季节性很有用,因为所使用的模型将应用同一类型的周期。 例如,如果要预测下周五的销售额,模型将使用上周五的销售额,或者上周、上个月或上年同一时期的其他周五的销售额。这使得预测更能与典型的周/双周/月度预期保持一致,因为它考虑到销售额在周五可能与一周中的其他任何一天遵循不同的趋势。 朴素预测的问题朴素方法易于计算,但可能不是最准确或最可靠的方法。之前没有讨论过的是,朴素预测法并未考虑可能影响需求波动的几个重要因素。 例如,您可以解释这些因素,如您当前销售额与预测销售额之间的百分比差异,我们之前已讨论过。实际上,高于 1 的比率表明方差很高,例如,41% 的方差意味着您销售的产品比预测的多了 41%。也许如果您没有缺货,并且您的库存水平仅比预测高 41%,您本可以销售更多。另一方面,如果方差为 -41%,则表示您的销售额低于预期,导致公司拥有比需要更多的库存。由于仓储费用,库存成本也更高,对于食品行业的公司来说,这种盈余可能导致变质或所谓的“死库存”。 在当今这个需求激烈且极不稳定的世界中,朴素预测可能是一种极具破坏性的策略。销售额的波动可能导致您预测到需求变化,从而可能导致您订购过多的库存,这会在其他时期导致更多损失。另一方面,需求的急剧下降可能导致缺货情况,从而错过潜在的销售机会,并可能将客户流失给竞争对手。此外,需求计划者难以理解导致这些波动的因素,这阻碍了他们在预测和库存技术方面的改进。 在这种动态的商业环境中,仅仅使用基本技术不足以得出正确的需求预测;这就需要一个考虑某些因素和市场波动性的模型。这将能够实现更有效的库存控制,并最终最大限度地减少库存过剩或库存不足的情况,这两种情况分别对盈利能力和客户关系都有害。 要在 Python 中实现朴素预测,我们将使用 statsforecast 库,该库提供了流行朴素模型的访问权限,用于在 Python 中实现时间序列预测。 要安装 stats forecast 库,请打开命令提示符并输入命令 让我们来实现 Python 中的朴素预测。在这里,我们有来自 Favorita 连锁店 2013 年至 2017 年的销售数据。要实现朴素预测,让我们导入所需的库。 代码 说明 Pandas 用于执行数据分析和操作,numpy 涉及数据操作;matplotlib 用于图形说明。此外,它从 stats forecast 包中导入 StatsForecast 类以及一些预测模型功能,例如 Naive、SeasonalNaive、WindowAverage 和 SeasonalWindowAverage。这些模型通过尝试重现数据的模式(例如平均值和季节性)来生成简单的时序预测,从而利用数据过去的趋势和模式进行预测。 导入库后,让我们加载数据,即我们的 train.csv 文件。 代码 输出 date store_nbr family sales onpromotion id 0 2013-01-01 1 AUTOMOTIVE 0.0 0 1 2013-01-01 1 BABY CARE 0.0 0 2 2013-01-01 1 BEAUTY 0.0 0 3 2013-01-01 1 BEVERAGES 0.0 0 4 2013-01-01 1 BOOKS 0.0 0 说明 上面的代码将包含存储销售数据的时序的 CSV 文件加载到 pandas DataFrame 中。它将“id”列设置为 DataFrame 的索引,并将“date”列转换为 datetime 以便进行灵活的操作。df.head() 函数用于显示 DataFrame 的前五行,以便可以初步了解数据。 让我们定义加权平均绝对百分比误差 (WMAPE) 来衡量预测的准确性。 代码 上面的代码单元建立了一个函数映射,该函数接受两个参数来给出加权平均绝对百分比误差 (WMAPE)。由于它量化了预测值与实际值之间的误差,因此它能够提供一个与平均绝对误差等其他度量标准进行标准化的误差,平均绝对误差计算了时间序列预测中实际值 y_true 和预测值 y_pred 之间的绝对误差的平均值。 让我们预处理数据。 代码 输出 ds unique_id y id 24 2013-01-01 MEATS 0.000 25 2013-01-01 PERSONAL CARE 0.000 1806 2013-01-02 MEATS 369.101 1807 2013-01-02 PERSONAL CARE 194.000 3588 2013-01-03 MEATS 272.319 3589 2013-01-03 PERSONAL CARE 153.000 5370 2013-01-04 MEATS 454.172 5371 2013-01-04 PERSONAL CARE 88.000 7152 2013-01-05 MEATS 328.940 7153 2013-01-05 PERSONAL CARE 141.000 说明 上面的代码单元用于仅选择必要的记录,即 store nbr 为 1 且 org_product_family 为 MEATS 或 PERSONAL CARE 的记录。然后,它在列选择步骤中仅获取日期、家族和销售额。过滤后,对列进行重命名:例如,变量 'date' 被转换为 'ds','sales' 被转换为 'y',而 'family' 被转换为 'unique_id',可能是为了创建时间序列分析所需的格式。最后,df.head(10) 显示修改后的数据帧样本的前 10 行以供参考。 让我们将数据分为训练集和验证集。训练数据用于训练预测模型,验证数据用于测试和验证模型。 代码 输出 ds unique_id y 0 2013-01-01 MEATS 0.000 1 2013-01-01 PERSONAL CARE 0.000 2 2013-01-02 MEATS 369.101 3 2013-01-02 PERSONAL CARE 194.000 4 2013-01-03 MEATS 272.319 5 2013-01-03 PERSONAL CARE 153.000 6 2013-01-04 MEATS 454.172 7 2013-01-04 PERSONAL CARE 88.000 8 2013-01-05 MEATS 328.940 9 2013-01-05 PERSONAL CARE 141.000 说明 此代码基于 '2017-01-01' 的日期将 pandas 数据帧 df 的数据集分别拆分为 pandas 数据帧 train 和 valid 的训练集和验证集。训练集包含 2017 年之前的数据,而验证集包含 2017 年 1 月 1 日至 2017 年 4 月 1 日之间的数据。为了更清楚,此公式计算 h,即验证集中不同天数的计数。然后,它创建一个名为 'dec25' 的列表,用于插入 2013 年至 2016 年 12 月 25 日 MEATS 和 PERSONAL CARE 产品系列的假设值,其销售额为相应年份 12 月 18 日的销售额。然后,它将此新数据附加到 train DataFrame,然后再次根据 'ds'(或日期)重新排列整个数据。 代码 输出 StatsForecast(models=[Naive,SeasonalNaive,WindowAverage,SeasWA]) 说明 在此代码片段中,使用 StatsForecast 八重奏(octet)创建了时间序列预测配置。它首先使用适合各种预测类型的类,例如 Naive 类和 SeasonalNaive 类,以及 WindowAverage 类和 SeasonalWindowAverage 类。每个模型都有独特的特性:最后一个方法 Naive 提供连续值作为预测;SeasonalNaive 提供一周的模式,季节长度为一周;WindowAverage 提供大小为 7 的移动平均;SeasonalWindowAverage 是季节性调整的组合,其中窗口大小为 2,季节长度为 7 天。然后使用这些模型初始化 StatsForecast,其中日频率表示为 'D',并行计算设置为 n_jobs=-1。设置模型后,fit 方法用于使用给定的训练数据集特征来训练模型。这使得模型能够基于历史输入数据进行预测。 代码 输出 unique_id ds Naive SeasonalNaive WindowAverage SeasWA y 0 MEATS 2017-01-01 187.434006 176.259995 251.70929 176.259995 0.000 1 MEATS 2017-01-02 187.434006 80.884003 251.70929 161.768997 116.724 2 MEATS 2017-01-03 187.434006 229.281006 251.70929 249.756500 344.583 3 MEATS 2017-01-04 187.434006 236.942001 251.70929 279.700500 326.203 4 MEATS 2017-01-05 187.434006 234.882004 251.70929 273.109985 274.205 5 MEATS 2017-01-06 187.434006 616.281982 251.70929 725.903503 720.991 6 MEATS 2017-01-07 187.434006 187.434006 251.70929 189.695999 254.636 7 MEATS 2017-01-08 187.434006 176.259995 251.70929 176.259995 122.859 8 MEATS 2017-01-09 187.434006 80.884003 251.70929 161.768997 274.457 9 MEATS 2017-01-10 187.434006 229.281006 251.70929 249.756500 354.819 10 MEATS 2017-01-11 187.434006 236.942001 251.70929 279.700500 335.086 11 MEATS 2017-01-12 187.434006 234.882004 251.70929 273.109985 253.676 12 MEATS 2017-01-13 187.434006 616.281982 251.70929 725.903503 768.371 13 MEATS 2017-01-14 187.434006 187.434006 251.70929 189.695999 258.474 14 MEATS 2017-01-15 187.434006 176.259995 251.70929 176.259995 119.443 15 MEATS 2017-01-16 187.434006 80.884003 251.70929 161.768997 263.016 16 MEATS 2017-01-17 187.434006 229.281006 251.70929 249.756500 241.312 17 MEATS 2017-01-18 187.434006 236.942001 251.70929 279.700500 277.846 18 MEATS 2017-01-19 187.434006 234.882004 251.70929 273.109985 259.604 19 MEATS 2017-01-20 187.434006 616.281982 251.70929 725.903503 733.804 20 MEATS 2017-01-21 187.434006 187.434006 251.70929 189.695999 281.905 21 MEATS 2017-01-22 187.434006 176.259995 251.70929 176.259995 95.406 22 MEATS 2017-01-23 187.434006 80.884003 251.70929 161.768997 243.851 23 MEATS 2017-01-24 187.434006 229.281006 251.70929 249.756500 248.489 24 MEATS 2017-01-25 187.434006 236.942001 251.70929 279.700500 315.459 25 MEATS 2017-01-26 187.434006 234.882004 251.70929 273.109985 256.342 26 MEATS 2017-01-27 187.434006 616.281982 251.70929 725.903503 685.893 27 MEATS 2017-01-28 187.434006 187.434006 251.70929 189.695999 238.377 28 MEATS 2017-01-29 187.434006 176.259995 251.70929 176.259995 99.830 29 MEATS 2017-01-30 187.434006 80.884003 251.70929 161.768997 302.193 说明 在代码的第一行,使用 predict 方法获取模型对象对于给定预测范围 h 的预测,并将其分配给变量 p。然后将预测 DataFrame 的索引设置为验证索引,并使用 join 方法将这两个 DataFrame 以 'left' 类型连接起来,键为 'ds' 和 'unique_id' 列。此合并操作旨在将预测值与特定的验证数据合并,这有助于同步预测结果与实际值或其他类型的信息。 |
我们请求您订阅我们的新闻通讯以获取最新更新。