ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

风电故障诊断时空特征融合数据集:设计思路与工程踩坑全记录

风电故障诊断时空特征融合数据集:设计思路与工程踩坑全记录

风电故障诊断方向做久了你会发现,行业里缺的从来不是模型结构,而是真正能支撑算法验证的数据集。前段时间我在推进一个时空特征融合的故障诊断项目,想找个合适的基准数据来跑通"时间维度+空间维度"联合建模的方案,结果翻遍了公开渠道:实验室台架振动信号的小样本、单台机组单一传感器的简化记录、没有空间关联信息的孤立表格,都不符合要求。最后我决定不再等现成数据,自己按真实风场的运行逻辑,整理了一套包含20台机组、6个月连续记录、同时保留时空关联信息的故障诊断数据集。这篇文章把数据集从设计思路、字段定义、数据清洗到特征融合的完整构建过程,以及我实际踩过的坑全部写出来,给准备做风电智能运维、故障诊断算法研究的同行一个可以复现和参考的基准。

1. 为什么做这个数据集:故障诊断研究的真实痛点

1.1 行业数据现状:公开集太少,可用性太差

风电运维走到今天,靠定期检修和事后维修已经很难扛住降本压力,预测性维护基本成了行业共识。而预测性维护的第一步就是数据,这个环节恰恰卡住了很多人。我接触过的公开数据集,要么来自实验室轴承台架,采样频率虽然高,但运行工况单一,和真实风机整机系统的耦合关系差得很远;要么是某台机组短时间的运行记录,故障样本少、标注不完整,根本撑不起一个像样的训练集。

对做算法研究的人来说,最尴尬的场景是论文里说自己模型效果多好,复现时连一个统一的数据基准都找不到。不同论文用不同数据、不同预处理、不同评价口径,结果很难横向对比。行业里其实非常需要一个“标准答案”式的数据集,让算法在同一份数据上公平竞争。

另一个现实问题是真实数据获取门槛太高。风电场数据涉及多方协作,运行数据、维护记录、气象数据通常散落在不同系统里,想凑齐一套完整、干净、带标注的数据,周期以季度计算。即便拿到了,各风场的机型、布局、运行环境差异很大,A风场的数据放到B风场的模型上往往直接失效。这也是为什么我判断:与其被动等一个完美的公开数据集,不如主动按真实逻辑构建一个,既能控制噪声、标注和数据质量,又能把时空特征融合这个方向真正跑起来。

1.2 时空特征融合为什么需要专属数据集

先解释清楚“时空特征融合”到底解决什么问题。风电机组是一个典型的多传感耦合系统,齿轮箱、主轴、发电机、叶片之间不是彼此独立的。一旦某个关键部件开始退化,异常信号不只体现在自身传感器上,还会通过振动传递、功率变化、温度传导等方式扩散到相邻部件乃至相邻机组。

纯时间维度模型的局限在于,它只盯着单台机组自身的传感器历史,忽略了一个关键事实:风电场内机组之间通过尾流效应、风向遮挡形成强关联。上游机组改变运行状态,下游机组的入流风速就会变化,进而影响功率和载荷。这就意味着,一台机组的异常特征,往往可以通过空间上邻近机组的运行状态变化被提前捕捉到。

要验证“时间+空间”融合的有效性,就必须有一个同时满足以下条件的数据集:

  • 多台机组在同一时间窗口内的同步运行数据;
  • 每台机组的多维传感器时间序列;
  • 明确的机组空间位置关系和风向信息;
  • 完整、可信的故障标签。

这种数据结构,公开数据集里基本找不到现成的答案,必须专门构建。这套数据集的核心价值就在于此:它不是一堆孤立的CSV表格,而是按照风场真实运行逻辑组织起来的、保留机组间空间关系和时间连续性的标准化数据资产。

2. 数据集总体设计:从风场逻辑到数据架构

2.1 数据范围与机组配置

设计数据集的第一件事,是确定范围和结构。参考一个典型内陆丘陵风电场的场景,我设置了20台单机容量2MW的机组,按5排4列规则布局,相邻机组间隔约300米,主导风向设定为西北方向。选这种规则布局是有讲究的:规则布局便于把空间位置量化成坐标矩阵,同时又能模拟真实的尾流遮挡关系,对研究空间特征来说,这是最基础也最有效的设置。

时间跨度设为6个月,SCADA层面采样间隔取10分钟。10分钟是主流风场集控系统的标准存储间隔,既能反映运行趋势,又不会让数据量失控。每台机组6个月大约2.6万个采样点,20台合计超过52万条记录。振动数据单独按1kHz采样,但完整振动数据体量太大,我做了分段统计特征处理,只保留冲击幅值、有效值、峭度、频率重心等频域指标,既保留故障判别能力,又让数据集可以被普通PC轻松加载。

