4

C++ でこの領域を測定するにはどうすればよいですか?

(更新:質問を再度編集するのではなく、ソリューションとコードを回答として投稿しました)

理想曲線と測定曲線の間の青い領域を定量化する方法
理想的な線 (赤の破線) は、開始点からのプロットで、測定角度ごとに平均上昇が追加されています。これは私が平均して取得します。テストデータを黒で測定しました。青色のくぼみの面積を定量化するにはどうすればよいですか? X 軸がユニット化されているため、傾きと計算が単純化されます。

このような領域のサイズのカットオフを決定し、この部分に再テストまたは失敗のフラグを立てることができます. まれに、右寄りに表示される別のくぼみがありますが、標準偏差のカットオフ値を設定すると、通常、それらの部分は失敗します。

アップデート

ディエゴの答えは、これを視覚化するのに役立ちました。何をしようとしているのかがわかったので、「自家製ディップ検出器」を実装するアルゴリズムに取り組みます。:)
問題のより良い視覚化


なんで?

私が販売しているスロットル位置センサーをテストするためのテスト ベンチを作成しました。収集されたデータを分析することにより、プロットがどれほどまっすぐであるかをプログラムで定量化しようとしています。この特定のモデルは私を悩ませています。

販売したくない部品のサンプル プロット: テストデータに曲線があります

X 軸は、スロットル開度の等間隔の角度です。ステッピング モーターは入力シャフトを回転させ、0.75° ごとに停止して 10 ビット ADC で出力を測定し、Y 軸に変換します。プロットは、をビットマップ座標に変換data[idx]したものです。次に、ブレゼンハムのアルゴリズムを使用して、ビットマップ内のポイント間に線を引きます。idx,value(x,y)

私の他の TPS 製品は、驚くほどリニアな出力を生成します。

プロットの下 (左) の部分は、自動車の通常の使用にとって重要です。それは、街中を運転している時、駐車場に入る時などです。この特定の部分は、開口部が 15° 前後に傾斜する傾向があります。このプログラムを使用して、曲線のこの「傾斜」を定量化し、テスターの直感。上記の例では、プロットは落ち込みますが、理想的な線には戻りません。

これは組み込みアプリケーションですが、レポートの印刷には 10 秒かかります。そのため、120 ポイントのデータの配列を何度もステップ実行することはサイクルの無駄だとは考えていません。また、uC32 PIC32 マイクロコントローラーを使用しているため、メモリが十分にあるため、コントローラー内でこの問題を熟考できる余裕があります。


私がすでに試していること

テスト ポイント間の上昇の配列: X 軸を完全に無視し、それがユニット化されていることを考慮してから、ある読み取り値から次の読み取り値への変更の配列を作成します。この配列は、レポートの「ポイント間の最小上昇: 0 最大: 14」に寄与するものです。私はこれを配列と呼びますdeltas

で標準偏差を使用しdeltasてみましたが、テスト中に、この部品の標準偏差が低いことは信頼できる尺度ではないことがわかりました。ディップが初期のデータ ポイントによって暗示された元のラインにすぐに戻る場合、標準偏差は一見低い (2.3 と低いことが観察されている) 可能性がありますが、その部品はまだ使用したくないものです。カットオフを 2.6 に設定しようとしましたが、素晴らしいプロットで失敗したパーツが多すぎました。上記にリンクされている他のより直線的な部分は、品質のために標準偏差を確実に当てにすることができます。

尖度は、この状況にはまったく当てはまらないようです。今日、尖度について学び、尖度と歪度を含む統計ライブラリを見つけました。継続的なテスト中に、これら 2 つの測定値のうち、合格または不合格に対応する正、負、または振幅の傾向がないことがわかりました。その同じ紳士が線形回帰ライブラリを共有していますが、Lin Reg は私の状況とは無関係であると考えています。AVG がdeltas私の理想的な線であるという仮定に満足しているためです。線形回帰と R^2 は、理想的ではないデータまたははるかに大きなセットから直線を見つけるためのものです。

