c – 测量来自线路的数据点的变化;抓住一下

如何在C中测量这个区域?

(更新:我发布了解决方案和代码作为答案,而不是再次编辑问题)

理想线(红色虚线)是从起始点开始的图,每个测量角加上平均上升值;这是我通过平均得到的.我用黑色测量了测试数据.如何量化蓝色倾角的面积? X轴是单位化的,因此简化了斜率和数学运算.

我可以确定这样的区域大小的截止值,然后标记该部分以进行重新测试或失败.很少会出现另一个接近右侧的下降,但设置标准偏差的截止值通常会使这些部分失效.

更新

迭戈的回答帮助我想象了这一点.现在我可以看到我正在尝试做什么,我将研究算法来实现“自制倾角检测器”. 🙂

为什么?

我创建了一个test bench来测试我正在销售的节气门位置传感器.我试图通过分析收集的数据以编程方式量化绘图的直线程度.这个特殊的模型令我烦恼.

我不想出售的零件样本图:

X轴是节流阀开口的均匀间隔角.步进电机转动输入轴,每0.75°停止一次,测量10位ADC的输出,转换为Y轴.该图是数据[idx]到idx的转换,值映射到(x,y)位图坐标.然后我使用Bresenham算法在位图内的点之间绘制线条.

我的其他TPS产品生产amazingly linear output.

该图的下(左)部分对于任何机动车辆的正常使用至关重要;这是当你在城里开车,进入停车场等时.这个特殊的部分倾向于在15°左右开口下滑,我希望用这个程序来量化曲线中的“下降”并且更少依赖于测试员的直觉.在上面的例子中,情节下降但没有返回到理想线的范围.

即使这是一个嵌入式应用程序,打印报告需要10秒钟,因此我不会考虑多次循环遍历120个数据点的数组而浪费周期.另外,由于我使用的是uC32 PIC32 microcontroller,因此内存充足,所以我能够在控制器中思考这个问题.

我正在尝试的东西

测试点之间的上升数组:我完全忽略X轴,考虑它是单元化的,然后从一个读数到下一个读数进行一系列的变化.这个数组有助于报告的“点之间的最小上升:0最大值:14”.我把这个数组称为deltas.

我尝试在增量上使用标准偏差,但是,在测试过程中我发现低Std Dev不是这部分的可靠测量.如果下降快速返回到早期数据点隐含的原始线,则Std Dev可能看起来很低(观察到低至2.3),但该部分仍然是我不想使用的部分.我尝试设置截止值为2.6,但它失败了太多的部分有很好的情节.与上面链接的另一个更线性的部分可以可靠地依靠Std Dev的质量.

Kurtosis似乎根本不适用于这种情况.我今天学到了Kurtosis,发现了Statistics Library,其中包括了Kurtosis和Skewness.在继续测试期间,我发现在这两个测量中,没有正,负或幅度趋势对应于通过或失败.同一位绅士已经分享了一个线性回归库,但我相信Lin Reg与我的情况无关,因为我对三角洲AVG的假设是我的理想路线感到很自在.线性回归和R ^ 2更适用于从不太理想的数据或更大的集合中查找线.

将每个增量值与AVG和Std Dev进行比较我设置了一个监视器来检查每个增量与增量数据的最终平均值.在这里,我也找不到可靠的指标.太多好的部件不会通过测试将任何增量限制在距离平均值2x Std Dev之内.最终,AVG唯一可以解决的变化是AVG Std Dev与AVG本身的区别.任何更严格的限制都会导致其他好的部分失败.并且在15°开口处难以捉摸的倾斜可以潜入这个测试.

自制倾角检测器当将增量输入到计算机的串行监视器时,我在倾角期间观察到连续的负增量,所以我在倾角检测器中编程,但对我来说感觉非常粗糙.如果连续有5个或更多负增量,我总结它们.我已经看到,如果我把这个总和的差值与AVG的差值除以负增量的数量,超过2.9或3的值可能意味着失败.我观察到逢低持续6到15个三角洲.随时可观察到的逢低与AVG的差异将达到-35.

来自AVG的累积变化趋势以上让我觉得观看三角洲的总和,因为它远离AVG可能是答案.这意味着,我逐步完成数组并总结AVG中每个增量的差异.我以为自己已经有了一些东西,直到很好的一部分吹响了这个理论.我看到一个趋势是,运行总和从AVG变化的次数少于2倍AVG,线条出现的直线越多.许多理想的部分只会显示8个或更少的delta点,其中sumOfDiff将偏离AVG很远.

float sumOfDiffs=0.0;
for( int idx=0; idx<stop; idx++ ){
    float spread = deltas[idx] - line->AdcAvgRise;
    sumOfDiffs = sumOfDiffs + spread;
    ...
    testVal = 2*line->AdcAvgRise;
    if( sumOfDiffs > testVal || sumOfDiffs < -testVal ){
        flag = 'S';
    }
    ...
}

然后一个具有奇妙线性图的部分出现了58个数据点,其中sumOfDiffs是AVG的两倍以上!我发现这很惊人,因为在~120数据点的末尾,sumOfDiffs值是-0.000057.

在测试期间,最终的sumOfDiffs结果通常会记录为0.000000,并且只有在特别差的部分才会大于.000100.实际上,我发现这一点非常令人惊讶:“坏部分”如何能够累积出极高的准确性.

来自监控sumOfDiffs的样本输出以下输出显示了下降发生.测试表示,当整个测试时,运行sumOfDiffs远离AVG的AVG的2倍.这种下降持续时间为23至49的deltas idx;从17.25°开始,持续19.5°.

