WEBKT

Prophet 时间序列预测:缺失值处理与实战技巧

14 0 0 0

一、 为什么缺失值是“拦路虎”?

二、 Prophet 缺失值处理策略: 你需要知道的

2.1 Prophet 内置的缺失值处理方法

2.2 深入理解 Prophet 的 fit 方法

2.3 如何查看 Prophet 处理后的数据?

三、 实战演练: 如何在 Prophet 中处理缺失值?

3.1 准备数据

3.2 使用 Prophet 进行预测

3.3 评估预测结果

3.4 改进策略: 结合业务知识与参数调整

策略一: 尝试不同的插补方法

策略二: 结合业务知识,自定义缺失值处理方法

策略三: 调整模型参数

四、 案例分析: 真实场景下的缺失值处理

4.1 案例背景

4.2 解决方案

4.3 代码示例

五、 总结: 掌握 Prophet 缺失值处理的“葵花宝典”

你好,我是老K,一个在时间序列预测领域摸爬滚打了多年的老家伙。今天,咱们来聊聊 Prophet 这个好用的时间序列预测工具,以及在实际应用中经常会遇到的一个“拦路虎”—— 缺失值。 别看缺失值不起眼,处理不好,预测结果可就“惨不忍睹”了。

一、 为什么缺失值是“拦路虎”?

在真实世界的数据中,缺失值几乎是不可避免的。可能是由于数据采集的错误、传感器故障、数据传输中断,或者仅仅是数据未被记录等等。这些缺失值,就好比是拼图里的“残片”,会直接影响到我们对整个“拼图”的理解。

具体来说,缺失值会带来以下问题:

  1. 模型训练偏差: Prophet 模型在训练时,会试图学习数据中的模式。如果数据中存在大量缺失值,模型可能无法准确地捕捉到这些模式,导致预测结果出现偏差。
  2. 预测准确性降低: 缺失值会影响模型的拟合程度,使得模型在预测未来的数据时,无法准确地反映真实的趋势和季节性,从而降低预测的准确性。
  3. 分析结果误导: 在进行时间序列分析时,缺失值可能导致我们对数据的理解出现偏差,例如,低估或高估某个时间段内的实际情况。

二、 Prophet 缺失值处理策略: 你需要知道的

幸运的是,Prophet 已经提供了一些处理缺失值的“武器”,但要真正用好它们,还需要结合实际情况,灵活运用。咱们先来看看 Prophet 内部的处理机制,再来探讨如何结合业务知识,进行更精细的调整。

2.1 Prophet 内置的缺失值处理方法

Prophet 在处理缺失值方面,主要依赖于以下两种方式:

  • 线性插补: 这是 Prophet 默认的缺失值处理方法。对于时间序列中的缺失值,Prophet 会使用线性插补的方式进行填充。这意味着,对于缺失值,Prophet 会根据缺失值前后两个已知值的线性关系,计算出缺失值应该取的值。这种方法简单易行,适用于数据缺失量不大的情况。

  • 忽略缺失值: 在某些情况下,如果缺失值比较多,或者缺失值对预测结果的影响较小,Prophet 可能会选择忽略缺失值。具体来说,Prophet 会将缺失值所在的时间点,从训练数据中剔除,从而避免缺失值对模型训练的影响。但是,这种方法可能会导致模型在某些时间段内,缺乏足够的数据进行学习,从而影响预测的准确性。

2.2 深入理解 Prophet 的 fit 方法

在使用 Prophet 进行时间序列预测时,核心步骤就是调用 fit 方法。 实际上,fit 方法内部就包含了缺失值处理的逻辑。 你不需要手动进行缺失值填充, Prophet 会自动完成。 不过,了解 fit 方法的细节,有助于我们更好地理解 Prophet 的处理方式,并在必要的时候,进行更精细的控制。

在 Prophet 的 fit 方法中,主要的处理流程如下:

  1. 数据预处理: fit 方法首先会对输入的数据进行预处理,包括检查数据的格式、排序等。 在这个过程中,Prophet 会自动识别缺失值。
  2. 线性插补: 如果数据中存在缺失值,并且 n_changepoints (突变点数量) 参数没有被设置,或者设置的数值没有影响到缺失值,Prophet 就会使用线性插补的方式,对缺失值进行填充。
  3. 模型训练: 在缺失值被处理后, Prophet 会使用处理后的数据,进行模型训练。 训练过程包括,确定趋势项、季节性项,以及节假日效应等。

