c++ - 测量线上数据点的变化; catch 浸

标签 c++ plot statistics line

如何在C++中测量该区域?
(更新:我发布了解决方案和代码作为答案,而不是再次编辑问题)

理想线(红色虚线)是从起点开始的图,每个测量角度均加上平均上升;我通过平均获得。我用黑色测量了测试数据。如何量化蓝色浸入区域? X轴是统一的,因此简化了斜率和数学运算。
我可以确定像这样的区域大小的临界值,然后将其标记为重新测试或失败。很少会出现一个更靠近右侧的倾斜,但是设置标准偏差的临界值通常会使这些零件失效。
更新
迭戈的答案帮助我形象地看到了这一点。现在,我可以看到要执行的操作,接下来,我将研究实现“自制倾斜检测器”的算法。 :)

为什么?
我创建了一个test bench来测试我销售的节气门位置传感器。我正在尝试通过分析收集的数据以编程方式量化绘图的直线度。这个特殊的模型让我很烦恼。
我不想出售的零件的样图:

X轴是节气门开度的均匀间隔角。步进电机转动输入轴,每0.75°停止一次,以测量10位ADC上的输出,该输出转换为Y轴。该图是data[idx]到映射到idx,value位图坐标的(x,y)的转换。然后,我使用Bresenham算法在位图中的点之间绘制线。
我的其他TPS产品产生amazingly linear output
该图的下部(左侧)对于任何汽车的正常使用都是至关重要的。这是当您在城镇周围开车,进入 parking 场等时。该特定部分趋向于在15°的开度附近出现倾角,我希望使用该程序来量化曲线中的“倾角”,而不再依赖于测试人员的直觉。在上面的示例中,地势有所下降,但并未恢复到理想的直线。
即使这是一个嵌入式应用程序,打印报告也需要10秒钟,因此我不认为多次遍历120个点的数据数组会浪费周期。另外,由于我使用的是uC32 PIC32 microcontroller,因此有足够的内存,因此我可以在 Controller 中考虑这个问题。

我已经在尝试什么
测试点之间的上升数组:考虑到X轴是统一的,我将其完全消除,然后对从一个读数到另一个读数的变化进行排列。此数组有助于报表的“点之间的最小上升:0最大:14”。我称这个数组为增量。
我尝试在增量上使用标准偏差,但是,在测试过程中,我发现低Std Dev并不是此部分的可靠措施。如果跌落很快返回到早期数据点所暗示的原始线,则Std Dev可以说是低的(观察到低至2.3),但是该部分仍然是我不想使用的东西。我尝试将临界值设置为2.6,但由于积压过多,它无法通过太多零件。上面链接的另一个更线性的部分可以可靠地依靠Std Dev来保证质量。
黑体病似乎根本不适合这种情况。我今天了解了Kurtosis,并发现了包括峰度和偏度的Statistics Library。在继续测试期间,我发现在这两个度量中,没有出现与通过或失败相对应的正,负或振幅趋势。这位先生共享一个线性回归库,但是我相信Lin Reg与我的情况无关,因为我很满意地认为增量AVG是我的理想选择。线性回归和R ^ 2更适合从不太理想的数据或更大的数据集中找到一条线。
将每个增量与AVG和Std Dev进行比较我设置了一个监视器,以根据增量数据的最终平均值检查每个增量。在这里,我也找不到可靠的指标。太多合格零件将无法通过将任何差值限制在偏离平均值2倍标准偏差之内的测试。最终,我可以确定的与AVG唯一的区别是与AVG本身的AVG+Std Dev差异不大。任何更严格的限制都会使本来不错的部分失败。大约15°的开度难以捉摸,可以通过此测试。
自制的倾角检测器当将增量提供给计算机的串行监视器时,我在倾角期间观察到连续的负增量,因此我在倾角检测器中进行了编程,但对我来说却非常粗糙。如果连续有5个或更多的负增量,则将它们相加。我已经看到,如果我将这个总和与AVG的骤降之差相除,然后除以负增量的数量,则大于2.9或3的值可能表示失败。我观察到跌幅持续6至15个三角洲。容易观察到的下降幅度与AVG的总和之间的差值最多为-35。
来自AVG的趋势累计变化上面的内容使我认为,观察偏离AVG的增量总和可能是答案。意思是,我遍历数组并求和AVG中每个增量的差。我以为我一直在研究某件事,直到很大程度上吹灭了这一理论。我看到一种趋势,即运行总和从AVG变化的次数少于2x AVG的次数越少,直线出现的越多。许多理想部分仅会显示8个或更少的增量点,其中sumOfDiffs将偏离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的Delta 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°!那时,我只是简单地测试了增量在任意总范围内,并选择了单个增量可能有多大的限制。与之前的30分测试相比,我的120分以上的测试感觉很上乘,但是该测试根本不知道这些下降。