Avg rise: 6.75    Std dev: 2.577
idx: delta  diff from avg   sumOfDiffs  Flag
 23:   5    -1.75           -14.05      S
 24:   6    -0.75           -14.80      S
 25:   7     0.25           -14.55      S
 26:   5    -1.75           -16.30      S
 27:   3    -3.75           -20.06      S
 28:   3    -3.75           -23.81      S
 29:   7     0.25           -23.56      S
 30:   4    -2.75           -26.31      S
 31:   2    -4.75           -31.06      S
 32:   8     1.25           -29.82      S
 33:   6    -0.75           -30.57      S
 34:   9     2.25           -28.32      S
 35:   8     1.25           -27.07      S
 36:   5    -1.75           -28.82      S
 37:  15     8.25           -20.58      S
 38:   7     0.25           -20.33      S
 39:   5    -1.75           -22.08      S
 40:   9     2.25           -19.83      S
 41:  10     3.25           -16.58      S
 42:   9     2.25           -14.34      S
 43:   3    -3.75           -18.09      S
 44:   6    -0.75           -18.84      S
 45:  11     4.25           -14.59      S
 47:   3    -3.75           -16.10      S
 48:   8     1.25           -14.85      S
 49:   8     1.25           -13.60      S
Final Sum of diffs: 0.000030
RunningStats analysis:
NumDataValues= 125
Mean= 6.752
StandardDeviation= 2.577
Skewness= 0.251
Kurtosis= -0.277

关于质量的令人清醒的注意事项:在这次旅程中开始我的是学习主要汽车OEM供应商如何将4点测试视为这些部件的标准测量.我的first test bench使用了带有8k RAM的Arduino,没有TFT显示器和打印机,机械分辨率只有3°!那时我只是测试了在任意总界限内的增量,并选择了任何单个delta可以有多大的限制.与之前的30分测试相比,我的120分测试感觉很高,但测试并不知道这些测试.

最佳答案 房地

>一组数据的平均值具有与平均值的偏差之和为0的数学特性.

>这解释了为什么坏的和好的数据集alwais几乎都给出了0.
>基本上当与零不同时的结果本质上是差异中的舍入误差的累积,这就是为什么不幸的是无法保存有用的信息

>最清楚地定义你所寻找的是你的形象:你正在寻找一个区域,这就是为什么你没有找到这种方式的解决方案:

>在单个点中查找度量标准过于本地化,无法提取该信息
>期待全球累积或参数(全球标准偏差)过于全球化,您会丢失太多信息和变化来源中的数据
> kurtosis(你已经告诉过我知道,但是为了完整性)已超出其应用领域,因为这不是概率分布
>最后,你已经尝试过的更合适的方法是“自制倾角探测器”,因为它以一种本地但不太多的方式思考.

>最后但并非最不重要:

>你要选择的任何算法都有它的默认点.

>因此,也许有人正在寻找一种超级聪明的算法,它不需要参数化,并且调整会自动适应问题并自我定义等等.
>另一方面,有一种算法可以支持作者对典型数据行为(好的和坏的)的了解,而且这种算法本身就是愚蠢的,如果存在另一种不同的和不可预见的行为,则结果是不可预测的
>好的,正确的方法是这两个中的一个,或者介于两者之间,具体取决于应用程序.因此,如果它也有效,“自制倾角探测器”可以成为一种解决方案.没有理由将原油定义为原油,但根据应用需求可能还不够,这是另一回事.

如何找到该地区

>一旦获得数据,首先要明确定义“理论直线”.我给出了一些选择:

>使用RANSAC算法(正式恕我直言)

>这使您最适合对齐的点,而不考虑未对齐的点
>这项工作相当困难,也许超大(恕我直言)

>考虑第一点和最后一点定义的线

>你告诉说,下降几乎总是在不接近边界的相同位置,所以第一点和最后一点可以被认为是负担得起的
>非常容易实施
>这是我之前所说的使用预期行为知识的一个例子,所以你需要思考你对这个假设的信心和程度

>考虑前10个点和后10个点的线性拟合

>只是以前更实惠的版本,因为使用更多的点你可以更少担心可能只是第一点或最后一个受到任何测量问题的影响所以所有都因为这个而失败
>也很容易实现
>如果我是你,我将使用这个或其他灵感的东西

>计算每个X的直线给出的Y值
>使用以下过程计算两条曲线之间的区域(或函数Y_dev = Y_data下的区域 – 数学上相同的Y_straight):

> PositiveMax = 0; NegativeMax = 0;
>从第一点开始(值可以是正数或负数)并放入临时区域累加器tmp_Area
>每个下一个点

>如果符号相同则累积该值
>如果不同的话

>停止累积
>检查累计值是否大于PositiveMax或低于NegativeMax,以及是否存储为新的PositiveMax或NegativeMax
>在任何情况下都使用tmp_Area = Y_dev重置累加器;以这种方式开始新的积累到当前值

>最后,您将获得最大被高估的连续区域和最大被低估的连续区域的值,我认为这些区域是您正在寻找的分数.
>如果您愿意,您只能根据观察到的和预期的数据行为来管理NegativeMax
>您可能会发现设置阈值很有用,这样如果值Y_dev低于阈值,则不会累积它.
>这是为了不从靠近直线的许多点获得大的累积,这可能类似于远离该线的几个点的累积

>需要这个,并且需要在某些样本数据上评估适当的阈值

>您需要为此连续区域找到合适的阈值,并且只能通过观察样本数据来获取该阈值.

>再次:它可以是您观察和决定阈值,或者您可以构建好的和坏的样本的存储库,并编写一个程序,自动了解要使用的阈值.但他不是算法,这是如何找到它的操作参数,并且人脑没有任何错误.. ..只取决于我们是否正在寻找一种方法来分离坏事和好事,或者如果我们’重新寻找和自动适应算法,这样做.. ..你决定目标.

点赞