2.3 如何查看 Prophet 处理后的数据?

虽然 Prophet 自动处理了缺失值,但我们仍然有必要去了解 Prophet 内部到底是如何处理的。 这样做,可以帮助我们评估处理的效果,并根据需要进行调整。 你可以通过以下方式,查看 Prophet 处理后的数据:

  • 使用 predict 方法: 在调用 predict 方法进行预测时, Prophet 会使用处理后的数据,进行预测。 你可以通过查看预测结果,来间接了解 Prophet 的缺失值处理效果。
  • 查看模型参数: 在模型训练完成后,你可以查看模型内部的参数,例如,趋势项的参数、季节性项的参数等。 这些参数可以反映出,模型对数据的拟合程度,以及对缺失值的处理效果。

三、 实战演练: 如何在 Prophet 中处理缺失值?

理论讲了这么多,咱们还是得“撸起袖子”干起来,通过实际案例,来体验一下如何在 Prophet 中处理缺失值。 为了便于理解,我将通过以下几个方面进行讲解:

  1. 准备数据: 模拟一个包含缺失值的时间序列数据。
  2. 使用 Prophet 进行预测: 直接使用 Prophet 进行预测,观察预测结果。
  3. 评估预测结果: 使用一些评估指标,来衡量预测的准确性。
  4. 改进策略: 尝试不同的缺失值处理方法,以及模型参数调整,来提高预测的准确性。

3.1 准备数据

首先,我们需要准备一个包含缺失值的时间序列数据。 这里,我们使用 Python 的 pandas 库,来模拟一个简单的时间序列,并随机引入缺失值。 数据包括日期 (ds) 和数值 (y) 两列。

import pandas as pd
import numpy as np
from prophet import Prophet
from sklearn.metrics import mean_squared_error, mean_absolute_error
# 生成模拟数据
np.random.seed(0)
dates = pd.date_range(start='2023-01-01', end='2023-12-31')
y_values = np.sin(2 * np.pi * np.arange(len(dates)) / 30) + np.random.normal(0, 0.2, len(dates))
df = pd.DataFrame({'ds': dates, 'y': y_values})
# 随机引入缺失值
missing_indices = np.random.choice(len(df), size=int(0.1 * len(df)), replace=False)
df.loc[missing_indices, 'y'] = np.nan
print(df.head())
print(df.isnull().sum())

运行这段代码,你将得到一个包含缺失值的数据集。 df.head() 会显示数据的前几行,df.isnull().sum() 会显示每列缺失值的数量。 从输出结果可以看出,我们的数据中确实存在缺失值。

3.2 使用 Prophet 进行预测

接下来,我们使用 Prophet 来对这个数据集进行预测。

# 创建 Prophet 模型
model = Prophet()
# 拟合模型
model.fit(df)
# 创建未来时间序列
future = model.make_future_dataframe(periods=30)
# 进行预测
forecast = model.predict(future)
# 打印预测结果
print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())
# 可视化预测结果
fig1 = model.plot(forecast)
fig2 = model.plot_components(forecast)

在这段代码中,我们首先创建了一个 Prophet 模型,然后使用 fit 方法,对数据进行训练。 接着,我们使用 make_future_dataframe 方法,创建了未来的时间序列,用于预测。 最后,我们使用 predict 方法,进行预测,并打印了预测结果,以及可视化了预测结果。

3.3 评估预测结果

仅仅看到预测结果,我们还不能判断预测的准确性。 我们需要使用一些评估指标,来衡量预测的准确性。 常用的评估指标包括:

  • 均方根误差 (RMSE): RMSE 衡量了预测值与真实值之间的差异。 RMSE 越小,表示预测的准确性越高。
  • 平均绝对误差 (MAE): MAE 衡量了预测值与真实值之间的平均绝对差异。 MAE 越小,表示预测的准确性越高。

为了计算这些指标,我们需要将预测结果,与真实值进行比较。 由于我们的数据中,只有部分时间点有真实值,因此,我们需要将预测结果,与真实值进行对齐。

