4

私は次のように構成されたいくつかの海の潮汐データを扱っています:

$data = array('date' => array('time' => array('predicted','observed')));

これが私が使用している実際のデータのサンプルです:http: //pastebin.com/raw.php?i = bRc2rmpG

そして、これは高い/低い値を見つけるための私の試みです:http: //pastebin.com/8PS1frc0

私のコードに関する現在の問題:

  • 読み取り値が変動すると(サンプルデータのスパンに見られるように11/14/2010=>11:30:0011/14/2010=>11:54:00、方向ロジックに「ぐらつき」が生じます。これにより、誤ったピークとトラフが作成されます。どうすればこれを回避/修正できますか?

注:私の方法は非常に「アドホック」です。平均、近似、または将来の見積もりを見つけようとはしていないので、すばらしい数学は必要ないと思いました。これまでに書いたコードを捨てることを意味するとしても、より良い方法のコード例を本当に感謝します。

4

7 に答える 7

3

ノイズの多い生理学的データに対して同様のタスクを実行する必要がありました。私の意見では、シグナルコンディショニングの問題があります。これが私のために働いたプロセスです。

  1. 時間の値を秒、つまり(HH * 3600)+(MM * 60)+(SS)に変換して、数値の「X」値を生成します。
  2. 結果のX配列とY配列を、たとえば幅10ポイントのスライドウィンドウで滑らかにします。このステップでは、冗長なタイムスタンプや偽のタイムスタンプを使用してデータをフィルタリングすることも検討してください。
  3. 平滑化されたY[1]とY[0]を比較して、指示位相検出を実行します。上記の投稿と同様に、(Y [1]> Y [0])の場合、データがピークに達していると見なすことができます。(Y [1] <Y [0])の場合、データは谷に向かって下降していると見なすことができます。
  4. 初期段階がわかれば、上記のようにピークとトラフの検出を実行できます。Y[i]> Y [i+1]およびY[i]<Y [i-1]の場合、ピークに遭遇しています。
  5. スライディングウィンドウのサイズを考慮して、平滑化されたX値を元のXデータに投影することにより、ピーク/トラフ時間を推定できます(スライディングウィンドウによって引き起こされる「信号の遅れ」を補正するため)。結果の時間値(秒単位)は、レポート用にHH:MM:SS形式に変換して戻すことができます。
于 2010-11-15T21:21:15.690 に答える
2

あなたは極小値と極大値を探していると思いますか?それは本当に簡単です:

<?php

$data = array(1, 9, 4, 5, 6, 9, 9, 1);

function minima($data, $radius = 2)
{
  $minima = array();

  for ($i = 0; $i < count($data); $i += $radius)
  {
    $minima[] = min(array_slice($data, $i, $radius));
  }

  return $minima;
}

function maxima($data, $radius = 2)
{
  $maxima = array();

  for ($i = 0; $i < count($data); $i += $radius)
  {
    $maxima[] = max(array_slice($data, $i, $radius));
  }

  return $maxima;
}

print_r(minima($data));
print_r(maxima($data));

?>

検索範囲を指定するだけで、データの極小値と極大値の配列が返されます。単純な方法で機能します。配列を長さのセグメントにカットし、$radiusそのセグメントの最小値を見つけます。このプロセスは、データセット全体に対して繰り返されます。

半径に注意してください。通常、データの山から谷までの平均距離となる半径を選択する必要がありますが、手動で見つける必要があります。デフォルトは2、で、半径内の最小値/最大値のみを検索し2ます。これにより、データセットで誤検知が発生する可能性があります。 半径を賢く選択してください。

スクリプトにハックする必要がありますが、それほど難しいことではありません。

幸運を!

于 2010-11-22T18:33:52.083 に答える
1

私はそれを詳細に読んでいませんが、あなたのアプローチは非常にアドホックなようです。より正しい方法は、おそらくそれを関数に適合させることです。

 f(A,B,w,p;t)=Asin(wt+p)+B 

非線形最小二乗法などの方法を使用します(残念ながら、反復法を使用して解決する必要があります)。サンプルデータを見ると、ぴったりのようです。wとpを計算したら、関数の時間微分を取り、ゼロを解くだけで、山と谷を簡単に見つけることができます。

t = (pi(1+2n)-2p)/w

しかし、あなたのコードが本当にあなたが望むことをしているのなら、物事を複雑にする意味はないと思います。二番目に推測するのをやめなさい。:)

于 2010-11-12T20:05:39.633 に答える
1

問題は、観測は観測であり、小さなエラーが含まれている可能性があると思います。少なくともそれを説明する必要があります。例えば:

  • 少なくとも次の2つのエントリも同じ方向にある場合にのみ、方向を変更します。

  • わずかな違いに関するデータによって決定を下さないでください。取るに足らない数を捨てなさい。$error = 0.10;条件をif $previous - $error > $currentetceteraに変更すると、おそらくはるかに良くなります。

于 2010-11-22T20:11:08.253 に答える
0

ピーク/バレーの検出はどの程度正確である必要がありますか?山や谷が発生する正確な記録を見つける必要があるだけなら、変曲点をチェックするだけで十分ではありませんか?

たとえば、位置'i'のレコードを考えると、record[i-1]とrecord[i +1]の両方がrecord[i]よりも「高い」場合、谷があります。また、record[i-1]とrecord[i +1]の両方がrecord[i]よりも低い場合は、ピークがあります。サンプリングレートが潮の変化よりも速い限り(ナイキスト周波数を調べてください)、そのプロセスでデータのピーク/トラフを取得できます。

これからグラフを生成し、ピーク/トラフのより正確な時点を推定する必要がある場合は、さらに作業を行う必要があります。

于 2010-11-12T21:31:04.947 に答える
0

1つの方法は、既存のピーク/トラフの周りの変動ではなく、新しいピーク/トラフとして分類する過去の絶対または相対偏差を定義することです。

現在、$direction山か谷かを判断しているので、導関数の符号が変わったら他の状態に移行する(谷か山を見つける)のではなく、現在の山/谷からの偏差がある場合にのみ状態を変更することを検討できます。十分に「大きい」です。

于 2010-11-22T18:02:19.107 に答える
0

約12時間以内に最大2分または2分が表示されないことを考えると、簡単な解決策は、3〜5時間程度のスライドウィンドウを使用して、最大値と最小値を見つけることです。それが最初または最後の30分になってしまう場合は、無視してください。

例として、次のデータが与えられます。

1 2 3 4 5 6 5 6 7 8 7 6 5 4 3 2 1 2

サイズ8のウィンドウで、最初と最後の2つは無視され、ピークのみが表示されます。

1 2 | 3 4 5 6 | 5 6,  max = 6, ignore = Y
2 3 | 4 5 6 5 | 6 7,  max = 7, ignore = Y
3 4 | 5 6 5 6 | 7 8,  max = 8, ignore = Y
4 5 | 6 5 6 7 | 8 7,  max = 8, ignore = Y
5 6 | 5 6 7 8 | 7 6,  max = 8, ignore = N
6 5 | 6 7 8 7 | 6 5,  max = 8, ignore = N
5 6 | 7 8 7 6 | 5 4,  max = 8, ignore = N
6 7 | 8 7 6 5 | 4 3,  max = 8, ignore = N
7 8 | 7 6 5 4 | 3 2,  max = 8, ignore = Y
8 7 | 6 5 4 3 | 2 1,  max = 8, ignore = Y
7 6 | 5 4 3 2 | 1 2,  max = 7, ignore = Y
于 2010-11-22T19:55:48.330 に答える