news 2026/9/25 17:38:06

tsfresh 时间序列滚动与预测:用 roll_time_series 与 make_forecasting_frame 构建特征级预测管道

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
tsfresh 时间序列滚动与预测:用 roll_time_series 与 make_forecasting_frame 构建特征级预测管道
  • 特征工程
  • 机器学习
  • 数据分析

【免费下载链接】tsfresh

Automatic extraction of relevant features from time series:

项目地址:https://gitcode.com/gh_mirrors/ts/tsfresh
点击查看免费下载

导读

本文讲解 tsfresh 官方文档中面向"滚动 / 时间序列预测"(Rolling / Time Series Forecasting)的完整方案:如何通过tsfresh.utilities.dataframe_functions.roll_time_series将一条长时序切成一组逐步右移的短时序窗口,再对每个窗口提取 tsfresh 特征,从而把"预测下一个时刻的值"转化为标准的监督学习问题。读完本文你将掌握max_timeshift、min_timeshift、rolling_direction三个窗口参数的语义与源码级实现细节,会用make_forecasting_frame一步构造特征容器与目标向量,并理解正负滚动方向、子序列命名规则及其在股票价格、工业流式数据等场景中的实战用法。

tsfresh 提取的特征可用于时间序列分类、压缩以及预测等多种任务。本文聚焦预测:设想你拥有某只股票(例如 Apple)过去 100 个时间步的价格,想要构建一个基于特征(feature-based)的模型来预测未来价格。如果只删掉"今天"这一个值、对截至今天的历史序列提取特征来预测今天,你只能得到一个训练样本。更聪明的做法是:对价格序列的每一天都执行同样的操作——删除当前值,对截至该值的历史数据提取特征,训练模型去预测被删除的那一天的值。这等价于在排序好的时间序列数据上滑动一个"裁切窗口"(cut-out window):每移动一步,就用窗口中看到的数据构造一条更短的新时间序列,只对它提取特征,然后继续滑动。在 tsfresh 中,这个过程被称为rolling(滚动)。

一、为什么需要 Rolling:从单条时序到多条时序

Rolling 的本质,是把一条时间序列变成多条时间序列,其中每一条都比前一条晚一个(或 n 个)时间步结束。tsfresh 的滚动工具帮助你把数据重塑成可以直接喂给tsfresh.extract_features的格式,也就是说"窗口切分"与"特征提取"两个步骤被明确分离。

需要特别强调的是,这里的 "time" 并不一定指时钟时间。tsfresh 支持的数据格式(见 Data Formats 文档)中,column_sort列只是给各条测量记录一个顺序状态:对时间序列而言它可以是时间维度,对其他场景则可以是位置、频率等。

1.1 流式数据场景(以工业 4.0 为例)

滚动机制同样适用于流式数据。例如在工业 4.0(Industry 4.0)应用中,你通常一次只收到一行新数据,并用它来预测机器故障。为了训练模型,你可以"假装"在流式播放数据:先给分类器喂第一个时间步之后的数据,再喂前两个时间步之后的数据,依此类推——这与滚动窗口的构造方式完全一致。

二、数据格式基础回顾

rolling 适用于 tsfresh 支持的所有时序格式。以最常见的**扁平 DataFrame(Flat DataFrame / 宽表)**为例,数据包含四种关键列类型:

  • column_id:标识时间序列所属的实体,特征将按 id 分别提取;
  • column_sort:提供排序依据的值(如时间戳),省略时假定 DataFrame 已按升序排好;
  • column_value/column_kind(仅堆叠格式需要):分别存放序列值与序列类型名。

注意:上述任何一列都不允许出现NaN、Inf或-Inf。完整的三种输入格式(扁平 DataFrame、堆叠 DataFrame、kind 字典)与输出格式说明见 Data Formats 文档,滚动函数对这些格式全部兼容。

三、滚动机制(The Rolling Mechanism)逐步演示

3.1 构造示例数据

考虑下面的扁平 DataFrame:两个实体(id 1 和 2)的两个传感器 x、y,分别在 4 个和 2 个时间步上测量:

idtimexy
1115
1226
1337
1448
281012
291113

生成这段数据的 Python 代码:

import pandas as pd df = pd.DataFrame({ "id": [1, 1, 1, 1, 2, 2], "time": [1, 2, 3, 4, 8, 9], "x": [1, 2, 3, 4, 10, 11], "y": [5, 6, 7, 8, 12, 13], })