数据集内容分为三部分:

  • 正常工况段:用于学习机组正常运行模式;
  • 退化与故障段:覆盖不同故障类型的演化过程;
  • 工况切换段:包含启停、变桨调节、限功率运行等过渡状态,用来考验模型对非稳态数据的适应能力。

2.2 字段设计与故障标注体系

数据字段按“环境-运行-状态-空间”四个维度组织,无论是做传统机器学习还是深度学习都非常顺手。下表是数据集实际采用的字段清单:

维度字段名说明
环境wind_speed轮毂高度等效风速(m/s)
环境wind_direction风向角(°,相对正北)
环境air_temp环境温度(℃)
环境air_density空气密度(kg/m³)
运行active_power有功功率(kW)
运行rotor_speed叶轮转速(rpm)
运行generator_speed发电机转速(rpm)
运行pitch_angle桨距角(°)
运行nacelle_direction机舱朝向(°)
状态gearbox_oil_temp齿轮箱油温(℃)
状态gearbox_bearing_temp齿轮箱轴承温度(℃)
状态generator_temp发电机绕组温度(℃)
状态main_bearing_temp主轴轴承温度(℃)
状态vibration_acc齿轮箱振动加速度有效值(m/s²)
状态vibration_peak齿轮箱振动峰值(m/s²)
空间turbine_x / turbine_y机组平面坐标(m)
空间neighbor_dist与最近上游机组的距离(m)
标签fault_label故障类型编码
标签fault_stage故障发展阶段编码

故障标注是整个数据集最花心思的部分。因为无法拿到某风电场完整维修记录,我采用“机理仿真+故障注入”的方式生成故障样本:在正常物理运行模型基础上,按故障类型加入温度漂移、振动冲击、传动效率下降等特征性变化,并由领域知识做二次校验。故障类型分四类,编码如下:

  • 0:正常
  • 1:齿轮箱故障(齿面磨损、断齿特征)
  • 2:轴承故障(内圈、外圈、滚动体点蚀特征)
  • 3:叶片故障(结冰、质量不平衡特征)
  • 4:发电机故障(绕组温度异常、绝缘退化特征)

fault_stage字段分早期、中期、严重期三个等级,目的是支持“故障预警”类研究,让模型不只做故障分类,还能学习从正常到故障的演化轨迹,提前几天甚至几周识别风险。

2.3 时空信息在数据中如何体现

这个数据集和普通SCADA数据集最大的区别,是明确把空间信息做进了数据组织方式里。时间维度上,每个采样点带时间戳,按固定10分钟间隔排序,保证时序连续。原始数据不做平滑处理,保留真实曲线的毛刺,让研究者在预处理环节有独立发挥的空间。

空间维度上,meta目录提供机组位置表,包含每台机组的平面坐标,同时预计算风向相关的尾流关系矩阵。每一时刻,每台机组的上游机组是哪一台、距离多远,这些信息直接生成为特征列,不需要使用者自己再去算空气动力学。

这样设计的原因是,很多做数据分析的人未必熟悉风机空气动力学,如果只给坐标让他们自己推算尾流关系,门槛太高。把最后一公里也补上,使用者拿到数据后就能直接聚焦在融合算法本身,而不是花大量时间处理领域知识。

3. 数据采集与预处理的实操记录

3.1 数据来源与采样策略

原始数据来自一套按风机运行机理搭建的仿真系统,叠加了真实SCADA数据的统计噪声特性。这里要说明白,不是凭空生成数据,而是先把真实风机的运行统计规律做了一番拟合,比如功率曲线形态、温度随风速变化的趋势、振动随转速变化的敏感度,再在这个规律之上进行物理仿真推演。生成的曲线从形态上和真实风场数据高度接近,同时能准确控制故障的发生时间、类型和严重度,适合做算法评估。

采样策略做了分级处理:

  • SCADA运行数据:10分钟一个点,覆盖6个月,保证长期趋势完整;
  • 振动特征数据:每10分钟聚合一次,内部由1kHz高频信号计算得出,包含有效值、峰值、峭度等,兼顾细节和体量;
  • 气象数据:10分钟同步记录,包含风速、风向、温度、湿度、空气密度。

