“我报名参与金石计划1期挑战——瓜分10万奖池,这是我的第16篇文章,点击检查活动概况”
问题提出
工业生产过程中会产生很多的数据,比方电压、温度、流量等等,不同的工况条件下,数据的走势不同,比方产值稳定时,流量走势平稳,产值添加时,流量必然也会添加,体现在图画上就是流量曲线上升。
比方下图:
上图中的曲线整体看起来有个趋势,但从细节来看,颤动十分剧烈,怎样从剧烈颤动的数据中找出整体趋势呢?这是咱们要处理的第一个问题。
如果咱们能够得到曲线的整体趋势,把曲线不同趋势看作不同工况,上图大致分为5段工况,分别是平稳——下降——平稳——上升——平稳。
当然,工况是一种浅显的表述,曲线的各种形状都可能是一种工况,咱们期望找到具有某种特征的工况区间,比方平稳、振动发散等。但是什么叫平稳,什么叫做振动发散呢,还有许多其他工况,咱们又该怎样辨认和界说呢?这是咱们要处理的第二个问题。
算法思路
先来思考问题一:怎样描绘数据的整体趋势?
咱们能够参阅股票的K线图,它除了每日的K线外,一般还有5日均线、10日均线等,炒股时一般参阅这些均线来检查股价的走势。咱们也能够考虑用同样的办法算出工业数据的趋势线,用不同的移动窗口得到不同等级(如分钟级、小时级、天级等)的趋势线。
趋势线的办法不止有均线这一种,还有许多其他办法能够得到更适合工业数据的趋势线,由于办法比较多且核算过程比较复杂,这儿就不过多介绍了,和移动均线要描绘的内容是相同的,不影响理解整体算法思路。
下图是用一种加权拟合方法算出的趋势线:
图中的“M”曲线是趋势线,它能够描绘原值“V”的走势,并且实时性更强,有用避免了移动平均导致的推迟问题。
有了趋势线,再来思考问题二:怎样辨认工况?
工业生产中的工况十分多,为每一种工况规划一种数学办法不太实际,咱们需求规划一个整体框架,在该框架下辨认各种需求的工况。
参阅积木的建立思路,用几个简略的积木形状(如正方体、圆柱体等等)建立出各式各样的形状(如城堡、飞机、人物等等)。咱们也创建一些工况的基础特征,如升降特征、振幅特征等,用它们“建立”出各种工况,如上升、下降、振动发散等。
咱们把曲线的基础特征总结成以下三类,每类又能够包括不同的指数:
- 升降特征
升降指数:描绘曲线上升或下降的状况,升降指数越大,上升趋势越显着;反之则下降趋势显着;当升降指数在0邻近时,则曲线趋势为平稳。
- 振幅特征
描绘曲线振动起伏的状况。
振幅指数:描绘振动起伏大小,振幅指数越大,振动起伏越大;反之则越小。
振幅升降指数:描绘振幅升降状况,振幅升降指数越大,振动起伏上升趋势越显着;反之则下降趋势显着;当振幅升降指数在0邻近时,则振幅平稳。
- 振频特征
振频指数:描绘振动频率大小,振频指数越大,振动频率越大;反之则越小。
振频升降指数:描绘振频升降状况,振频升降指数越大,振动频率上升趋势越显着;反之则下降趋势显着;当振频升降指数在0邻近时,则振频平稳。
假定咱们已经用数学办法算出这些特征指数了,怎样用他们辨认工况呢?
以常见工况为例说明:
再回忆一下这张图:
使用趋势线,三类特征指数都能够在它的基础上算出来,来看看他们的“姿态”:
升降指数:
图中L是升降指数曲线。使用它能够快速辨认上升和下降的工况。
振幅指数
当原值偏离趋势线多时,振幅大;原值在趋势线邻近时,振幅小。
振幅升降指数
图(a)是原值V、趋势线M、振幅指数R的曲线图。图(b)是振幅指数R、振幅趋势线RM、振幅升降指数RL的曲线图。
振幅升降指数是描绘振幅升降状况的指数,和升降指数描绘原值升降状况相同,RL大于0,振幅上升,RL小于0,振幅下降。
振频指数
当原值穿越趋势线次数多时,振频大;原值穿越趋势线次数少时,振频小。
振频升降指数
图(a)是原值V、趋势线M、振频指数F的曲线图。图(b)是振频指数F、振频趋势线FM、振频升降指数FL的曲线图。
振频升降指数是描绘振频升降状况的指数,FL大于0,振频上升,FL小于0,振频下降。
特征指数核算出来了,怎样挑选工况呢?
理论上只要挑选出各个指数的规模就能够了,但实际上这个规模很难设置,各个指数的数量级完全不同,下表是本例各个指数的数量级状况:
特征指数 | 数量级 |
原值 | 100 |
升降指数 | 0.1 |
升降速度指数 | 0.01 |
振幅指数 | 1 |
振幅升降指数 | 0.1 |
振频指数 | 10 |
振频升降指数 | 1 |
这样的指数没有办法设置合适的规模来挑选工况,需求把这些特征指数投射到一个固定规模内,在固定规模内设置参数即可,因为有些指数有正有负并且0自身有其特殊的意义,所以挑选[-1,1]作为这个固定规模。
使用某种规则,将指数投射在[-1,1]内,参数只要在[-1,1]内设置即可完结工况挑选。
有时期望找出几段连续工况,如先下降后平稳,能够按下图流程挑选:
实践效果
把上面思路写成代码,就能够挑选工况了。
1. 挑选取值在[90,95]之间的工况。
依据原值规模挑选工况,不需求核算特征指数,也不需求投射,依照需求设置规模挑选即可。
SPL代码
A | |
1 | =file(“1Ddata.csv”).import@tc() |
2 | [Value] |
3 | [[90,95]] |
4 | [100,10000] |
5 | =A2.(~/”>=”/”number(“/$[A3(]/#/$[)(1)]/”)”/”&&”/~/”<=”/”number(“/$[A3(]/#/$[)(2)]/”)”).concat(“&&”) |
6 | =A1.pselect@a(eval(A5)) |
7 | =A6.group@u(~-#) |
8 | =A7.select(~.len()>=A4(1)&&~.len()<=A4(2)) |
9 | =A1.(Value) |
10 | =A8.(A9(~)) |
SPL提供了丰富的循环函数,简略的语句就能实现循环,为编码工作节省很多试错时间。
核算结果示例如下:
2. 上升工况
需求核算升降指数L,需求投射参数。
SPL代码
A | |
1 | =file(“1Ddata.csv”).import@tc() |
2 | 600 |
3 | [L] |
4 | [[0.1,1]] |
5 | [100,10000] |
6 | =A1.(Value) |
7 | =2*power(4,lg(A2/15,2)-1) |
8 | =fit_main(A6,A7) |
9 | =A2/40 |
10 | =Lift(A8,A9) |
11 | =[A10.min(),A10.max()] |
12 | =[A11] |
13 | =A4.((idx=#,~.(arg_throw(~,A12(idx)(2),A12(idx)(1))))) |
14 | =A1.derive(A10(#):L) |
15 | =A3.(~/”>=”/”number(“/$[A13(]/#/$[)(1)]/”)”/”&&”/~/”<=”/”number(“/$[A13(]/#/$[)(2)]/”)”).concat(“&&”) |
16 | =A14.pselect@a(eval(A15)) |
17 | =A16.group@u(~-#) |
18 | =A17.select(~.len()>=A5(1)&&~.len()<=A5(2)) |
19 | =A18.(A6(~)) |
代码是示例性的,其间还调用了升降指数、参数投射等函数,这些函数并不是固定的,能够依据实际状况界说。
核算结果示例:
3. 振动发散的工况
需求核算振幅指数R和振幅升降指数RL,需求投射参数。
SPL代码
A | |
1 | =file(“1Ddata.csv”).import@tc() |
2 | 600 |
3 | [VaL, VfL] |
4 | [[0,1],[-0.5,1]] |
5 | [100,10000] |
6 | =A1.(Value) |
7 | =2*power(4,lg(A2/15,2)-1) |
8 | =fit_main(A6,A7) |
9 | =A2/40 |
10 | =A6–A8 |
11 | =Amplitude(A10,A9) |
12 | =fit_main(A11,A7) |
13 | =Lift(A12,A9) |
14 | =VFre(A10,A9) |
15 | =fit_main(A14,A7) |
16 | =Lift(A15,A9) |
17 | =[A13.min(),A13.max()] |
18 | =[A16.min(),A16.max()] |
19 | =[A17,A18] |
20 | =A4.((idx=#,~.(arg_throw(~,A19(idx)(2),A19(idx)(1))))) |
21 | =A1.derive(A13(#):VaL,A16(#):VfL) |
22 | =A3.(~/”>=”/”number(“/$[A20(]/#/$[)(1)]/”)”/”&&”/~/”<=”/”number(“/$[A20(]/#/$[)(2)]/”)”).concat(“&&”) |
23 | =A21.pselect@a(eval(A22)) |
24 | =A23.group@u(~-#) |
25 | =A24.select(~.len()>=A5(1)&&~.len()<=A5(2)) |
26 | =A25.(A6(~)) |
代码结构和挑选上升工况的结构相似,都是核算特征——投射参数——挑选工况。
核算结果示例:
4. 先下降再平稳的曲线段
多段连续工况比单段的略显复杂,但思路是相似的,只不过把找到的两种工况按先后顺序合并起来。
SPL代码
A | |
1 | =file(“1Ddata.csv”).import@tcI() |
2 | =select_down(A1) |
3 | =select_stable(A1) |
4 | =[A2,A3] |
5 | =A4.conj((idx=#,~.new(~:seq,idx:seq_idx))) |
6 | =A5.sort(seq) |
7 | =A6.group@u(seq_idx-#) |
8 | =A7.select(~.len()==A4.len()&&(ss=~.(seq),ss(2)(1)-ss(1).m(-1)<=180)) |
9 | =A8.((sq=~.(seq).conj(),to(sq.~,sq.m(-1)))) |
10 | =A9.(A1(~)) |
SPL的调集运算能力很强,排序合并两种工况不在话下。
最终需求说明一下,本文仅仅介绍挑选工况的思路,特征指数只介绍了常用的升降、振幅、振频三类,在实际场景应用时能够依据状况添加其他特征指数,以便一起组合“建立”出需求的工况。文中的代码也是示意性的,为每种示例写了相应的代码,实际上,能够只写一段通用的代码,依据不同的参数来辨认不同的工况,当然代码会复杂一些,全部写出会占用过多篇幅,这儿就省掉了,有兴趣的读者能够和咱们联络交流。
开发这类算法常常需求做很多实验来挑选合适的函数核算式并调整参数,SPL编程的高效性会发挥巨大的作用,在同样的时间内能够尝试更多种方案。
资料
- SPL下载
- SPL源代码