WEBKT

深入剖析 Prophet 变点函数 changepoint_func:原理、用法与影响

11 0 0 0

changepoint_func:自定义你的变点检测引擎

数据输入格式

内部工作原理

与 changepoint_prior_scale 的交互

影响变点选择

实践案例:自定义 changepoint_func

案例 1:检测趋势的加速变化

案例 2:基于周期性成分的变点检测

案例3: 自定义分段常数变点

案例 4:结合多种变化检测

注意事项

总结

Facebook Prophet 是一个强大的时间序列预测工具,其灵活性的一大来源就是对变点(changepoint)的精细控制。changepoint_func 参数允许你自定义变点检测的底层模型,这为高级用户提供了更深层次的定制能力。今天咱们就来深入探讨一下 changepoint_func,聊聊它的数据输入格式、内部工作原理、与 changepoint_prior_scale 的交互,以及它如何影响最终的变点选择。

changepoint_func:自定义你的变点检测引擎

在 Prophet 中,默认的变点检测方法是基于线性模型的斜率变化。但现实世界的时间序列数据往往更加复杂,可能需要更灵活的变点模型。changepoint_func 参数正是为此而生,它允许你传入一个自定义的函数,该函数将负责计算每个潜在变点的“变化幅度”。

数据输入格式

传给 changepoint_func 的函数需要接受两个主要参数:

  1. t: 一个 NumPy 数组,表示时间序列的时间点(通常是相对于序列起始时间的标准化时间)。
  2. y: 一个 NumPy 数组,表示时间序列的观测值。

你的自定义函数需要返回一个与 t 长度相同的 NumPy 数组,其中每个元素代表对应时间点的“变化幅度”。这个“变化幅度”可以是任何你认为能反映变点可能性的指标。Prophet 会根据这个“变化幅度”来选择最终的变点。

内部工作原理

Prophet 的变点选择过程可以大致概括为以下几个步骤:

  1. 潜在变点生成:Prophet 首先会在时间序列上生成一系列潜在的变点。默认情况下,这些潜在变点会均匀地分布在时间序列的前 80% 范围内(可以通过 changepoints 参数手动指定)。
  2. 变化幅度计算:对于每个潜在变点,Prophet 会调用 changepoint_func(如果你提供了的话,否则使用默认的线性模型)来计算该点的“变化幅度”。
  3. 变点选择:Prophet 会根据 changepoint_prior_scale 参数来调整“变化幅度”的先验分布。changepoint_prior_scale 越大,模型越倾向于选择更多的变点;反之,则倾向于选择更少的变点。最终,Prophet 会从潜在变点中选择一部分作为最终的变点,这些被选中的变点对应的“变化幅度”在调整后的先验分布下具有较高的后验概率。
  4. 模型拟合:在确定了变点之后,Prophet 会使用分段线性模型(或你指定的其他模型)来拟合整个时间序列。

与 changepoint_prior_scale 的交互

changepoint_prior_scale 是一个重要的超参数,它控制着模型对变点的敏感程度。它的值越大,模型就越容易将数据中的波动视为变点,从而选择更多的变点;反之,它的值越小,模型就越倾向于认为数据中的波动是噪声,从而选择更少的变点。

changepoint_funcchangepoint_prior_scale 是协同工作的。changepoint_func 负责计算每个潜在变点的“原始”变化幅度,而 changepoint_prior_scale 则负责对这些“原始”变化幅度进行缩放,从而影响最终的变点选择。

影响变点选择

changepoint_func 的选择直接影响了模型对变点的定义。不同的 changepoint_func 会对数据的不同特征产生不同的敏感度。例如:

  • 默认的线性模型:对趋势的线性变化敏感。
  • 自定义的二次模型:可能对趋势的加速或减速更敏感。
  • 基于傅里叶变换的模型:可能对周期性的变化更敏感。

通过精心设计 changepoint_func,你可以让 Prophet 更好地捕捉到你所关心的变点类型。

实践案例:自定义 changepoint_func

下面,我们通过几个具体的例子来展示如何使用 changepoint_func

案例 1:检测趋势的加速变化

假设我们有一个时间序列,其趋势可能存在加速或减速的变化。我们可以定义一个 changepoint_func 来检测这种变化:

import numpy as np
def quadratic_changepoint_func(t, y):
"""
计算二次模型的斜率变化,用于检测趋势的加速或减速。
"""
# 对时间进行标准化
t_scaled = (t - t.min()) / (t.max() - t.min())
# 拟合二次模型
z = np.polyfit(t_scaled, y, 2)
p = np.poly1d(z)
# 计算二阶导数(斜率的变化率)
second_derivative = p.deriv(m=2)(t_scaled)
return np.abs(second_derivative)