这里有一个关键取舍:没有直接给原始1kHz振动波形。原因很简单,20台机组6个月的原始振动波形体量在TB级别,一般研究者的机器根本扛不动。而故障诊断真正需要的,往往是振动的高层统计特征,提供这些特征已经能覆盖绝大多数算法实验需求。如果后续有研究专注于深度学习信号处理方向,可以单独申请小样本原始波形,这个版本迭代计划里已经考虑到了。

3.2 清洗流程:异常值、缺失值与噪声处理

原始数据永远不能直接用,这个道理做数据的人都懂。清洗环节主要处理了四类问题。

第一,剔除传感器停机值。风机在维护、停机、通讯中断时,数据会出现全零或者恒定值块,这类数据不处理,会把模型的均值、方差全带偏。判断方式是功率和转速同时低于阈值且持续超过30分钟,标记为停机段并剔除。

第二,识别限功率段。风场在电网调度、尾流控制或测试期间会出现有功降额运行,此时风速很高但功率很低,属于正常现象却不是故障特征。如果把这部分数据当作故障样本,模型会学到错误映射。数据集里单独提供is_curtailment标记,训练时可以按需过滤。

第三,处理缺失值。10分钟SCADA偶尔会有单点丢数,采用的策略是:连续缺失小于等于3个点,用前后线性插值;超过3个点,直接丢弃该段并加mask标记,而不是强行填充。强行填充长段缺失会引入大量伪信号,调试时特别难排查。

第四,去除温漂和季节性趋势。环境温度变化会直接导致轴承温度、油温整体移动,夏天油温可能整体高十几度。如果不处理,模型很容易把“季节”当“故障”。数据集里提供去除趋势后的可选版本字段,用滚动差分和STL分解两种方式实现,实验者可以对比不同预处理的效果。

3.3 工况划分与数据切片

风电数据的特殊之处是工况变化剧烈。同一台风机,3m/s和12m/s风速下的齿轮箱温度、振动幅值可以差出好几倍。把所有数据混在一起训练,模型会倾向于按风速分类,而不是按故障分类。

针对这个问题,数据集里做了两件事。一是提供工况区间字段,按风速区间把运行数据划分为切入区、额定区、限功率区和切出区四个工况段,在元信息里标注每个样本所属工况,方便做工况分治实验。

二是按任务导向提供切片。一个切片包含某台机组连续7天的采样记录,时间窗口中心为故障报警点。这种结构既可用于故障分类,也可以用于剩余寿命预测,还方便做滑动窗口输入。实测下来,7天窗口既能捕捉故障演化信息,又不会因为窗口过长引入太多无关波动。

4. 特征工程:时间特征与空间特征的融合实现

4.1 时间维度特征提取

时间特征的核心思路,是让模型看到“过去一段时间的变化趋势”,而不只是当前时刻的瞬时值。数据集里预设了基础时间特征的计算逻辑,同时保留原始序列供扩展。

具体做法是,对每个关键状态量(油温、轴承温度、振动有效值、功率、转速)计算三类特征:

  • 统计特征:窗口内的均值、标准差、最大值、最小值、分位数;
  • 趋势特征:窗口内线性拟合斜率、前后半段均值差;
  • 频域特征:振动量做FFT后的主频幅值、频谱重心、频带能量比。

窗口大小选择1小时、6小时和24小时三档。1小时窗口捕捉短期异常冲击,比如齿轮箱突然点蚀剥落;6小时窗口捕捉中期趋势变化;24小时窗口捕捉昼夜温差和缓慢退化。多尺度搭配比单一窗口稳得多,这也是我实测下来效果差距最明显的一处。

时间窗口的步长和重叠率同样是关键参数。基础版本用10分钟步长、窗口之间50%重叠,既保证样本量充足,又不会让相邻样本过于雷同导致训练集冗余。

4.2 空间维度特征提取

空间特征是这个数据集最有特色的部分,也是很多做时间序列的人一开始容易忽略的。

核心思想是:一台机组的运行状态,不应该只看它自己,还要看它的“邻居”。在风电场里,上游机组的尾流会降低下游机组的入流风速,同时增加湍流强度。这种现象带来一个很有用的副产品:当某台机组出现故障导致功率下降、温度异常时,这种异常会改变它下游机组的入流条件,从而在空间上留下痕迹。

数据集原始特征列中提供两种空间特征:

  • 静态空间特征:机组相对位置坐标、机组之间欧氏距离、上下游关系;
  • 动态空间特征:风向主导下,每台机组当前时刻的上游机组编号、上游机组风速、上游机组功率、上游机组振动特征。