# 准备评估数据
forecast_df = forecast.set_index('ds')
true_df = df.dropna().set_index('ds')
# 合并预测值和真实值
merged_df = forecast_df.join(true_df, how='inner')
# 计算评估指标
rmse = np.sqrt(mean_squared_error(merged_df['y'], merged_df['yhat']))
mae = mean_absolute_error(merged_df['y'], merged_df['yhat'])
print(f'RMSE: {rmse}')
print(f'MAE: {mae}')

在这段代码中,我们首先将预测结果和真实值,按照日期 (ds) 进行对齐。 然后,我们使用 mean_squared_errormean_absolute_error 函数,计算了 RMSE 和 MAE。 通过查看这些指标,我们可以评估预测的准确性。

3.4 改进策略: 结合业务知识与参数调整

如果预测结果不理想,我们需要采取一些改进策略,来提高预测的准确性。 以下是一些常用的策略:

  • 数据清洗: 在进行预测之前,对数据进行清洗,可以提高预测的准确性。 例如,我们可以使用插补方法,对缺失值进行填充。 除了线性插补,还可以尝试其他的插补方法,例如,均值插补、中位数插补、或者使用更复杂的插补模型。
  • 特征工程: 增加额外的特征,可以提高模型的预测能力。 例如,我们可以添加节假日信息、天气信息、或者其他相关的业务指标。
  • 参数调整: 调整 Prophet 模型中的参数,可以优化预测结果。 例如,我们可以调整 changepoint_prior_scaleseasonality_prior_scale 等参数,来控制模型的拟合程度。 此外,我们还可以调整季节性参数,例如,调整季节性的周期、幅度等。

策略一: 尝试不同的插补方法

前面我们提到, Prophet 默认使用线性插补。 那么,我们是否可以尝试其他插补方法呢? 当然可以! 例如,我们可以使用均值插补,或者中位数插补。 在 pandas 库中,提供了 fillna 方法,可以方便地进行缺失值填充。

# 均值插补
df_mean = df.copy()
df_mean['y'].fillna(df_mean['y'].mean(), inplace=True)
# 中位数插补
df_median = df.copy()
df_median['y'].fillna(df_median['y'].median(), inplace=True)
# 使用 Prophet 预测 (均值插补)
model_mean = Prophet()
model_mean.fit(df_mean)
future_mean = model_mean.make_future_dataframe(periods=30)
forecast_mean = model_mean.predict(future_mean)
# 评估预测结果
forecast_mean_df = forecast_mean.set_index('ds')
merged_mean_df = forecast_mean_df.join(true_df, how='inner')
rmse_mean = np.sqrt(mean_squared_error(merged_mean_df['y'], merged_mean_df['yhat']))
mae_mean = mean_absolute_error(merged_mean_df['y'], merged_mean_df['yhat'])
print(f'Mean Imputation - RMSE: {rmse_mean}, MAE: {mae_mean}')
# 使用 Prophet 预测 (中位数插补)
model_median = Prophet()
model_median.fit(df_median)
future_median = model_median.make_future_dataframe(periods=30)
forecast_median = model_median.predict(future_median)
# 评估预测结果
forecast_median_df = forecast_median.set_index('ds')
merged_median_df = forecast_median_df.join(true_df, how='inner')
rmse_median = np.sqrt(mean_squared_error(merged_median_df['y'], merged_median_df['yhat']))
mae_median = mean_absolute_error(merged_median_df['y'], merged_median_df['yhat'])
print(f'Median Imputation - RMSE: {rmse_median}, MAE: {mae_median}')

通过比较不同插补方法的 RMSE 和 MAE,我们可以选择最适合的插补方法。

策略二: 结合业务知识,自定义缺失值处理方法

除了使用通用的插补方法,我们还可以结合业务知识,自定义缺失值处理方法。 例如,如果我们的数据是电商平台的销售数据,那么,缺失值可能发生在周末,因为周末的销售额通常较低。 在这种情况下,我们可以使用周末的销售额的平均值,来填充缺失值。

