检测传感器数据的变化点

时间:2014-03-02 10:17:14

标签: php math statistics

我有很多传感器数据,我需要能够可靠地检测到变化。基本上它来自远程客户端的水位传感器。它正在使用加速度计和漂浮以获得水位。我的问题是数据有时可能会有噪音(每次测量会变化2-5个单位),有时我需要检测低至7-9个单位的变化。

当我绘制数据时,人眼很明显有变化,但我怎样才能编程呢?现在我只是尝试以编程方式检测大于x的变化,但它不太可靠。我附上了一个示例图,并用箭头指出了这些变化。一开始的巨大变化只是测试,所以这不是数据的正常行为。

数据在MYSQL数据库中,代码在PHP中,所以如果你能指出我正确的方向,我会非常感激!

编辑:数据中也可能存在一些不被认为有效的尖峰,而是数据中的错误。

编辑:可以从http://pastebin.com/x8C9AtAk找到示例数据 该算法需要每隔30分钟左右运行一次,并且能够检测到最后2-4次ping内的变化。每次ping每隔3-5分钟。

enter image description here

2 个答案:

答案 0 :(得分:1)

我做了一些awk,你或其他人可能想要试验。我将最后10个(m)样本的平均值除去当前样本,并平均最后2个样本(n),然后计算两者之间的差异,如果绝对差值超过阈值,则输出一条消息。

#!/bin/bash
awk -F, '
                                    # j will count number of samples
                                    # we will average last m samples and last n samples
   BEGIN {j=0;m=10;n=2}

   {d[j]=$3;id[j++]=$1" "$2}        # Store this point in array d[]

   END {                            # Do this at end after reading all samples
      for(i=m-1;i<j;i++){           # Iterate over all samples, except first few while building average

         totlastm=0                 # Calculate average over last m not incl current
         for(k=m;k>0;k--)totlastm+=d[i-k]
         avelastm=totlastm/m        # Average = total/m

         totlastn=0                 # Calculate average over last n
         for(k=n-1;k>=0;k--)totlastn+=d[i-k]
         avelastn=totlastn/n        # Average = total/n

         dif=avelastm-avelastn      # Calculate difference between ave last m and ave last n
         if(dif<0)dif=-dif          # Make absolute

         mesg="";
         if(dif>4)mesg="<-Change detected"; # Make message if change large
         printf "%s: Sample[%d]=%d,ave(%d)=%.2f,ave(%d)=%.2f,dif=%.2f%s\n",id[i],i,d[i],m,avelastm,n,avelastn,dif,mesg;
      }
   }
   ' <(tr -d '"' < levels.txt)

最后一位<(tr...)只是在将文件levels.txt发送到awk之前删除双引号。

以下是输出的摘录:

18393344 2014-03-01 14:08:34: Sample[1319]=343,ave(10)=342.00,ave(2)=342.00,dif=0.00
18393576 2014-03-01 14:13:37: Sample[1320]=343,ave(10)=342.10,ave(2)=343.00,dif=0.90
18393808 2014-03-01 14:18:39: Sample[1321]=343,ave(10)=342.10,ave(2)=343.00,dif=0.90
18394036 2014-03-01 14:23:45: Sample[1322]=342,ave(10)=342.30,ave(2)=342.50,dif=0.20
18394266 2014-03-01 14:28:47: Sample[1323]=341,ave(10)=342.20,ave(2)=341.50,dif=0.70
18394683 2014-03-01 14:38:16: Sample[1324]=346,ave(10)=342.20,ave(2)=343.50,dif=1.30
18394923 2014-03-01 14:43:17: Sample[1325]=348,ave(10)=342.70,ave(2)=347.00,dif=4.30<-Change detected
18395167 2014-03-01 14:48:25: Sample[1326]=345,ave(10)=343.20,ave(2)=346.50,dif=3.30
18395409 2014-03-01 14:53:28: Sample[1327]=347,ave(10)=343.60,ave(2)=346.00,dif=2.40
18395645 2014-03-01 14:58:30: Sample[1328]=347,ave(10)=343.90,ave(2)=347.00,dif=3.10

答案 1 :(得分:0)

解决这类问题的正确方法是建立一个感兴趣的现象模型,并建立噪声过程模型,然后根据一些数据推断出这种现象。这些推论必然是概率性的。您需要执行的一般计算是P(H_k | data) = P(data | H_k) P(H_k) / (sum_k (P(data | H_k) P(H_k))(贝叶斯规则的一般形式),其中H_k是所有感兴趣的假设,例如“时间上的数量级”或“大小的噪声” ”。在这种情况下,可能存在大量似是而非的假设,涵盖所有可能的大小和时间。您可能需要限制所考虑的假设范围,以使问题易于处理,例如:只回顾一定数量的时间步。