X 和 y 形状不同的时间序列的 CV 管道

数据挖掘 scikit-学习 时间序列
2022-03-07 11:26:41

我正在使用 ML 模型来预测时间序列。我想生成一个 sklearn 管道,例如

from sklearn.preprocessing import FunctionTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler

pipe = Pipeline(
    steps=[
        ("gen", FunctionTransformer(generate_features)),
        ("imp_nan", SimpleImputer(strategy="median")),
        ("scale", StandardScaler()),
        ("reg", keras.wrappers.scikit_learn.KerasRegressor(build_model, epochs=35))
    ]
)

Wheregenerate_features接收我的数据X并为给定的时间戳生成一组特征。例如 5 天滚动标准差。但是,我的目标y可能有不同的形状。

例如,我可能想预测未来 5 小时(因此我的目标将有一个周期为 5 小时的日期时间索引),但我的输入数据的频率可能为 1 分钟(因此最初的索引周期为 1 min 转化为 5 小时)。这会在尝试交叉验证时导致问题。例如,如果我使用

splitter = TimeSeriesSplit(n_splits=3)
grid = GridSearchCV(pipe, {"gen__kw_args": [{"windows": (2,4,6)},]}, cv=splitter)
grid.fit(X_train, y_train)

我立即收到一个错误,告诉我形状X_trainy_train不一样。这是有道理的,因为需要在 X 和 y 上使用分离器。

我想这样做是因为我想对我的generate_features函数的参数(以及我的模型的参数......)执行网格 cv

我的问题

X当我们的输入形状可能与我们的输入形状不同时,是否有一种很好的方法来创建管道并在时间序列特征生成上执行交叉验证y

编辑:这是回溯

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-11-f0c6e65ecbb8> in <module>
      1 splitter = TimeSeriesSplit(n_splits=3)
      2 grid = GridSearchCV(pipe, {"gen__kw_args": [{"windows": (2,4,6)},]}, cv=splitter)
----> 3 grid.fit(X_train, y_train)

~/.local/lib/python3.8/site-packages/sklearn/model_selection/_search.py in fit(self, X, y, groups, **fit_params)
    648             refit_metric = 'score'
    649 
--> 650         X, y, groups = indexable(X, y, groups)
    651         fit_params = _check_fit_params(X, fit_params)
    652 

~/.local/lib/python3.8/site-packages/sklearn/utils/validation.py in indexable(*iterables)
    246     """
    247     result = [_make_indexable(X) for X in iterables]
--> 248     check_consistent_length(*result)
    249     return result
    250 

~/.local/lib/python3.8/site-packages/sklearn/utils/validation.py in check_consistent_length(*arrays)
    209     uniques = np.unique(lengths)
    210     if len(uniques) > 1:
--> 211         raise ValueError("Found input variables with inconsistent numbers of"
    212                          " samples: %r" % [int(l) for l in lengths])
    213 

ValueError: Found input variables with inconsistent numbers of samples: [522323, 52417]
1个回答

我做了一些搜索,实际上已经找到了使用tsfresh.

您可以在此处找到 sklearn 转换器: https ://tsfresh.readthedocs.io/en/latest/text/sklearn_transformers.html

这是示例中的代码片段。

pipeline = Pipeline(
    [
        ('augmenter', RelevantFeatureAugmenter(column_id='id', column_sort='time')),
        ('classifier', RandomForestClassifier())
    ]
)

df_ts, y = load_robot_execution_failures()
X = pd.DataFrame(index=y.index)

pipeline.set_params(augmenter__timeseries_container=df_ts)
pipeline.fit(X, y)

我们将一个空数据框传递给pipeline.fit并将输入数据指定为tsfresh转换器的参数。df_tsy拥有完全不同的形状!

:-)