# 模拟业务知识,周末缺失值使用周末平均值填充
df_business = df.copy()
# 找到周末的索引
df_business['dayofweek'] = df_business['ds'].dt.dayofweek
weekend_indices = df_business[df_business['dayofweek'].isin([5, 6])].index
# 计算周末销售额的平均值
weekend_mean = df_business.loc[~weekend_indices, 'y'].mean()
# 使用周末平均值填充缺失值
df_business.loc[weekend_indices, 'y'] = df_business.loc[weekend_indices, 'y'].fillna(weekend_mean)
# 使用 Prophet 预测 (业务知识插补)
model_business = Prophet()
model_business.fit(df_business)
future_business = model_business.make_future_dataframe(periods=30)
forecast_business = model_business.predict(future_business)
# 评估预测结果
forecast_business_df = forecast_business.set_index('ds')
merged_business_df = forecast_business_df.join(true_df, how='inner')
rmse_business = np.sqrt(mean_squared_error(merged_business_df['y'], merged_business_df['yhat']))
mae_business = mean_absolute_error(merged_business_df['y'], merged_business_df['yhat'])
print(f'Business Knowledge Imputation - RMSE: {rmse_business}, MAE: {mae_business}')

在这个例子中,我们根据业务知识,对缺失值进行了特殊的处理,从而提高了预测的准确性。

策略三: 调整模型参数

Prophet 模型中有很多参数,可以用来调整模型的拟合程度。 例如,changepoint_prior_scale 参数,可以控制模型对趋势变化的敏感度。 seasonality_prior_scale 参数,可以控制模型对季节性变化的敏感度。

# 调整 changepoint_prior_scale 参数
model_changepoint = Prophet(changepoint_prior_scale=0.1)
model_changepoint.fit(df)
future_changepoint = model_changepoint.make_future_dataframe(periods=30)
forecast_changepoint = model_changepoint.predict(future_changepoint)
# 评估预测结果
forecast_changepoint_df = forecast_changepoint.set_index('ds')
merged_changepoint_df = forecast_changepoint_df.join(true_df, how='inner')
rmse_changepoint = np.sqrt(mean_squared_error(merged_changepoint_df['y'], merged_changepoint_df['yhat']))
mae_changepoint = mean_absolute_error(merged_changepoint_df['y'], merged_changepoint_df['yhat'])
print(f'Changepoint Prior Scale - RMSE: {rmse_changepoint}, MAE: {mae_changepoint}')
# 调整 seasonality_prior_scale 参数
model_seasonality = Prophet(seasonality_prior_scale=10)
model_seasonality.fit(df)
future_seasonality = model_seasonality.make_future_dataframe(periods=30)
forecast_seasonality = model_seasonality.predict(future_seasonality)
# 评估预测结果
forecast_seasonality_df = forecast_seasonality.set_index('ds')
merged_seasonality_df = forecast_seasonality_df.join(true_df, how='inner')
rmse_seasonality = np.sqrt(mean_squared_error(merged_seasonality_df['y'], merged_seasonality_df['yhat']))
mae_seasonality = mean_absolute_error(merged_seasonality_df['y'], merged_seasonality_df['yhat'])
print(f'Seasonality Prior Scale - RMSE: {rmse_seasonality}, MAE: {mae_seasonality}')

通过调整这些参数,我们可以优化模型的拟合程度,从而提高预测的准确性。

四、 案例分析: 真实场景下的缺失值处理

理论和实践都讲了,咱们再来结合一个真实的案例,看看在实际工作中,如何处理 Prophet 中的缺失值。 假设你是一家电商公司的数据分析师,需要预测未来一周的销售额。 你的数据包括每日的销售额,但是,由于系统故障,某些天的销售额数据缺失了。

4.1 案例背景

  • 数据来源: 电商平台的每日销售额数据。
  • 数据特点: 数据包含缺失值,缺失值可能发生在周末,也可能发生在工作日。
  • 目标: 预测未来一周的销售额,并尽可能提高预测的准确性。

