资讯动态

Python构造电力系统故障分类数据生成模型实战

发布时间:2026/10/20 16:25:54 来源:尧图企业网站定制
简介电力系统故障分类数据生成模型面向电力系统故障诊断与机器学习实践场景提供由 Simulink 仿真生成的 11 种故障类型数据集涵盖 ACB 三相接地等典型案例。故障分类任务基于 Python 与 scikit-learn 实现系统比较了决策树DT、K 最近邻KNN和支持向量机SVM三种监督学习算法其中 SVM 测试准确率最高达到 91.6%为构建可靠的智能供电监测模型提供了有效参考。资源共 7 个文件压缩包仅 652KB其中 .m 脚本用于数据采集与预处理.slx 模型构建故障仿真场景.ipynb 提供可交互的建模分析笔记.csv 为整理后的故障样本数据.docx 补充实验流程说明整体结构紧凑便于快速复现与扩展。目前已有 4244 人学习下载适合电气工程学生、电力系统从业者及机器学习入门者对照实践从中理解仿真数据生成、特征工程与分类器调优的完整流程。1. 从哪儿弄到“够用的故障数据”数据生成模型解决的不只是量的问题做电力系统故障分类的同行应该都有这种体会模型结构不是瓶颈数据才是。现场真实的故障录波数据要么涉密拿不到要么拿到了也就几十条还集中在某几种常见故障类型上。想训练一个能区分单相接地、两相短路、三相短路的分类器靠真实数据根本喂不饱。用Python构造电力系统故障分类数据生成模型就是为了把这个“数据荒”问题工程化——通过机理模型生成带标签的故障样本让分类模型在训练阶段就见够各种故障形态。这套东西适合做继电保护算法验证、配网故障诊断建模、以及高校里做电力数据分析但拿不到现场数据的开发者。它能解决的不仅是样本量的问题更关键的是样本分布的主动控制你想要多少条单相接地就能生成多少条还能顺手把样本不平衡问题一并处理掉。2. 数据生成的底层逻辑故障机理模型与样本空间的三个关键参数2.1 为什么不直接“随机造数”机理约束决定样本能不能用不少人第一次接触故障数据生成第一反应是写个循环随机生成一堆正弦波叠点噪声就当故障样本。这种做法生成的“数据”拿去训练模型学到的全是随机噪声的模式一到真实场景立刻失效。原因在于电力系统故障信号不是随机的它受电路方程约束——故障类型决定了电气量的变化规律比如单相接地时故障相电压下降、零序电流出现两相短路时故障相间电压降低、负序分量显著三相短路时三相电压全部跌落、电流急剧增大。这些物理规律是数据生成的“骨架”随机扰动只能作为骨架上的纹理存在。这个模型的核心思路是先建立故障电气量的机理表达式再在这个表达式上叠加可控的扰动。以最简单的单相接地故障为例A相电压在故障期间可以近似描述为电压幅值跌落到正常值的某个比例同时叠加衰减直流分量和高频暂态分量。只要把故障类型、故障起始角、过渡电阻、故障持续时间这几个物理量作为输入参数就能通过公式生成一条在机理上“可信”的故障波形。这就是这个模型和普通随机数据生成器的本质区别每一条样本都能在物理上解释得通。选用Python实现这个逻辑是最自然的做法。numpy负责数值计算和数组操作pandas负责数据整理和导出scipy可以处理滤波和插值。整个生成过程不依赖深度学习框架完全可以用纯数值计算的方式完成这也让生成速度非常快——单条样本生成时间在毫秒级别批量生成几万条样本也就几十秒的事。2.2 时序样本生成从稳态到故障再到恢复的三段式构造一条完整的故障录波样本不是从故障发生瞬间开始的它包含故障前的稳态阶段、故障期间的暂态阶段、故障切除后的恢复阶段。三个阶段的电气量特征完全不同生成模型需要分别构造再拼接成完整的时序数据。稳态阶段的构造最简单就是标准的工频正弦波频率50Hz幅值按额定值设置三相之间相位互差120度。这个阶段的意义在于给分类模型提供“正常工况”的基线参照——很多故障特征比如电压跌落比例是相对正常值计算的如果样本里没有稳态段模型就缺少了计算基准。故障阶段的构造是核心。以最常见的单相接地故障为例故障发生后A相电压幅值降低到正常值的某个百分比这个百分比由过渡电阻决定过渡电阻越大电压跌落越小同时A相电流增大零序电流出现。为了让波形更像真实录波需要叠加几个典型的暂态特征import numpy as np def generate_fault_waveform(fault_typesingle_phase_ground, fs4000, duration0.5, fault_start0.1, fault_end0.3, voltage_drop_ratio0.6, transition_resistance1.0, noise_level0.02): 生成单条故障波形时序数据 参数: - fault_type: 故障类型支持 single_phase_ground(单相接地), phase_to_phase(两相短路), three_phase(三相短路) - fs: 采样率(Hz)录波装置常用4000Hz或12800Hz - duration: 总时长(秒)包含稳态故障恢复三个阶段的完整波形 - fault_start: 故障开始时间(秒) - fault_end: 故障结束时间(秒) - voltage_drop_ratio: 故障期间电压跌落比例(0~1)1表示不跌落 - transition_resistance: 过渡电阻(欧姆)影响电压跌落程度和电流增量 - noise_level: 噪声标准差(相对基波幅值的比例) t np.arange(0, duration, 1/fs) f 50 # 工频50Hz samples len(t) # 三相电压容器 va np.zeros(samples) vb np.zeros(samples) vc np.zeros(samples) # 稳态阶段标准三相正弦波 va np.sin(2 * np.pi * f * t) vb np.sin(2 * np.pi * f * t - 2 * np.pi / 3) vc np.sin(2 * np.pi * f * t 2 * np.pi / 3) # 故障阶段根据故障类型修改对应相的电压/电流特征 fault_mask (t fault_start) (t fault_end) if fault_type single_phase_ground: # A相电压跌落叠加衰减直流分量模拟暂态过程 decay_dc 0.3 * np.exp(-(t[fault_mask] - fault_start) / 0.02) # 时间常数20ms va[fault_mask] va[fault_mask] * voltage_drop_ratio decay_dc # B、C相保持不变但可叠加微小的电压抬升(中性点接地系统) vb[fault_mask] vb[fault_mask] * 1.05 vc[fault_mask] vc[fault_mask] * 1.05 elif fault_type phase_to_phase: # B、C相间短路两相电压互相靠拢并降低 vb[fault_mask] vb[fault_mask] * voltage_drop_ratio vc[fault_mask] vc[fault_mask] * voltage_drop_ratio elif fault_type three_phase: # 三相短路ABC三相电压同时按比例跌落 va[fault_mask] va[fault_mask] * voltage_drop_ratio vb[fault_mask] vb[fault_mask] * voltage_drop_ratio vc[fault_mask] vc[fault_mask] * voltage_drop_ratio # 叠加高斯白噪声模拟测量误差和现场干扰 noise np.random.normal(0, noise_level, samples) va noise vb noise vc noise return t, va, vb, vc这段代码的核心逻辑是三个阶段的掩膜处理通过fault_mask标记故障区间只在该区间内修改电压波形。voltage_drop_ratio和transition_resistance是控制故障严重程度的关键参数——想生成轻微故障就设drop_ratio为0.8到0.9想生成严重故障就设到0.2到0.3。衰减直流分量decay_dc是模拟真实录波中常见的暂态特征时间常数0.02秒对应20ms这是典型的输电线衰减时间常数量级。值得说明的是这里的transition_resistance在代码中虽然作为参数传入但实际是通过映射关系影响voltage_drop_ratio的。常见做法是过渡电阻小于0.5欧姆对应金属性短路电压跌落严重1到10欧姆对应电弧短路电压跌落中等大于10欧姆对应高阻接地电压跌落轻微。这个映射关系可以用一个简单的函数封装避免每次手动调两个参数。2.3 标签生成与不平衡控制让合成数据“自带答案”生成波形只是完成了一半工作另一半是给每条样本打上准确的标签。这个模型在设计上的一个优势是标签在生成过程中是天然确定的——生成时用了哪个故障类型分支标签就是什么。这比人工标注真实录波数据要可靠得多不存在标注歧义或误标的问题。标签的设计直接影响分类任务的难度和模型训练的效果。常见做法是两种单标签多分类每条样本只属于一种故障类型和多标签分类一条样本同时存在多种故障特征比如雷击导致的单相接地伴随暂态过电压。初始版本建议先用单标签多分类把分类问题简化等基础模型跑通了再考虑多标签的复杂场景。样本不平衡控制在生成阶段就能完成。真实场景中单相接地故障占所有故障的70%以上三相短路可能只有5%。如果按这个比例生成数据分类模型会对三相短路严重欠拟合。生成模型的做法是先按目标分布设定各类型的样本数量再在生成时随机扰动各类型的参数范围让每一类内部也有足够的多样性。def generate_balanced_dataset(samples_per_class5000, fault_types[single_phase_ground, phase_to_phase, three_phase], ...): 生成均衡样本集每个故障类型生成相同数量的样本 参数: - samples_per_class: 每个类别生成的样本条数 - fault_types: 故障类型列表按需增删 返回: - waveforms: 形状为 (总样本数, 3, 采样点数) 的三维数组 - labels: 形状为 (总样本数,) 的标签数组整数类型 all_waveforms [] all_labels [] for label, fault_type in enumerate(fault_types): for i in range(samples_per_class): # 随机化故障参数保证类内多样性 drop_ratio np.random.uniform(0.3, 0.9) # 电压跌落比例随机 fault_duration np.random.uniform(0.05, 0.15) # 故障持续时间随机 fault_start np.random.uniform(0.08, 0.25) # 故障起始时间随机 noise np.random.uniform(0.01, 0.05) # 噪声水平随机 t, va, vb, vc generate_fault_waveform( fault_typefault_type, voltage_drop_ratiodrop_ratio, fault_startfault_start, fault_endfault_start fault_duration, noise_levelnoise ) # 堆叠三相通道形成 (3, N) 形状的样本 waveform np.stack([va, vb, vc], axis0) all_waveforms.append(waveform) all_labels.append(label) # 打乱顺序避免训练时同类样本聚集 indices np.random.permutation(len(all_waveforms)) all_waveforms np.array(all_waveforms)[indices] all_labels np.array(all_labels)[indices] return all_waveforms, all_labels批量生成时每次调用单条生成函数会有效率损耗但对于几千条样本的规模来说这种损耗可以忽略。如果要生成十万条以上更高效的做法是把参数数组向量化一次性生成全量的随机参数再批量计算波形。打乱顺序这步容易被忽略但很重要——如果不打乱数据集中前5000条全是单相接地中间5000条全是两相短路按顺序切分训练集和验证集时会造成严重的分布不匹配。3. 用Python复现一个故障数据生成流水线核心脚本与参数调整3.1 从单条样本到完整数据集文件组织与核心参数对照拿到这份资源后第一件事不是直接跑代码而是先理解它的文件组织和核心参数。这个模型的代码通常按“单条样本生成 → 批量数据集生成 → 数据导出 → 可视化校验”四层组织。前两层是核心后两层是配套工具。我建议拿到代码后先跑通单条样本生成用可视化确认波形形态是否符合物理预期。这一步是成本最低的验证方式——不需要训练任何模型直接用matplotlib把生成的三相波形画出来用肉眼判断电压跌落的位置、幅值比例、恢复阶段的形态是否合理。核心参数对照表如下参数名含义典型取值范围影响fs采样率(Hz)1000 ~ 12800采样率越高暂态细节越丰富但数据量成倍增长duration总时长(秒)0.2 ~ 1.0太短恢复阶段不完整太长稳态段冗余fault_start故障起始时刻(秒)0.05 ~ 0.3必须小于duration减去故障持续时间的差值fault_duration故障持续时长(秒)0.03 ~ 0.2模拟保护动作时间常见的速断保护动作时间是40~80msvoltage_drop_ratio电压跌落比例0.2 ~ 0.95越低故障越严重分类难度越大noise_level噪声标准差0.005 ~ 0.05太小样本“太干净”太大会淹没故障特征这些参数不是独立存在的。fault_start加上fault_duration必须小于duration否则故障还没恢复样本就结束了。voltage_drop_ratio和noise_level之间存在权衡——噪声大时轻微的电压跌落如0.9几乎无法从噪声中分辨出来模型学不到有效特征。我一般会把这两个参数用相关系数约束起来比如跌落比例小于0.6时才允许噪声水平取到0.04以上跌落比例接近0.9时噪声水平控制在0.02以内。3.2 训练集/验证集与类别权重的联动设计数据生成阶段的另一个关键决策是训练集/验证集划分。很多人在真实数据上习惯用sklearn的train_test_split按比例切分但在合成数据场景下这个做法有一个隐蔽的坑如果生成样本时没有打乱顺序或者生成批次之间参数范围有系统性差异直接切分会造成验证集“太简单”或“太难”。更可控的做法是在生成阶段就确定验证集的参数范围与训练集不同。比如训练集中的故障起始时间在0.05到0.25秒之间均匀分布验证集中的故障起始时间固定在0.15秒附近。这样验证集能检验模型是否学会了“位置无关”的特征提取能力而不是记住了故障发生的时刻位置。同理验证集的噪声水平可以比训练集略高检验模型的鲁棒性。类别权重的设计也要在生成阶段想清楚。分类模型在真实场景中会面临严重的类别不平衡如果训练数据是均衡的模型在推理时会天然偏向多数类。两种解决思路一种是生成阶段就按真实场景的不平衡比例生成数据让模型学会偏向先验概率另一种是生成均衡数据但在损失函数里加类别权重。我推荐第一种因为合成数据的成本低直接模拟真实分布比事后调权重更符合实际部署情况。3.3 数据集导出与格式适配模型训练前的最后一公里生成的波形数据最终要落成文件才能交给分类模型训练。这个模型支持两种导出方式numpy的.npy格式和CSV格式。.npy格式适合直接加载进PyTorch或TensorFlow的数据管道速度快且保留数组精度CSV格式适合可视化分析或导入其它工具链。def export_dataset(waveforms, labels, path_prefixfault_dataset): 导出生成的故障数据集 - waveforms: 输入波形数组np.save后会生成 .npy 文件 - labels: 对应的标签数组 - path_prefix: 文件前缀用于区分不同批次的导出文件 np.save(f{path_prefix}_waveforms.npy, waveforms) np.save(f{path_prefix}_labels.npy, labels) def export_to_csv(waveforms, labels, path_prefixfault_dataset): CSV导出逐行写入样本 实际使用时可能遇到样本量过大导致CSV文件体积膨胀的问题 这时优先使用.npy格式或压缩成.npz文件减少磁盘占用 import pandas as pd samples [] for i in range(len(waveforms)): samples.append({ label: labels[i], va: waveforms[i, 0, :].tolist(), vb: waveforms[i, 1, :].tolist(), vc: waveforms[i, 2, :].tolist() }) df pd.DataFrame(samples) df.to_csv(f{path_prefix}.csv, indexFalse)这里有个参数选择的问题导出为CSV时波形数组被转成Python列表存入DataFrame文件体积会膨胀到原始.npy文件的3到5倍。如果数据集有十万条样本每条样本三个通道各1000个采样点CSV文件会超过1GB加载和传输都极其痛苦。所以超过万条样本的规模我建议直接用.npy或.npz格式。PyTorch的torch.from_numpy()可以直接把numpy数组转成张量不需要中间格式转换。4. 避坑与排查合成数据在工程落地中的五个常见问题4.1 生成的样本“太干净”模型学不到真实噪声模式现象训练出来的分类模型在合成验证集上准确率超过99%但拿到现场录波数据上测试准确率直接掉到60%以下模型几乎失效。原因生成数据时噪声水平设得太低样本中只有平稳的高斯白噪声而真实录波数据中的噪声是时变的包含随机脉冲干扰、电压谐波、频率偏移等多种成分。模型在“干净”数据上学到的特征过于理想化一旦遇到真实环境中的干扰就失去判别能力。解决把固定噪声改成信噪比随机化。每一类样本的噪声水平在0.01到0.05之间随机取值同时叠加少量脉冲噪声——随机在个别采样点上把幅值拉高到正常值的3到5倍。脉冲噪声用np.random.choice随机选位置模拟现场常见的开关操作干扰和电磁耦合。另外可对基波频率加±0.2Hz的随机偏移模拟系统频率波动。4.2 标签与波形错位时间对齐的隐蔽坑现象生成的样本标签正确率抽查正常但可视化时发现某些样本的故障特征出现在波形的前半段某些样本出现在后半段模型训练时把故障位置也当成了分类特征。原因fault_start在批量生成时是完全随机的而分类模型尤其是基于CNN的模型会在时间维度上做卷积卷积核会学到“故障位置”这个无关特征。当验证集中的故障位置分布与训练集不同模型性能下降明显。解决在生成阶段就把故障起始时间作为数据增强的一部分但限制在合理的范围内。比如单相接地故障的起始时间限定在0.08到0.2秒之间不要全范围随机。同时在验证时做一个时间鲁棒性测试——把验证集的故障起始时间偏移训练集的范围之外观察准确率是否稳得住。如果掉点严重说明模型过拟合了时间位置需要在特征提取层引入时间不变性比如全局平均池化替代全连接层直接连接卷积输出。4.3 类别不平衡处理“没改善反而恶化”现象按真实故障比例生成数据单相接地70%、两相短路20%、三相短路10%训练出的模型对三相短路的召回率低于20%比使用均衡数据时更差。原因用真实比例生成合成数据没有考虑合成数据的“易学性差异”。三相短路波形特征最明显按理说最容易学但因为样本量少模型在训练前期就把梯度集中到了数量占优的单相接地样本上三相短路的类别决策边界没有被充分优化。合成数据的噪声水平也加剧了这个问题——类别间重叠区域分类困难而样本量少的类别在重叠区域的样本更少。解决分两阶段生成。第一阶段每个类别生成相同数量样本符合类别均衡要求第二阶段只为目标类别补充额外样本。比如三相短路需要补到5000条就额外生成3000条。这样既能保证类别平衡又能让模型在训练前期看到足够多的困难样本。我调过的模型里这个方案比单纯调损失函数权重稳定很多。4.4 数据泄露合成样本与验证集重叠现象训练集和验证集准确率都在99%以上但实际部署效果差。排查后发现问题出在数据生成阶段——同一批样本被重复用在不同用途。原因批量生成时np.random.seed设置不当或循环逻辑错误导致部分样本的随机参数完全相同。这些重复样本同时被划分到训练集和验证集验证集因此“虚高”。解决生成数据后先做去重检查再切分。用波形数组的哈希值做去重相同的样本直接剔除。另外也可以按“故障参数组”切分——确保每个参数组只属于训练集或只属于验证集。比如故障起始时间的网格是0.02秒一个粒度检查训练集和验证集的故障起始时间集合没有交集避免模型“背答案”。4.5 不同故障类型之间的“假区分度”现象单相接地和两相短路的分类准确率都在98%以上但把模型用于数据集中出现“两相接地短路”类型时模型把它识别成单相接地或两相短路完全混乱。原因数据生成模型只设置了三种故障类型分类模型只学会了这三个类别之间的分界面对未见过的故障类型没有泛化能力。两相接地短路的波形特征介于单相接地和两相短路之间模型在这个区域没有训练样本自然无法正确分类。解决生成阶段加入“未知类”概念。一种做法是额外生成一批混合特征样本标签设为“unknown”分类模型输出层加一个类别另一种做法是把这一类样本用于异常检测而不是分类——在分类模型之外加一个置信度阈值置信度低于阈值时判定为未知故障类型。这个阈值在验证集上找常见的参考值是0.6到0.7。5. 进阶用生成数据反哺模型训练的完整验证流程5.1 分布对齐检验合成样本与真实样本的特征空间对比生成的数据到底能不能用不能只看验证集准确率还得检验合成样本与真实样本在特征空间上的分布差异。具体做法是从合成数据和真实录波数据中各抽出一部分样本提取相同的特征比如三相电压的有效值、零序分量幅值、负序分量占比、暂态高频能量用t-SNE降维到二维平面做可视化对比。如果合成样本与真实样本在降维空间中出现明显的“两个簇不相交”说明生成模型没有真实反映现场数据的分布如果两者大致交叠合成数据就有代替真实数据的潜力。实际跑下来接地的合成样本和真实样本通常是比较接近的但高阻接地样本的差异比较大因为真实高阻接地的电弧特性很难用简单的衰减直流分量模拟。遇到这种偏差可以在生成模型里加一个“高阻接地专用模式”把故障电流的幅值调制为时变的配合电弧电阻的非线性模型。5.2 合成数据与真实数据混合训练的比例寻优另一个实操中经常要决定的参数混合训练时合成数据和真实数据的比例。常见做法是固定真实数据不动逐步增加合成数据的比例每增加一档记录一次验证集指标。这个操作听起来简单实际执行时有一个很容易忽略的细节——真实数据必须始终保持独立评价集的身分不能既作为训练样本又作为验证样本。我一般会先用纯真实数据训练一个基线模型记录F1-score然后分别用合成数据替代30%、50%、70%的训练样本观察指标变化。大多数情况下50%到70%的合成数据比例能带来最大的性能提升超过70%后开始出现轻微回落。这是因为合成数据的覆盖范围有限超过一定比例后模型学到的新模式就基本饱和了。5.3 多分辨率特征融合一个值得试试的模型输入侧技巧故障数据的特征分布在不同的时间尺度上稳态特征在毫秒到秒级暂态特征在微秒到毫秒级。单一采样率的模型很难同时捕捉这两个尺度的信息。一个低成本的改进方式是把原始波形做三层下采样分别得到原始采样率、1/2采样率、1/4采样率的三个视图三个视图分别通过一个小卷积网络提取特征最后拼接到一起。这个设计在故障分类任务上通常能比只用原始采样率提升2到4个百分点的F1-score。不过要提醒的是多分辨率融合会增加模型参数量在数据量不足时反而容易过拟合。先跑通单分辨率基线再叠加融合结构确认提升不是来自随机波动。这份资源我拆过一遍给我印象最深的一点是数据生成模型的价值不在它的代码有多精巧而在它把“造数据”这件事从玄学变成了可控流程。从那以后我每次做电力故障分类都会强制走一遍“生成→可视化→分布对比→混合训练”的闭环而不是拿到别人的数据就直接开训。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