WEBKT

Prophet 线性插值算法详解与 Python 代码实战

13 0 0 0

Prophet 线性插值算法详解与 Python 代码实战

什么是线性插值?

Prophet 中的线性插值实现

Python 代码演示

总结与注意事项

进阶思考

Prophet 线性插值算法详解与 Python 代码实战

大家好,我是你们的技术老 বন্ধু 序哥。今天咱们来聊聊 Facebook 开源的时间序列预测神器 Prophet 中的一个重要组成部分:线性插值算法。相信不少搞数据分析、机器学习的小伙伴都或多或少接触过 Prophet,它在处理具有季节性和趋势性的时间序列数据时表现非常出色。但是,在使用 Prophet 的过程中,你有没有思考过它是如何处理缺失值的呢?没错,Prophet 内部就使用了线性插值算法来填充缺失数据。那么,什么是线性插值?Prophet 又是如何具体实现线性插值的?别急,接下来序哥就带你一步步揭开它的神秘面纱。

什么是线性插值?

在开始深入代码之前,咱们先来搞清楚线性插值的基本概念。想象一下,你手里有一组时间序列数据,但是由于各种原因(比如传感器故障、数据传输错误等),其中有一些数据点缺失了。这时候,我们就需要想办法把这些缺失的数据补上,而线性插值就是一种常用的数据填充方法。

线性插值的基本思想非常简单:假设缺失点两侧的数据点是已知的,那么我们可以用一条直线连接这两个已知点,然后根据缺失点的时间戳,在这条直线上找到对应的值,作为缺失点的估计值。是不是很简单粗暴?但是,在很多情况下,这种简单的方法却非常有效。

用数学公式来表示的话,假设我们有两个已知点 (x1, y1) 和 (x2, y2),其中 x 表示时间戳,y 表示对应的值。现在有一个缺失点 x,我们需要估计它的值 y。那么,根据线性插值的公式,我们可以这样计算:

y = y1 + (y2 - y1) * (x - x1) / (x2 - x1)

这个公式看起来有点复杂,但其实就是初中数学里学过的两点式直线方程。你可以把它理解为:缺失点的估计值 = 第一个已知点的值 + (第二个已知点的值 - 第一个已知点的值) * (缺失点的时间戳 - 第一个已知点的时间戳) / (第二个已知点的时间戳 - 第一个已知点的时间戳)。

Prophet 中的线性插值实现

了解了线性插值的基本原理之后,我们来看看 Prophet 是如何具体实现线性插值的。在 Prophet 的源码中,线性插值的实现主要位于 forecaster.py 文件中的 _linear_interpolation 函数中。为了方便大家理解,我把这个函数的代码简化了一下,并加上了详细的注释:

import numpy as np
import pandas as pd
def _linear_interpolation(ts, missing_dates):
"""
Prophet 中线性插值的核心函数。
参数:
ts (pd.Series): 包含缺失值的时间序列数据。
missing_dates (pd.DatetimeIndex): 缺失日期的索引。
返回:
pd.Series: 经过线性插值填充后的时间序列数据。
"""
# 复制一份时间序列数据,避免修改原始数据
ts_interp = ts.copy()
# 遍历所有缺失日期
for date in missing_dates:
# 找到缺失日期前后的第一个非缺失值
prev_date = ts[ts.index < date].dropna().index[-1] if len(ts[ts.index < date].dropna()) >0 else None
next_date = ts[ts.index > date].dropna().index[0] if len(ts[ts.index > date].dropna()) >0 else None
# 如果缺失日期前后都有非缺失值,则进行线性插值
if prev_date is not None and next_date is not None:
prev_val = ts[prev_date]
next_val = ts[next_date]
# 使用线性插值公式计算缺失值
ts_interp[date] = prev_val + (next_val - prev_val) * (date - prev_date).total_seconds() / (next_date - prev_date).total_seconds()
# 如果缺失日期前面没有非缺失值,则用后面的值填充。
elif next_date is not None:
ts_interp[date] = ts[next_date]
# 如果缺失日期后面没有非缺失值,则用前面的值填充。
elif prev_date is not None:
ts_interp[date] = ts[prev_date]
return ts_interp