各デルタを AVG および Std Dev と比較するdeltasのデータの最終平均に対して各デルタをチェックするようにモニターを設定しました。ここでも、信頼できる指標が見つかりませんでした。良品が多すぎると、デルタを平均から標準偏差の 2 倍以内に制限するテストに合格しません。最終的に、私が納得できる AVG からの唯一のバリエーションはAVG+Std Dev、AVG 自体との差の範囲内に収まることです。より制限的なものは、そうでなければ良い部分に失敗します。そして、15°の開口部付近のとらえどころのないディップは、このテストをこっそり通り抜けることができます.

自作のディップ検出器コンピュータのシリアルモニターにフィードdeltasすると、ディップ中に連続して陰性が観察されdeltasたので、ディップ検出器をプログラムしましたが、非常に粗雑に感じました。deltas連続して 5 つ以上のマイナスがある場合は、それらを合計します。AVG からのディップの差の合計を取り、負のデルタの数で割ると、2.9 または 3 を超える値は失敗を意味する可能性があることを確認しました。6 から 15 デルタまで続くディップを観察しました。容易に観察できるディップは、AVG 合計との差が最大で -35 になります。

AVG からのトレンド累積変動 上記のことから、AVGdeltasから離れていくにつれての合計を見ることが答えになるのではないかと思いました。つまり、配列をステップ実行し、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';
    }
    ...
}

そして、素晴らしい線形プロットを持つ部品はsumOfDiffs、AVG の 2 倍以上である 58 のデータ ポイントで実現しました! sumOfDiffs120 個までのデータ ポイントの最後で、値が -0.000057であるため、これは驚くべきことだと思います。

テスト中、最終sumOfDiffs結果はしばしば 0.000000 として登録され、非常に悪い部品でのみ .000100 より大きくなります。実際、これは非常に驚くべきことでした。「悪い部分」がどのように優れた精度を蓄積できるかということです。

sumOfDiffs のモニタリングからの出力例この下の出力は、ディップが発生していることを示しています。sumOfDiffsテスト全体で、実行が AVG から AVG の 2 倍以上離れているため、テストは監視します。この落ち込みはdeltas idx23 度から 49 度まで続きます。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 点テストをこれらの部品の標準的な尺度と考えているかを学んだことでした。私の最初のテスト ベンチは、8k の RAM を搭載した Arduino を使用し、TFT ディスプレイもプリンターも備えておらず、機械的解像度はわずか 3° でした。当時、私は単純deltasに、任意の合計範囲内にあることと、単一のデルタがどれだけ大きくなるかの制限を選択することをテストしました. 私の120点以上のテストは、以前の30点のテストに比べて高級感がありますが、そのテストはこれらの低下については知りませんでした.

4

2 に答える 2

1

敷地内

  • データセットの平均には、平均からの偏差の合計が 0 になるという数学的な性質があります。
    • これは、悪いデータセットと良いデータセットの両方が常にほぼ 0 になる理由を説明しています。
    • 基本的に、ゼロと異なる場合の結果は、基本的に差分の丸め誤差の累積であり、残念ながら有用な情報を保持できないのはそのためです。
  • あなたが探しているものを最も明確に定義するのはあなたのイメージです: あなたはAREAを探していますが、これがこの方法で解決策を見つけられない理由です:
    • 単一のポイントのメトリックを見ると、ローカルすぎてその情報を抽出できません
    • グローバルな累積またはパラメーター (グローバル標準偏差) に注目するのはグローバルすぎて、あまりにも多くの情報と変動の原因の中でデータを失います
    • これは確率分布ではないため、尖度(すでに知っていると言われましたが、完全を期すためのものです)は適用範囲外です
    • 最後に、すでに試したもののより適切なアプローチは、「自家製ディップ検出器」です。これは、局所的ではあるが多すぎない方法で考えるからです。
  • 最後だが大事なことは:
    • 選択しようとしているアルゴリズムには、それが立っている暗黙のポイントがあります。
      • したがって、パラメータ化やチューニングを行わずに自動的に問題に適応し、しきい値などを自己定義する非常に賢いアルゴリズムを探している人もいるでしょう。
      • 反対側には、典型的なデータ動作 (良いものと悪いもの) のライターによる知識に基づくアルゴリズムがあり、別の異なる予期しない動作がある場合、結果が予測できないという点でそれ自体が愚かです。
      • わかりました、正しい方法は、アプリケーションに応じて、この 2 つのうちの 1 つ、またはその中間です。したがって、それが機能する場合は、「自家製の浸漬検出器」が解決策になる可能性があります. それを大まかに定義する理由はありませんが、アプリケーションのニーズに基づいて十分ではない可能性があり、それは別のことです.