动态空间特征是最花功夫的部分。风向一变,整张尾流关系图就变,每一时刻都要重新计算上游是谁。数据集按10分钟一个点,把每台机组在每个时刻的上游关系预计算好,生成一张邻接关系表。用户可以拿这张表直接建图,也可以拿上游特征直接拼到特征向量里。

经过这样处理,一个样本就不再是“一台机组的一个时刻”,而是“一个机组在某个空间上下文里的一个时间窗口”。这恰恰是图神经网络或者注意力机制最友好的输入结构。

4.3 融合方式对比

特征算出来,怎么融合又是另一个问题。构建数据集时专门设计了一条基准实验流水线,对比三种融合方式的差异,并把结果作为baseline写进README,供后续研究者参考。

第一种是特征拼接。把时间统计特征和空间邻域特征直接拼成长向量,输入梯度提升树或全连接网络。这种方式简单直接,但特征维度偏高,无法显式建模机组间的结构关系。

第二种是两分支网络。时间分支用LSTM或Transformer处理单机时序,空间分支用图卷积网络处理邻接关系,最后把两个分支的隐向量拼接后分类。这种方式参数更多,但能充分利用两种信息的互补性。

第三种是统一时序图模型。把整个风场建模成动态图,节点是机组,节点特征是时间窗口统计量,邻接矩阵由风向尾流关系动态生成,再用时空图网络端到端训练。这种方式最复杂,也是当前研究比较认可的方向。

基准版本的结论是:在故障分类准确率上,统一时序图模型明显优于纯时间分支模型,空间邻域信息平均多带来4到7个百分点的提升,尤其在叶片故障和齿轮箱早期故障这两类容易被单一传感器漏判的场景上,空间特征的优势最突出。这个结论也印证了当初做时空特征融合数据集的判断。

5. 数据集的使用指南与基准验证

5.1 目录结构与读取方式

一个数据集好不好用,很大程度上看组织是否清晰。数据集按“原始数据、处理后数据、元信息、文档”四层组织,解压后的结构如下:

wind_turbine_fault_dataset/ ├── README.md ├── data/ │ ├── raw/ │ │ ├── scada/ # 每台机组一个csv,按时间排序 │ │ ├── vibration_summary/ # 每台机组振动统计特征 │ │ └── weather/ # 气象数据 │ ├── processed/ │ │ ├── train.parquet # 训练集(已标注、已切片) │ │ ├── val.parquet │ │ └── test.parquet │ └── meta/ │ ├── turbine_info.csv # 机组坐标、型号、投产时间 │ ├── fault_labels.csv # 故障事件、类型、起止时间 │ └── neighbor_relation.parquet # 动态上游关系表 ├── baseline/ │ ├── features/ # 预计算好的时间+空间特征 │ └── results/ # 基准确率、F1结果记录 └── tools/ └── data_preview.py # 快速预览脚本

processed目录下提供的是已经切好片、带标签、可直接喂给模型的训练、验证、测试集。为了公平评估,划分时严格保证同一台机组的同一段故障事件不会被拆到训练和测试两个集合里,避免数据泄漏导致指标虚高。

5.2 加载代码示例

为了方便新手快速上手,写了数据预览脚本,核心代码如下:

import pandas as pd # 读取机组信息 turbine_info = pd.read_csv("data/meta/turbine_info.csv") print("机组数量:", len(turbine_info)) # 读取已切片的训练数据(示例) train_df = pd.read_parquet("data/processed/train.parquet") print("训练样本量:", len(train_df)) print("故障标签分布:") print(train_df["fault_label"].value_counts(normalize=True)) # 提取时间特征和空间特征列 feature_cols = [c for c in train_df.columns if c.startswith("feat_")] target_col = "fault_label" X = train_df[feature_cols].values y = train_df[target_col].values

processed数据里每行是一个样本,对应“某台机组、某时间窗口、某空间上下文”。如果想研究原始时序结构,可以用data/raw/scada下的逐点数据自行切片;如果只想快速验证baseline,直接用processed和预计算特征即可。

5.3 基准模型实测对比

为了让大家对数据集难度有直观认知,我跑了几个常见模型作为基准,结果记录在baseline/results里。测试集保持固定,各类别样本量经过重采样平衡。

模型输入特征准确率Macro-F1参数量级
逻辑回归时间统计特征78.4%75.2%小
LightGBM时间统计特征87.1%84.6%中
LSTM原始时序特征89.3%86.9%中
LSTM + 空间拼接时序+邻域特征92.6%90.4%中
时空图网络时序+动态邻接图95.1%93.8%大