3.2 执行滚动并观察窗口

可以想象有一个窗口在时间序列上滑动,把窗口内能看到的所有数据都提取出来。窗口有三个可调参数:

  • max_timeshift:定义窗口最大能有多大。提取出的时间序列长度最多为max_timeshift + 1(也可能更短,因为序列开头的时间戳没有足够的历史值)。
  • min_timeshift:定义每个窗口的最小尺寸。更短的时间序列(通常是序列开头部分)会被直接丢弃。
  • rolling_direction(高级参数):决定沿正(sort 递增)还是负(sort 递减)方向滑动。绝大多数场景不需要负方向,建议保持默认;该参数的绝对值决定每次切窗移动多少步。

列参数与常规数据格式一致。对我们的示例数据执行:

from tsfresh.utilities.dataframe_functions import roll_time_series df_rolled = roll_time_series(df, column_id="id", column_sort="time")

新数据集只包含旧数据集的值,但带上了新的 id,sort 列的值(这里是time)会被原样复制。按id分组后,你会得到如下"窗口":

  • 分组(1,1):[(time=1, x=1, y=5)]
  • 分组(1,2):[(time=1, x=1, y=5), (time=2, x=2, y=6)]
  • 分组(1,3):[(time=1, x=1, y=5), (time=2, x=2, y=6), (time=3, x=3, y=7)]
  • 分组(1,4):[(time=1, x=1, y=5), (time=2, x=2, y=6), (time=3, x=3, y=7), (time=4, x=4, y=8)]
  • 分组(2,8):[(time=8, x=10, y=12)]
  • 分组(2,9):[(time=8, x=10, y=12), (time=9, x=11, y=13)]

3.3 对滚动结果提取特征

滚动完成后,即可对每个窗口运行常规的特征提取流程:

from tsfresh import extract_features df_features = extract_features(df_rolled, column_id="id", column_sort="time")

每个窗口都会得到一组特征,可以直接用于训练预测模型。例如对示例数据,x__abs_energy与x__absolute_sum_of_changes两列结果如下(省略其余特征):

idx__abs_energyx__absolute_sum_of_changes...
(1,1)1.00.0...
(1,2)5.01.0...
(1,3)14.02.0...
(1,4)30.03.0...
(2,8)100.00.0...
(2,9)221.01.0...

例如 id 为(1,3)的特征,是用id=1截至并包含t=3的数据(即t=1、t=2、t=3)提取出来的。

四、用 make_forecasting_frame 一键构建特征矩阵与目标向量

如果目标是训练预测模型,tsfresh 还提供tsfresh.utilities.dataframe_functions.make_forecasting_frame便捷封装,帮你正确对齐目标向量(target vector)。其思路是:紫色的滚动子序列作为构造特征矩阵X的基础(f即extract_features函数),绿色的数据点是需要被模型预测的值,作为目标向量y的行。

限制:make_forecasting_frame只适用于单条一维时间序列(单一 id、单一 kind)。

from tsfresh.utilities.dataframe_functions import make_forecasting_frame # x 可以是 np.array 或 pd.Series;传入 pd.Series 时,其 index 会被用作 id df_shift, y = make_forecasting_frame( x=range(4), # 单条时序 kind="test", # 时序类型名 max_timeshift=1, # 窗口最多包含 2 个历史点 rolling_direction=1, # 正向滚动 )

从源码实现看(tsfresh/utilities/dataframe_functions.py),该函数内部做了三件事:

  1. 把输入x包装成{"id": "id", "time": t, "value": x, "kind": kind}的扁平 DataFrame(x为pd.Series时t取它的 index,否则取range(n)),并调用roll_time_series完成滚动;
  2. 通过一个mask_first掩码删除每个窗口的最后一行(result[-1] = 0,其余为 1)——因为这一行就是要被预测的目标点,不应出现在特征矩阵中;
  3. 以df["value"][1:]构建目标向量y(第一个点没有历史可预测,故剔除),把y的索引重写为("id", 时间戳)形式的多元索引,并只保留与滚动后df_shift中实际存在的 id 对齐的行。