这个函数首先对时间进行标准化,然后拟合一个二次模型,最后计算二次模型的二阶导数(即斜率的变化率)的绝对值作为“变化幅度”。二阶导数的绝对值越大,表示趋势的加速或减速越明显。

案例 2:基于周期性成分的变点检测

如果我们的时间序列具有明显的周期性,我们可能希望基于周期性成分的变化来检测变点。我们可以使用傅里叶变换来实现这一点:

import numpy as np
from scipy.fft import fft
def periodic_changepoint_func(t, y):
"""
基于傅里叶变换的周期性成分变化检测变点。
"""
# 计算傅里叶变换
yf = fft(y)
# 计算幅度谱
amplitude_spectrum = np.abs(yf)
# 计算幅度谱的变化
amplitude_spectrum_change = np.diff(amplitude_spectrum)
# 在两端填充以保持长度一致
amplitude_spectrum_change = np.concatenate(([0], amplitude_spectrum_change, [0]))
return np.abs(amplitude_spectrum_change)

这个函数首先计算时间序列的傅里叶变换,然后计算幅度谱的变化作为“变化幅度”。幅度谱的变化越大,表示周期性成分的变化越明显。

案例3: 自定义分段常数变点

有时候,你可能需要对数据进行分段常数拟合。这种情况下,变点就代表了不同常数段之间的切换点。下面是一个自定义的changepoint_func来实现这个功能:

import numpy as np
def piecewise_constant_changepoint_func(t, y):
"""检测分段常数变化"""
# 计算相邻数据点之间的差值
diffs = np.diff(y)
# 在开头补0,使其与t的长度相同
diffs = np.concatenate(([0], diffs))
# 返回差值的绝对值,作为变化幅度
return np.abs(diffs)

这个函数计算了相邻数据点之间的差值。在分段常数模型中,变点位置的差值会显著大于非变点位置。通过返回差值的绝对值,我们让Prophet更容易识别这些切换点。

案例 4:结合多种变化检测

在许多实际应用中,单一类型的变点检测可能不足以捕捉到所有重要的变化。因此,将多种变化检测方法结合起来可能是一个好主意。下面是一个例子,展示如何结合线性和分段常数检测:

import numpy as np
from prophet.make_seasonality_features import fourier_series
def combined_changepoint_func(t, y):
"""结合线性趋势变化和分段常数变化"""
# 线性趋势变化 (默认的Prophet方法)
m = np.mean(np.diff(y))
linear_change = np.abs(np.diff(y) - m)
linear_change = np.concatenate(([0], linear_change))
# 分段常数变化
piecewise_change = piecewise_constant_changepoint_func(t, y)
# 结合两种变化幅度 (这里简单地取平均)
combined_change = (linear_change + piecewise_change) / 2
return combined_change

在这个例子中,我们结合了默认的线性趋势变化检测和自定义的分段常数变化检测。通过简单地取两种变化幅度的平均值,我们创建了一个新的changepoint_func,它对两种类型的变化都敏感。

注意事项

  • 计算复杂度:自定义的 changepoint_func 可能会增加模型的计算复杂度,特别是当你的函数涉及到复杂的计算时。在设计 changepoint_func 时,要注意平衡模型的准确性和计算效率。
  • 数据预处理:在某些情况下,你可能需要对数据进行预处理,例如去除异常值、填补缺失值等,以提高 changepoint_func 的效果。
  • 参数调优changepoint_prior_scalechangepoint_func 需要结合起来进行调优。你可以通过交叉验证等方法来选择最佳的参数组合。
  • 与其它Prophet组件的交互: changepoint_func主要影响变点检测,但Prophet还有其它组件,如季节性(seasonality)和节假日(holidays)。 当自定义changepoint_func时,要考虑它是否与其它组件产生了意料之外的交互。例如,如果你的changepoint_func过于敏感,可能会错误地将季节性波动识别为变点。

总结

changepoint_func 是 Prophet 中一个强大的工具,它允许你自定义变点检测的逻辑,从而更好地适应各种复杂的时间序列数据。通过深入理解 changepoint_func 的工作原理和使用方法,你可以充分发挥 Prophet 的潜力,构建更准确、更可靠的预测模型。希望这篇深入的讲解能帮助你更好地驾驭 Prophet,成为时间序列预测的高手!

数据占卜师 Prophet时间序列变点检测

评论点评

打赏赞助
sponsor

感谢您的支持让我们更好的前行

分享

QRcode

https://www.webkt.com/article/8814