表里可以看出两个信息:一是数据集对简单模型不是“躺赢”,逻辑回归只能到八成左右,说明分类难度是真实的;二是时间+空间信息的融合确实能带来稳定提升,这也是这个数据集存在的意义。需要提醒的是,这些数字是在固定划分和预处理下得到的,不同预处理、不同特征窗口会产生合理浮动,不要直接拿去做跨论文硬比。

6. 构建数据集踩过的坑与排查实录

6.1 故障标签怎么标才靠谱

标签是监督学习的天花板,标签错了一切白搭。标注过程中踩过最大的坑,是把“报警”当作“故障”。

风场SCADA系统本身有阈值报警机制,比如齿轮箱油温超过设定值就报警。但报警不等于故障,夏天高负荷运行时油温也可能短时超阈值,过几个小时又降回来。如果直接把报警点当故障标签,模型学到的其实是“高温报警”而不是“故障退化”,泛化能力极差。

解决方案是引入“持续性与传导性”双重校验:一个真正的故障特征,必须在时间上有持续性,比如连续超过6小时偏离基线;并且在相邻部件上有传导性,比如齿轮箱振动升高同时伴随轴承温度、功率变化。只有两个条件同时满足,才会打上对应故障标签。这个规则虽然增加了工作量,但显著提高了标签纯度。

6.2 数据不平衡怎么处理

故障数据天然稀缺,这个坑躲不开。数据集中正常样本占比约八成,四类故障样本合计两成,其中严重期样本尤其稀少。

处理不平衡,我的经验分三步走:

  • 第一,不要上来就过采样。先理清训练目标和评估指标,如果做故障预警,比起准确率更应关注召回率和误报率的平衡。
  • 第二,针对严重期样本极少的情况,用早期故障阶段样本做数据增强,通过时间序列幅值缩放、局部抖动和频段滤波制造“近似严重期”样本,这比简单的随机过采样有效得多。
  • 第三,评估时用分层采样,保证每个类别在train、val、test中占比一致,否则验证集的F1会失真。

6.3 工况耦合导致的假相关

这是最隐蔽的一个坑,在初版数据集上栽过一次。当时跑LSTM,测试集准确率接近97%,但仔细一查,发现模型其实是在测“风速”而不是测“故障”。

原因很简单,故障样本大多注入在较高风速段,而正常样本覆盖所有风速段。模型学会了一看风速高就猜故障,准确率自然虚高,这就是工况与标签耦合导致的假相关。

后来重新构造数据集,保证每个故障类别在四个风速工况区间内都有分布,并且在元信息里强制要求实验者报告分工况准确率,而不是只看全局平均。之后模型的真实性能才显露出来:全局准确率从虚高的97%回落到95%左右,但分工况表现均匀,模型的可靠性反而提升了。

6.4 关于空间特征缺失的补充说明

在导出数据集时反复纠结的一个点,是动态上游关系表的处理。表中把每台机组“当前时刻的上游机组”按主导风向预计算好,但遇到风向剧烈变化的时段,上游关系切换频繁,容易导致空间特征跳变。

妥协方案是把风向变化率大于某阈值的时刻单独打上标记字段,让使用者选择过滤或保留。基准实验里过滤掉这些时段后整体F1有小幅提升,但代价是样本量减少。这个取舍没有标准答案,不同任务需求下选择不同。

6.5 数据泄漏的高危点

最后提醒一个很多人容易踩的坑:时间序列数据里的泄漏问题。初版导出时,为了省事直接按时间顺序前80%做训练、后20%做测试,结果在故障样本上出现明显偏差。原因是故障往往集中出现在特定时间段,比如冬季结冰高发期,这导致测试集里特定类别占比异常高。

修正方案是按“事件”划分,同一台机组同一场故障事件的所有切片必须全部落在同一个集合里,并且尽量让不同故障事件按类型分层分配到训练和测试。经过这个调整,指标才真正稳定下来。任何时序数据集如果没有做好这层处理,模型再漂亮也可能是虚的。

这套数据集从构思到整理完,我在中间迭代了很多版,最大的体会是:做数据远比做模型费精力,但数据质量的回报会在模型效果上被几何级放大。那些看起来不起眼的组织方式,比如标签校验规则、工况标记、动态邻接表,最后都会变成实验效果的一部分。如果你也准备做风电故障诊断或者时空特征融合方向,我建议先花些时间把这套数据集的元信息和预处理逻辑吃透,再动手调模型。下一步我打算继续补充原始振动波形子集,以及更多故障类型的长时间退化样本,让数据集在预测性维护方向上有更完整的支撑。也欢迎同行实际用过之后反馈问题,这个版本会继续迭代下去。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进