最佳答案

前提

  • 一组数据的平均值具有数学性质,即与平均值的偏差之和为0。
  • ,这说明了为什么好的和坏的数据集alwais都给出几乎为0的原因。
  • 从零开始的结果基本上是diff中舍入误差的累积,这就是为什么不幸的是无法保存有用的信息
  • 最清楚地定义您正在寻找的东西是您的图像:您正在寻找区域,这就是为什么您无法通过以下方式找到解决方案的原因:

    在单点查找指标的
  • 太本地了,无法提取该信息
  • 寻找全局累积或参数(全局标准偏差)过于笼统,您会丢失太多信息和变异源中的数据
  • 峰度(您已经告诉我知道,但出于完整性考虑)不在其应用领域,因为这不是概率分布
  • 最后,您已经尝试过的方法中更合适的方法是“自制倾角检测器”,因为它以本地方式而不是太多方式进行思考。
  • 最后但并非最不重要的:
  • 您要选择的任何算法都有其默认点。
  • 因此,也许有人正在寻找一种 super 聪明的算法,该算法无需参数化,并且调整会自动适应该问题并自定义问题。
  • 另一方面,存在一种算法,它将基于作者对典型数据行为(好的和坏的)的了解,并且它本身是愚蠢的,因为如果存在另一种不同且未预期的行为,则结果是不可预测的
  • 好吧,正确的方法是这两个方法之一,或介于两者之间,具体取决于应用程序。因此,如果它也可行,“自制倾角检测器”将是一个解决方案。没有理由将其定义为粗糙的,但是根据应用程序的需求可能还不够,这是另一回事。

  • 如何寻找地区
  • 获得数据后,首先要做的就是清楚地定义“理论直线”。我提供一些选择:
  • 使用RANSAC算法(正式成为的最佳选择,恕我直言)
  • 这将使您最适合对齐点,而不考虑未对齐的点
  • 对于这项工作(IMHO)相当困难,甚至可能过大
  • 考虑由第一点和最后一点定义的线
  • ,您告诉我们,底线几乎总是在不靠近边界的同一位置上,因此可以将第一个点和最后一个点视为负担得起的
  • 非常容易实现
  • 这是一个使用预期行为知识的示例,正​​如我之前所说的,因此您需要考虑是否对该假设以及给定的信任程度
  • 考虑前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的值小于阈值,则您不会对其进行累加。
  • 这是为了不从接近直线的许多点获得大的累积,而这可能类似于远离直线的少数点的累积
  • 需要这样做,并且需要在一些样本数据上评估适当的阈值
  • 您需要为该连续区域找到合适的阈值,并且只能通过观察样本数据来获取它。

    再次是
  • :您可以观察并确定阈值,或者可以建立好样本和坏样本的存储库,并编写一个程序来自动了解要使用的阈值。但是他不是算法,这是找到其操作参数的方法,人脑没什么可做的.....这仅取决于我们是否正在寻找一种将好与坏事物分开的方法,或者重新寻找执行此操作的自适应算法.....您确定目标。
  • 关于c++ - 测量线上数据点的变化; catch 浸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19269638/

    相关文章:

    c++ - boost graph 从 txt 文件循环创建图形

    c++ - 使用指针传递数组值

    c++ - 如何在 OpenCV 中锐化图像

    r - 如何从倒置的钟形曲线中采样

    用于引导置信区间和非参数多数据集比较的 Python 统计包

    database - 是否可以根据退出/进入数量的数据估计平均访问者持续时间?

    2003 年的 c++ mfc 库问题

    r - 修改 r 中雷达图的现有函数

    r - R中互相关的方法

    python - 如何在 Scikit-Learn 中绘制超过 10 倍交叉验证的 PR 曲线