测量系统中误差分为系统误差、随机误差、疏忽误差三种。系统误差一般是硬件精度或缺陷导致;随机误差是偶然产生,诸多外界因素微小变化共同导致,它服从统计规律的;疏忽误差则无规律可循,且明显和事实不符合。
疏忽误差的样本值偏离了总体的平均值,在样本足够多且服从正态分布的情况下,通过一系列数理统计算法过滤坏样本。
正态分布的68-95-99.7规则
均值到左一和右一个标准差之间的定积分值是68%
均值到左二和右二个标准差之间的定积分值是95%
均值到左三和右三个标准差之间的定积分值是99.7%
一般情况下认为,某个采样值与均值的差值大于3倍标准差,即可判定该采样值为坏样本。
- #include "math.h"
- #define SAMPLE_NUM 100
-
- int sample[SAMPLE_NUM];//假设已经采集的SAMPLE_NUM个样本已经缓存再数组
- int average;//平均值
- int standard;//标准差
- int sample_num=SAMPLE_NUM;//有效的样本个数,初始是SAMPLE_NUM
-
- int filter(void)
- {
- int i,d;
- int low,high;
- int sum=0;
-
- for(i=0;i<sample_num;i++)
- {
- sum+=sample[i];
- }
- average=sum/SAMPLE_NUM;//平均值
- //----------------------------------------------
- for(i=0;i<sample_num;i++)
- {
- d=sample[i]-average;
- sum=d*d+sum;
- }
- standard=sqrt(sum/SAMPLE_NUM);//标准差
- //----------------------------------------------
- //按99.7%的范围,合理的上限和下限是3倍的标准差
- low=average-3*standard;
- high=average+3*standard;
- for(i=0;i<sample_num;i++)
- {
- if((sample[i]<low)||(sample[i]>high))
- {
- //坏样本
- if(i<sample_num-1)
- {
- sample[i]=sample[sample_num-1];//将最后一个样本前移覆盖坏样本
- i--;
- }
- sample_num--;
- }
- }
- return sample_num;//剔除坏样本后剩下的有效样本数
- }
-
通过正态分布的规则剔除异常样本,其前提是样本基数大。对于算法还可进一步改进,如果sample_num前后发生变化,表示sample[]样本发生了变化,可以再次递归执行过滤。
正态分布的规则不仅能过滤异常,对于控制监测也可应用,比如人体血压、心律检测,发现异常值则触发报警。