4.2 解决方案

  1. 数据预处理: 首先,我们需要对数据进行预处理,包括检查数据的格式,以及处理缺失值。 在这里,我们先使用线性插补方法,对缺失值进行填充。 当然,你也可以尝试其他插补方法,并比较不同方法的预测效果。
  2. 特征工程: 为了提高预测的准确性,我们可以添加一些额外的特征。 例如,我们可以添加节假日信息,天气信息,或者其他相关的业务指标。 在这个案例中,我们没有添加节假日信息,因为节假日对销售额的影响,在我们的数据中,可能并不明显。 但是,如果节假日对销售额有明显的影响,那么,添加节假日信息,可以显著提高预测的准确性。
  3. 模型训练: 使用 Prophet 模型,对数据进行训练。 在训练过程中,我们可以根据实际情况,调整 Prophet 模型中的参数。 例如,我们可以调整 changepoint_prior_scale 参数,来控制模型对趋势变化的敏感度。 调整 seasonality_prior_scale 参数,来控制模型对季节性变化的敏感度。
  4. 预测: 使用训练好的模型,对未来一周的销售额进行预测。 在进行预测时,我们需要创建未来时间序列。 创建未来时间序列的方法,就是使用 make_future_dataframe 方法。
  5. 评估: 评估预测结果,并根据需要进行调整。 评估预测结果,可以使用 RMSE、MAE 等评估指标。 如果预测结果不理想,我们可以尝试不同的插补方法、添加额外的特征、或者调整模型参数,来提高预测的准确性。

4.3 代码示例

import pandas as pd
from prophet import Prophet
from sklearn.metrics import mean_squared_error, mean_absolute_error
# 模拟数据 (包含缺失值)
df = pd.DataFrame({
'ds': pd.to_datetime(['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05', '2024-01-06', '2024-01-07',
'2024-01-08', '2024-01-09', '2024-01-10', '2024-01-11', '2024-01-12', '2024-01-13', '2024-01-14']),
'y': [100, 120, np.nan, 150, 140, np.nan, 130,
110, 130, 160, 150, 170, 160, 140]
})
# 1. 数据预处理 (线性插补)
df_filled = df.copy()
df_filled['y'].interpolate(method='linear', inplace=True)
# 2. 模型训练
model = Prophet()
model.fit(df_filled)
# 3. 预测
future = model.make_future_dataframe(periods=7)
forecast = model.predict(future)
# 4. 评估 (可选,如果原始数据有更多)
# 假设我们有2024-01-01 到 2024-01-14 的真实值
# 那么就可以评估
# 5. 结果分析和调整
print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(7))
# 如果预测效果不好,尝试以下调整:
# * 不同的插补方法 (均值、中位数、业务知识)
# * 调整模型参数 (changepoint_prior_scale, seasonality_prior_scale)
# * 增加特征 (节假日,天气等)

在这个案例中,我们通过数据预处理、模型训练、预测和评估,来处理 Prophet 中的缺失值,并提高预测的准确性。 当然,在实际工作中,我们可能需要根据实际情况,进行更多的调整和优化。

五、 总结: 掌握 Prophet 缺失值处理的“葵花宝典”

好了,老K 今天就分享到这里。 咱们一起回顾一下,在 Prophet 中处理缺失值的“葵花宝典”:

  1. 了解 Prophet 的内置处理机制: Prophet 默认使用线性插补处理缺失值,并自动完成。 了解 fit 方法的细节,可以帮助我们更好地理解 Prophet 的处理方式。
  2. 数据预处理是关键: 在进行预测之前,务必对数据进行预处理,包括检查数据的格式,以及处理缺失值。 可以尝试不同的插补方法,并比较不同方法的预测效果。
  3. 结合业务知识: 结合业务知识,自定义缺失值处理方法,可以提高预测的准确性。 例如,根据业务知识,对周末的缺失值进行特殊处理。
  4. 特征工程: 增加额外的特征,可以提高模型的预测能力。 例如,添加节假日信息、天气信息等。
  5. 参数调整: 调整 Prophet 模型中的参数,可以优化预测结果。 例如,调整 changepoint_prior_scaleseasonality_prior_scale 等参数,来控制模型的拟合程度。
  6. 评估和迭代: 评估预测结果,并根据需要进行调整。 这是一个不断迭代的过程。 通过不断尝试不同的方法,我们可以找到最适合的解决方案。

记住,没有完美的解决方案,只有最合适的解决方案。 掌握了这些“葵花宝典”,相信你在使用 Prophet 进行时间序列预测时,就能更加游刃有余,轻松应对缺失值带来的挑战。 祝你在时间序列预测的道路上,越走越远!

如果你有任何问题,欢迎随时和我交流!

老K Prophet时间序列预测缺失值处理数据分析机器学习

评论点评

打赏赞助
sponsor

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

分享

QRcode

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