单元测试(tests/units/utilities/test_dataframe_functions.py)验证了三种输入形态——list、np.arange与带DatetimeIndex的pd.Series——下df/y的精确形状与取值,例如x=range(4), max_timeshift=1, rolling_direction=1时df的 id 为[("id", 1), ("id", 2), ("id", 3)]、y为[1, 2, 3];test_make_forecasting_frame_feature_extraction还验证了返回的df可直接送入extract_relevant_features完成特征提取与选择。

五、参数与实现细节:命名规则、正负滚动与边界校验

5.1 子序列的命名规则

为了标识每一条子序列,tsfresh 用将被预测的那个点的时间戳+旧 id组成新 id:

  • 正向滚动(positive rolling):timeshift是子序列中最后一个时间戳;
  • 负向滚动(negative rolling):timeshift是子序列中第一个时间戳。

例如示例 DataFrame 做负向滚动(rolling_direction=-1)会得到以下窗口(可用于"用未来值预测当前值",如果你的场景合理的话):

idtimexy
(1,1)115
(1,1)226
(1,1)337
(1,1)448
(1,2)226
(1,2)337
(1,2)448
(1,3)337
(1,3)448
(1,4)448
(2,8)81012
(2,8)91113
(2,9)91113

5.2 参数边界行为

  • 使用非默认的max_timeshift或min_timeshift会让提取出的子序列更短,甚至被完全移除。例如正向滚动下取min_timeshift = 1,则(1,1)(即id=1, timeshift=1)的窗口会消失——因为它的长度不满足最小尺寸要求。
  • rolling_direction的绝对值大于 1(例如 2 或 -2)会跳过部分窗口——在这个例子里,每隔一个窗口才被保留一次(每次移动 2 步)。

5.3 源码层面的参数校验与实现(tsfresh/utilities/dataframe_functions.py)

roll_time_series的完整签名如下:

roll_time_series(df_or_dict, column_id, column_sort=None, column_kind=None, rolling_direction=1, max_timeshift=None, min_timeshift=0, chunksize=defaults.CHUNKSIZE, n_jobs=defaults.N_PROCESSES, show_warnings=defaults.SHOW_WARNINGS, disable_progressbar=defaults.DISABLE_PROGRESSBAR, distributor=None)

从源码可以确认以下行为:

  • 输入校验:rolling_direction == 0会抛出ValueError("Rolling direction of 0 is not possible");max_timeshift <= 0抛出ValueError("max_timeshift needs to be positive!");min_timeshift < 0抛出ValueError("min_timeshift needs to be positive or zero!");column_id缺失列时抛AttributeError,未传column_id时抛ValueError;column_sort含NaN时抛ValueError;整个容器只有 0 或 1 行时无法滚动(抛ValueError)。这些校验行为都被 tests/units/utilities/test_dataframe_functions.py 的RollingTestCase.test_with_wrong_input覆盖。
  • 排序与均匀采样检查:若传了column_sort且其 dtype 不是 object,函数会先按column_sort排序,然后计算每个 id(及 kind)分组内相邻 sort 值的差分;如果差分不全部相等,会发出警告 "Your time stamps are not uniformly sampled, which makes rolling nonsensical in some domains."——即滚动假设时序是均匀采样的。
  • 窗口切分逻辑:核心切分在内部辅助函数_roll_out_time_series(dataframe_functions.py)中完成。正向滚动时窗口右端随timeshift移动(shift_from = max(shift_until - max_timeshift - 1, 0));负向滚动时窗口左端随timeshift移动(shift_from = max(timeshift - 1, 0))。max_timeshift未指定时默认取整个分组内最大行数(prediction_steps),即"无限大"窗口。
  • 并行与分发:n_jobs == 0或1时使用单进程MapDistributor,否则使用多进程MultiprocessingDistributor;distributor参数允许你传入自定义分发器(参见 tsfresh/utilities/distribution.py),例如在集群或 Dask/PySpark 场景下复用大规模并行基础设施。chunksize控制每个 job 处理的窗口数。
  • 字典输入:若df_or_dict是字典,column_kind必须为None(否则抛ValueError),函数会对每个 kind 递归执行滚动并返回同构的字典。
  • 结果:所有分片通过pd.concat合并,并按["id", column_sort]排序返回。注意:该方法一定会生成新的 id!

六、完整预测流程小结

把上述内容串成一条可直接落地的特征级预测管道:

import pandas as pd from tsfresh import extract_features from tsfresh.utilities.dataframe_functions import make_forecasting_frame # 1. 准备单条时序(示例:4 个历史点) x = pd.Series([0, 1, 2, 3]) # 2. 构造滚动特征容器与目标向量 df_shift, y = make_forecasting_frame( x=x, kind="price", max_timeshift=2, rolling_direction=1 ) # 3. 对每个窗口提取特征(df_shift 为扁平格式,需指定 value/kind 列) X = extract_features( df_shift, column_id="id", column_sort="time", column_value="value", column_kind="kind", ) # 4. X 的每一行对应一个"截至某时刻的历史窗口"特征,y 对应待预测值, # 两者按 ("id", 时间戳) 多元索引对齐,可直接用于训练回归/分类模型

要点回顾:窗口切分(rolling)与特征提取(extract_features)是两个解耦步骤;max_timeshift控制窗口上限(子序列最长max_timeshift + 1),min_timeshift过滤过短的窗口,rolling_direction的符号控制方向、绝对值控制步长;make_forecasting_frame只适用于单一 id + 单一 kind 的一维时序,且会删除每个窗口的末行以构建严格对齐的(X, y)。对于工业流式数据、股票价格等需要"用历史特征预测下一时刻"的任务,这套机制是 tsfresh 官方推荐的标准数据准备路径。

  • 特征工程
  • 机器学习
  • 数据分析

【免费下载链接】tsfresh

Automatic extraction of relevant features from time series:

项目地址:https://gitcode.com/gh_mirrors/ts/tsfresh
点击查看免费下载
上一篇:Zola 快速上手实战:用 `zola init` 与 Tera 模板从零搭建一个多页面博客站点
下一篇:CopilotKit Headless 模式完整版(Headless Complete)实战与验证指南:以 Langroid 集成 demo 为例

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 17:37:48

基于YOLOv8与CRNN的轮胎字符识别方案:从数据标注到模型部署

简介&#xff1a;一份面向计算机、通信、人工智能、自动化等相关专业师生与从业者的机器学习期末大作业项目&#xff0c;基于机器学习完成轮胎字符识别&#xff0c;配套完整源码、预训练模型和使用说明&#xff0c;适合作为课程设计、期末大作业或毕业设计参考&#xff0c;也适…

作者头像 李华
网站建设 2026/9/25 17:32:58

基于语义地图的激光雷达定位:动态车间高精度匹配实战

简介&#xff1a;这是一份面向机器人定位与自动驾驶方向学习者的技术文档&#xff0c;围绕「基于语义地图的激光雷达定位方法」展开&#xff0c;适合具备一定SLAM与点云处理基础的研究生、算法工程师参考。文档系统梳理了语义地图、SLAM、LiDAR、语义分割、形态学滤波与全局定位…

作者头像 李华
网站建设 2026/9/25 17:32:37

工程五金选型实战手册:从螺栓强度等级到扭矩控制与表面处理

1. 为什么每位工程人都该有一本五金手册干了十几年项目&#xff0c;我最大的体会是&#xff1a;工地上百分之八十的返工和维修&#xff0c;根源不在图纸&#xff0c;不在结构计算&#xff0c;而在一颗螺栓选错了、一根钉子打偏了、一种表面处理没匹配对环境。甲方催工期的时候没…

作者头像 李华
网站建设 2026/9/25 17:30:34

sinon sandbox.verify:批量校验沙箱内全部 Mock 期望值的权威指南

测试开发工具 【免费下载链接】sinon Test spies, stubs and mocks for JavaScript. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/si/sinon 点击查看 免费下载 sandbox.verify() 是 sinon 沙箱&#xff08;sandbox&#xff09;体系中用于一次性校验所有经由该沙箱创…

作者头像 李华
网站建设 2026/9/25 17:30:34

Atlas 300V 24G推理加速卡部署YOLO全流程:从环境搭建到性能调优

“atlas”这个词在AI圈里现在指向性已经很明确了——昇腾Atlas系列。最近后台不少人都在问两件事&#xff1a;一是“atlas部署yolo”到底怎么搞&#xff0c;二是“atlas 300v 24g 是运算加速卡吗”。这俩问题其实都指向同一个核心&#xff1a;这块24G大显存的卡能不能拿来跑目标…

作者头像 李华