ExpandingWindowFeatures#

窗口特征是通过对时间序列中过去数据的窗口执行数学运算而创建的变量。

滚动窗口特征 是通过对时间序列数据的过去数据点进行 **滑动分区**(或移动窗口)上的聚合来创建的。在这种情况下,窗口大小是恒定的。

扩展窗口特征 是通过对时间序列的过去值的 扩展分区 进行聚合来创建的。随着我们接近更近期的值,窗口大小会增加。

扩展窗口特征的一个例子是当前行/值之前所有数据点的平均值。当前行之前所有行的最大值是另一个扩展窗口特征。

对于一个适合预测的扩展窗口特征,窗口可以从数据的开始延伸到但不包括第一个预测点。

扩展窗口特征可以通过使用传统的机器学习模型,如线性回归,用于预测。

使用 pandas 扩展窗口特征#

在Python中,我们可以通过利用pandas方法`expanding`来创建扩展窗口特征。例如,通过执行:

X[["var_1", "var_2"].expanding(min_periods=3).agg(["max", "mean"])

通过之前的命令,我们为每个变量 var_1var_2 创建了两个窗口特征,通过取所有观测值到(包括)某一行的最大值和平均值。

如果我们想使用这些特征通过传统的机器学习算法进行预测,我们也会使用 pandas 方法 shift 将窗口向前移动:

X[["var_1", "var_2"].expanding(min_periods=3).agg(["max", "mean"]).shift(period=1)

使用 Feature-engine 扩展窗口特征#

ExpandingWindowFeatures 向数据框添加扩展窗口特征。

窗口特征是通过对过去数据窗口中的变量应用聚合操作(例如,均值、最小值、最大值等)得到的结果。

在预测一个变量的未来值时,该变量的过去值很可能是具有预测性的。为了利用变量的过去值,我们可以简单地使用 LagFeatures 来滞后特征。我们还可以使用 ExpandingWindowFeatures 将过去值汇总为一个单一的量来创建特征。

ExpandingWindowFeatures 基于 pandas.expandingpandas.aggregatepandas.shift 工作。

ExpandingWindowFeatures 使用 pandas.aggregate 在扩展窗口上执行数学运算。因此,您可以使用 pandas 支持的任何操作。有关支持的聚合函数,请参阅扩展窗口 函数

使用 pandas.shiftExpandingWindowFeatures 会延迟扩展窗口操作的结果。这有助于确保仅使用预测时已知的信息来计算窗口特征。因此,如果在预测时我们只知道前一时间段的特征值及其之前的值,那么我们应该将窗口特征延迟一个时间段。如果在预测时我们只知道两周前的特征值及其之前的值,那么我们应该将窗口特征列延迟两周。ExpandingWindowFeatures 使用默认的一个时间段的延迟。

ExpandingWindowFeatures 会将带有代表性名称的新变量添加到原始数据框中。它还具有 fit()transform() 方法,使其与 Scikit-learn 的 Pipeline 和交叉验证函数兼容。

请注意,在当前的实现中,ExpandingWindowFeatures 仅适用于索引(包含时间序列时间戳)包含唯一值且无 NaN 的数据框。

示例#

让我们创建一个玩具数据集来演示 ExpandingWindowFeatures 的功能。该数据框包含3个数值变量、一个分类变量和一个日期时间索引。

import pandas as pd

X = {"ambient_temp": [31.31, 31.51, 32.15, 32.39, 32.62, 32.5, 32.52, 32.68],
     "module_temp": [49.18, 49.84, 52.35, 50.63, 49.61, 47.01, 46.67, 47.52],
     "irradiation": [0.51, 0.79, 0.65, 0.76, 0.42, 0.49, 0.57, 0.56],
     "color": ["green"] * 4 + ["blue"] * 4,
     }

X = pd.DataFrame(X)
X.index = pd.date_range("2020-05-15 12:00:00", periods=8, freq="15min")

y = pd.Series([1,2,3,4,5,6,7,8])
y.index = X.index

X.head()

下面我们看到我们的玩具数据框的输出:

                     ambient_temp  module_temp  irradiation  color
2020-05-15 12:00:00         31.31        49.18         0.51  green
2020-05-15 12:15:00         31.51        49.84         0.79  green
2020-05-15 12:30:00         32.15        52.35         0.65  green
2020-05-15 12:45:00         32.39        50.63         0.76  green
2020-05-15 13:00:00         32.62        49.61         0.42   blue

现在让我们打印出目标:

y

下面我们看到目标变量:

2020-05-15 12:00:00    1
2020-05-15 12:15:00    2
2020-05-15 12:30:00    3
2020-05-15 12:45:00    4
2020-05-15 13:00:00    5
2020-05-15 13:15:00    6
2020-05-15 13:30:00    7
2020-05-15 13:45:00    8
Freq: 15min, dtype: int64

现在我们将从数值变量中创建扩展窗口特征。在 functions 中,我们指定了我们希望在这些窗口上执行的所有操作。在下面的示例中,我们希望计算这些窗口内数据的均值和标准差,并找出窗口内的最大值。

from feature_engine.timeseries.forecasting import ExpandingWindowFeatures

win_f = ExpandingWindowFeatures(functions=["mean", "max", "std"])

X_tr = win_f.fit_transform(X)

X_tr.head()

我们可以在数据框的右侧找到窗口特征。

                     ambient_temp  module_temp  irradiation  color  \
2020-05-15 12:00:00         31.31        49.18         0.51  green
2020-05-15 12:15:00         31.51        49.84         0.79  green
2020-05-15 12:30:00         32.15        52.35         0.65  green
2020-05-15 12:45:00         32.39        50.63         0.76  green
2020-05-15 13:00:00         32.62        49.61         0.42   blue

                     ambient_temp_expanding_mean  ambient_temp_expanding_max  \
2020-05-15 12:00:00                          NaN                         NaN
2020-05-15 12:15:00                    31.310000                       31.31
2020-05-15 12:30:00                    31.410000                       31.51
2020-05-15 12:45:00                    31.656667                       32.15
2020-05-15 13:00:00                    31.840000                       32.39

                     ambient_temp_expanding_std  module_temp_expanding_mean  \
2020-05-15 12:00:00                         NaN                         NaN
2020-05-15 12:15:00                         NaN                   49.180000
2020-05-15 12:30:00                    0.141421                   49.510000
2020-05-15 12:45:00                    0.438786                   50.456667
2020-05-15 13:00:00                    0.512640                   50.500000

                     module_temp_expanding_max  module_temp_expanding_std  \
2020-05-15 12:00:00                        NaN                        NaN
2020-05-15 12:15:00                      49.18                        NaN
2020-05-15 12:30:00                      49.84                   0.466690
2020-05-15 12:45:00                      52.35                   1.672553
2020-05-15 13:00:00                      52.35                   1.368381

                     irradiation_expanding_mean  irradiation_expanding_max  \
2020-05-15 12:00:00                         NaN                        NaN
2020-05-15 12:15:00                      0.5100                       0.51
2020-05-15 12:30:00                      0.6500                       0.79
2020-05-15 12:45:00                      0.6500                       0.79
2020-05-15 13:00:00                      0.6775                       0.79

                     irradiation_expanding_std
2020-05-15 12:00:00                        NaN
2020-05-15 12:15:00                        NaN
2020-05-15 12:30:00                   0.197990
2020-05-15 12:45:00                   0.140000
2020-05-15 13:00:00                   0.126853

用于窗口特征输入的变量存储在 ExpandingWindowFeaturesvariables_ 属性中。

win_f.variables_
['ambient_temp', 'module_temp', 'irradiation']

我们可以使用 get_feature_names_out() 方法获取返回数据框中的变量名称:

win_f.get_feature_names_out()
['ambient_temp',
 'module_temp',
 'irradiation',
 'color',
 'ambient_temp_expanding_mean',
 'ambient_temp_expanding_max',
 'ambient_temp_expanding_std',
 'module_temp_expanding_mean',
 'module_temp_expanding_max',
 'module_temp_expanding_std',
 'irradiation_expanding_mean',
 'irradiation_expanding_max',
 'irradiation_expanding_std']

删除包含 nan 的行#

当我们使用扩展窗口创建窗口特征时,可能会为那些过去数据不足以创建窗口的数据点引入 nan 值。我们可以自动删除在训练集和目标变量中窗口特征包含 nan 值的行,如下所示:

win_f = ExpandingWindowFeatures(
    functions=["mean", "max", "std"],
    drop_na=True,
)

win_f.fit(X)

X_tr, y_tr = win_f.transform_x_y(X, y)

X.shape, y.shape, X_tr.shape, y_tr.shape

我们看到,结果数据框包含的行数少于原始数据框:

(8, 4), (8,), (6, 13), (6,))

填充包含 nan 的行#

如果不想在扩展窗口特征中删除包含 nan 的行,而是想填补这些值,我们可以使用 Feature-engine 的任何插补器来实现。在这里,我们将使用管道中的 MeanMedianImputer 将 nan 替换为结果窗口特征的中值:

from feature_engine.imputation import MeanMedianImputer
from feature_engine.pipeline import Pipeline

win_f = ExpandingWindowFeatures(functions=["mean", "std"])

pipe = Pipeline([
    ("windows", win_f),
    ("imputer", MeanMedianImputer(imputation_method="median"))
])

X_tr = pipe.fit_transform(X, y)

print(X_tr.head())

我们看到生成的数据框,其中 nan 值已被中位数替换:

                     ambient_temp  module_temp  irradiation  color  \
2020-05-15 12:00:00         31.31        49.18         0.51  green
2020-05-15 12:15:00         31.51        49.84         0.79  green
2020-05-15 12:30:00         32.15        52.35         0.65  green
2020-05-15 12:45:00         32.39        50.63         0.76  green
2020-05-15 13:00:00         32.62        49.61         0.42   blue

                     ambient_temp_expanding_mean  ambient_temp_expanding_std  \
2020-05-15 12:00:00                    31.840000                    0.518740
2020-05-15 12:15:00                    31.310000                    0.518740
2020-05-15 12:30:00                    31.410000                    0.141421
2020-05-15 12:45:00                    31.656667                    0.438786
2020-05-15 13:00:00                    31.840000                    0.512640

                     module_temp_expanding_mean  module_temp_expanding_std  \
2020-05-15 12:00:00                   49.770000                   1.520467
2020-05-15 12:15:00                   49.180000                   1.520467
2020-05-15 12:30:00                   49.510000                   0.466690
2020-05-15 12:45:00                   50.456667                   1.672553
2020-05-15 13:00:00                   50.500000                   1.368381

                     irradiation_expanding_mean  irradiation_expanding_std
2020-05-15 12:00:00                      0.6260                   0.146424
2020-05-15 12:15:00                      0.5100                   0.146424
2020-05-15 12:30:00                      0.6500                   0.197990
2020-05-15 12:45:00                      0.6500                   0.140000
2020-05-15 13:00:00                      0.6775                   0.126853

使用 pandas 系列#

如果你的时间序列是一个 pandas Series 而不是一个 pandas Dataframe,你需要在使用 ExpandingWindowFeatures 之前将其转换为 dataframe。

以下是一个 pandas Series:

X['ambient_temp']
2020-05-15 12:00:00    31.31
2020-05-15 12:15:00    31.51
2020-05-15 12:30:00    32.15
2020-05-15 12:45:00    32.39
2020-05-15 13:00:00    32.62
2020-05-15 13:15:00    32.50
2020-05-15 13:30:00    32.52
2020-05-15 13:45:00    32.68
Freq: 15T, Name: ambient_temp, dtype: float64

我们可以使用 ExpandingWindowFeatures 来创建,例如,通过找到一个 pandas Series 的平均值和最大值来创建两个新的扩展窗口特征,如果我们使用 to_frame() 方法将其转换为 pandas Dataframe:

win_f = ExpandingWindowFeatures(functions=["mean", "max"])

X_tr = win_f.fit_transform(X['ambient_temp'].to_frame())

X_tr.head()
                     ambient_temp  ambient_temp_expanding_mean  \
2020-05-15 12:00:00         31.31                          NaN
2020-05-15 12:15:00         31.51                    31.310000
2020-05-15 12:30:00         32.15                    31.410000
2020-05-15 12:45:00         32.39                    31.656667
2020-05-15 13:00:00         32.62                    31.840000

                     ambient_temp_expanding_max
2020-05-15 12:00:00                         NaN
2020-05-15 12:15:00                       31.31
2020-05-15 12:30:00                       31.51
2020-05-15 12:45:00                       32.15
2020-05-15 13:00:00                       32.39

如果我们不希望返回的数据框中包含时间序列的原始值,我们只需要记住在转换后删除原始序列:

win_f = ExpandingWindowFeatures(
    functions=["mean", "max"],
    drop_original=True,
)

X_tr = win_f.fit_transform(X['ambient_temp'].to_frame())

X_tr.head()
                     ambient_temp_expanding_mean  ambient_temp_expanding_max
2020-05-15 12:00:00                          NaN                         NaN
2020-05-15 12:15:00                    31.310000                       31.31
2020-05-15 12:30:00                    31.410000                       31.51
2020-05-15 12:45:00                    31.656667                       32.15
2020-05-15 13:00:00                    31.840000                       32.39

获取新功能的名称#

我们可以使用 get_feature_names_out 方法轻松获取原始和新变量的名称。

win_f = ExpandingWindowFeatures()

win_f.fit(X)

win_f.get_feature_names_out()
['ambient_temp',
 'module_temp',
 'irradiation',
 'color',
 'ambient_temp_expanding_mean',
 'module_temp_expanding_mean',
 'irradiation_expanding_mean']

另见#

查看额外的转换器以创建滚动窗口特征 (WindowFeatures) 或滞后特征,通过滞后时间序列数据的过去值 (LagFeatures)。

教程和课程#

关于此方法及其他时间序列预测的特征工程方法的教程,请查看我们的在线课程:

../../../_images/fetsf.png

时间序列预测的特征工程#

../../../_images/fwml.png

使用机器学习进行预测#











我们的课程适合初学者和希望使用传统机器学习模型(如线性回归或梯度提升机)进行时间序列预测的更高级数据科学家。

通过购买它们,您正在支持 Feature-engine 的主要开发者 Sole。