这段代码的核心逻辑如下:

  1. 复制时间序列数据: 首先,为了避免修改原始数据,我们创建了一个时间序列数据的副本 ts_interp
  2. 遍历缺失日期: 然后,我们遍历所有缺失日期 missing_dates
  3. 查找前后非缺失值: 对于每个缺失日期,我们分别查找它之前的第一个非缺失值 prev_date 和之后的第一个非缺失值 next_date
  4. 线性插值: 如果 prev_datenext_date 都存在(即缺失日期前后都有非缺失值),我们就使用前面介绍的线性插值公式计算缺失值,并将其填充到 ts_interp 中。
  5. **边界情况:**如果缺失日期前面或后面没有数据,则用后面的值或者前面的值填充
  6. 返回结果: 最后,我们返回经过线性插值填充后的时间序列数据 ts_interp

Python 代码演示

为了更直观地展示 Prophet 中线性插值的效果,我们来看一个具体的 Python 代码示例。假设我们有以下一组时间序列数据,其中包含一些缺失值:

data = {
'ds': pd.to_datetime(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-05', '2023-01-06', '2023-01-08']),
'y': [10, 12, 14, None, 18, None]
}
df = pd.DataFrame(data)
df = df.set_index('ds')
print(df)

输出:

y
ds
2023-01-01 10.0
2023-01-02 12.0
2023-01-03 14.0
2023-01-05 NaN
2023-01-06 18.0
2023-01-08 NaN

可以看到,2023-01-05 和 2023-01-08 两个日期的数据缺失了。现在,我们使用上面定义的 _linear_interpolation 函数来填充这些缺失值:

# 找出缺失日期的索引
missing_dates = df[df['y'].isnull()].index
# 使用线性插值填充缺失值
df_interp = _linear_interpolation(df['y'], missing_dates)
print(df_interp)

输出:

2023-01-01 10.0
2023-01-02 12.0
2023-01-03 14.0
2023-01-05 16.0
2023-01-06 18.0
2023-01-08 18.0
Name: y, dtype: float64

可以看到,经过线性插值后,2023-01-05 的缺失值被填充为 16.0((14+18)/2),2023-01-08 的缺失值被填充为 18.0(因为后面没有数据,所以用前面的数据填充)。

总结与注意事项

通过本文的介绍,相信你已经对 Prophet 中的线性插值算法有了一个比较全面的了解。线性插值是一种简单而有效的数据填充方法,在很多情况下都可以取得不错的效果。但是,在使用线性插值时,也需要注意以下几点:

  • 数据趋势: 线性插值假设数据在缺失点附近是线性变化的。如果数据的变化趋势比较复杂(比如存在明显的非线性关系),那么线性插值的结果可能不够准确。
  • 缺失值比例: 如果缺失值的比例过高,那么线性插值的结果可能无法反映数据的真实情况。一般来说,缺失值的比例不宜超过 20%。
  • 边界情况: 对于时间序列数据的开头和结尾处的缺失值,线性插值可能无法找到足够的信息来进行填充。在这种情况下,可以考虑使用其他方法(比如使用相邻值填充、使用均值填充等)。

总的来说,线性插值是一种非常实用的数据处理技巧,掌握它可以帮助你更好地处理时间序列数据中的缺失值问题。希望本文对你有所帮助,如果你有任何问题或者想进一步了解 Prophet 的其他功能,欢迎在评论区留言,序哥会尽力解答。

进阶思考

除了线性插值,Prophet 还支持其他的插值方法吗?

答:Prophet 主要使用线性插值来处理缺失值。虽然 Prophet 本身并没有直接提供其他插值方法的选项,但是你可以通过预处理数据的方式来实现其他插值方法,比如样条插值、多项式插值等。你可以使用 Pandas 或者 SciPy 等库中的插值函数来对数据进行预处理,然后再将处理后的数据输入到 Prophet 中进行预测。

Prophet 如何处理周期性缺失值?

答:如果你的数据存在周期性缺失(比如每周的某一天总是缺失数据),那么线性插值可能不是最佳选择。在这种情况下,你可以考虑使用 Prophet 的周期性组件来处理缺失值。Prophet 可以自动检测数据中的周期性模式,并将其纳入预测模型中。这样,即使某些日期的数据缺失,Prophet 也可以根据周期性模式来预测这些日期的值。

序哥 Prophet时间序列线性插值

评论点评

打赏赞助
sponsor

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

分享

QRcode

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