面積の求め方

  • データを入手したら、まず「理論上の直線」を明確に定義します。私はいくつかのオプションを与えます:
    • RANSACアルゴリズムを使用します(正式には最良のオプションIMHO)
      • これにより、整列していないポイントを無視して、整列したポイントに最適にフィットします
      • それはかなり難しく、この作品には大きすぎるかもしれません(IMHO)
    • 最初と最後の点によって定義された線を考えてください
      • ディップはほとんどの場合、境界近くではない同じ位置にあるとおっしゃっていたので、最初と最後のポイントは手頃な価格であると考えることができます
      • 実装が非常に簡単
      • これは、前に述べたように、予想される動作に関する知識を使用した例であるため、この仮定にどの程度の信頼を与えるかを考える必要があります。
    • 最初の 10 点と最後の 10 点への線形適合を考慮する
      • より多くのポイントを使用するため、最初のポイントまたは最後のポイントだけがメジャーの問題の影響を受け、これが原因ですべてが失敗するという心配が少なくなるため、以前のより手頃なバージョンにすぎません
      • 実装も非常に簡単です
      • 私があなただったら、これか、これにインスパイアされた何かを使います
  • 各 X の直線で与えられる Y 値を計算する
  • Y_dev = Y_data - Y_straight次の手順で 、2 つの曲線の間の面積 (または数学的に同じ関数の下の面積) を計算します。
    • PositiveMax = 0; NegativeMax = 0;
    • 最初のポイント (値は正または負の値) から開始し、一時領域アキュムレータに入れますtmp_Area
    • 次のポイントごとに
      • 符号が同じ場合、値を累積します
      • 違う場合
        • 蓄積をやめる
        • 累積値が PositiveMax よりも大きいか、NegativeMax よりも小さいかを確認し、新しい PositiveMax または NegativeMax として保存するかどうかを確認します
        • いずれにせよ、アキュムレータをtmp_Area = Y_dev;現在の値にリセットし、この方法で新しいアキュムレーションを開始します
    • 最終的に、最大の過大評価された連続領域と最大の過小評価された連続領域の値が得られます。これは、探しているスコアであると思います。
    • 必要に応じて、観察されたデータの動作と予想されるデータの動作に基づいて NegativeMax のみを管理できます
    • Y_devがしきい値よりも低い場合に累積しないように、しきい値を設定すると便利な場合があります。
    • これは、直線に近い多くの点から大きな累積が得られないようにするためです。これは、直線から遠く離れた少数の点の累積と同様になる可能性があります。
      • これの必要性と適切なしきい値は、いくつかのサンプルデータで評価する必要があります
    • この連続領域の適切なしきい値を見つける必要があり、サンプル データの観察からのみ得ることができます。
      • 繰り返しになりますが、しきい値を観察して決定することも、良いサンプルと悪いサンプルのリポジトリを構築して、使用するしきい値を自動的に学習するプログラムを作成することもできます。しかし、彼はアルゴリズムではありません。これは、その操作パラメーターを見つける方法であり、人間の脳が行うことは何も悪いことではありません...それは、私たちが悪いことと良いことを分離する方法を探しているかどうかにかかっているだけです.これを行う自動適応アルゴリズムを探しています.. ..あなたがターゲットを決めます。
于 2013-10-09T22:42:23.553 に答える