データセットのピークを見つけるにはどうすればよいですか?


47

次のようなグラフを生成するデータセットがある場合、表示されたピーク(この場合は3つ)のx値をアルゴリズムで決定するにはどうすればよいでしょうか。

ここに画像の説明を入力してください


13
6つの極大が見られます。どの3つを参照していますか?:-)。(もちろん、それは明白だ-それは良いアルゴリズムを作成するための鍵だから、私の発言の推力は、より正確に「ピーク」を定義することをお勧めします。)
whuber

3
データがランダムノイズ成分が追加された純粋に周期的な時系列である場合、周期と振幅がデータから推定されるパラメーターである調和回帰関数に適合させることができます。結果として得られるモデルは、滑らかな周期関数(つまり、いくつかの正弦と余弦の関数)になります。したがって、一次導関数がゼロで二次導関数が負の場合、一意に識別可能な時点になります。それらがピークになります。一次導関数がゼロで二次導関数が正である場所は、トラフと呼ばれるものです。
マイケル・Chernick

2
modeタグを追加しました。これらの質問のいくつかをチェックしてください。興味のある回答があります。
アンディW

皆さんの回答とコメントに感謝します。大歓迎です!データに関連する推奨アルゴリズムを理解して実装するには時間がかかりますが、後でフィードバックで更新するようにします。
非公理

私のデータが本当にうるさいからかもしれませんが、以下の答えでは成功しませんでした。しかし、私はこの答えで成功しました:stackoverflow.com/a/16350373/84873
ダニエル

回答:


35

一般的なアプローチは、データ平滑化してから、極大フィルターと平滑化を比較してピークを見つけることです。でR

argmax <- function(x, y, w=1, ...) {
  require(zoo)
  n <- length(y)
  y.smooth <- loess(y ~ x, ...)$fitted
  y.max <- rollapply(zoo(y.smooth), 2*w+1, max, align="center")
  delta <- y.max - y.smooth[-c(1:w, n+1-1:w)]
  i.max <- which(delta <= 0) + w
  list(x=x[i.max], i=i.max, y.hat=y.smooth)
}

その戻り値には、x質問に答えるローカル最大値()の引数と、ローカル最大値が発生するxおよびy配列へのインデックス(i)が含まれます。

状況に合わせて調整する2つのパラメーターがあります w。ローカル最大値の計算に使用されるウィンドウの半幅です。(その値は、データの配列の長さの半分よりも大幅に短くする必要があります。)小さな値は小さなローカルバンプを拾いますが、大きな値はそれらの上を通過します。もう1つ(このコードでは明示的ではありません)spanは、loessスムーザーの引数です。(通常は0〜1です。x値の範囲の割合としてウィンドウ幅を反映します。)値を大きくすると、データがより積極的に平滑化され、ローカルバンプが完全に消えます。

このチューニングが有効であることを確認するために、結果をプロットするための小さなテスト関数を作成しましょう。

test <- function(w, span) {
  peaks <- argmax(x, y, w=w, span=span)

  plot(x, y, cex=0.75, col="Gray", main=paste("w = ", w, ", span = ", span, sep=""))
  lines(x, peaks$y.hat,  lwd=2) #$
  y.min <- min(y)
  sapply(peaks$i, function(i) lines(c(x[i],x[i]), c(y.min, peaks$y.hat[i]),
         col="Red", lty=2))
  points(x[peaks$i], peaks$y.hat[peaks$i], col="Red", pch=19, cex=1.25)
}

以下に、若干のノイズの多い合成データに適用したいくつかの実験を示します。

x <- 1:1000 / 100 - 5
y <- exp(abs(x)/20) * sin(2 * x + (x/5)^2) + cos(10*x) / 5 + rnorm(length(x), sd=0.05)
par(mfrow=c(3,1))
test(2, 0.05)
test(30, 0.05)
test(2, 0.2)

プロット

広いウィンドウ(中央のプロット)またはより積極的なスムーズ(下のプロット)のいずれかが、上のプロットで検出された局所的な最大値を除去します。積極的な平滑化はこれらのピークをシフトするように見えるため、ここでの最良の組み合わせは、おそらく広いウィンドウと穏やかな平滑化のみです(下のプロットの中央と右側のポイントを参照し、それらの位置を生データの見かけのピークと比較します)。この例では、w=50span=0.05偉大な仕事(図示せず)ん。

エンドポイントでの極大が検出されないことに注意してください。これらは個別に検査できます。(これをサポートするためにargmax、平滑化されたy値を返します。)


このアプローチには、汎用の作業のためのより正式なモデリングよりもいくつかの利点があります。

  • データの先入観のあるモデルは採用していません。

  • データ特性に適合させることができます。

  • 興味のあるピークの種類を検出するように適合させることができます。


3
それどころか、@ Michael:周期性については何も想定していません。実際、この例は周期的に見えますが、そうではありません。二次項に注意してください。この例(および他の多くのこのようなシリーズ)では、調和回帰が失敗します。さらに、「視覚的に」何も選択しません。すべてアルゴリズムで実行されます。(なぜこの回答を実際に読んでいないという強い印象を受けますか?)
whuber

1
1次および2次導関数テストによりアルゴリズム的にピークを見つけることができますが、他の手段(数値検索など)を使用する必要があります。私のポイントは、一方のアプローチが他方のアプローチよりも優れていると主張することでも、あなたの答えを批判することでもありませんでした。多くの類似点といくつかの相違点が見られるだけで、ピークを特定する方法をより明確に理解しようとしていました。
マイケルチャーニック

3
@Michaelピークは、移動する最大値を超えない場所です。これにより、計算が高速かつ簡単になります。数値検索はなく、単純なスキャンだけです。微分可能なスムースを使用する利点は、指定されたx値間のピークを補間できることです。これは、粗いまたは不均一なx解像度に役立ちます。O(n)
whuber

4
@Michael、回答/コメントを読む時間がない場合は、投稿への応答/断言を控えることを検討できます。これはあなたが繰り返しやってきたことであり、しばしば非建設的なやり取りや、後で撤回する誤ったステートメントを作成することにつながります。あなたの時間とあなたがそのような会話に従事する他の人の無駄のようです。たとえば、このコメントスレッド全体は、答えを読むだけで開始するよりも時間がかかります。この方法でサイトを使用することを選択する理由は、私を困惑させ続けています。私はそれがどのような利益をもたらすかわかりません。
マクロ

2
興味深いアプローチをありがとう。私はまた、マイケルがために到達されたポイントを得ると思う:あなたはのための最高の値を決定するためのチャートを表示するのに必要wspanし、また、より高い値があることを発見しspanたピークをずらしました。これらの手順も自動化できるように感じます。たとえば、最初の問題では、発見されたピークの品質を評価できればoptimize、パラメーターを実行できます。2番目の問題については、たとえば、検出されたピークの両側のウィンドウを選択し、より高い値を探します。
ダレン・クック

1

コメントで述べたように、時系列が周期的に適合しているように見える場合、調和回帰モデルは関数を平滑化し、1次および2次導関数テストを適用してピークを特定する方法を提供します。Huberは、複数のピークがあり、関数が必ずしも周期的ではない場合に利点があるノンパラメトリックテストを指摘しました。しかし、無料のランチはありません。彼が言及した彼の方法には利点がありますが、パラメトリックモデルが適切な場合は欠点があります。それは常にノンパラメトリック手法を使用することの裏返しです。パラメトリックな仮定を回避しますが、パラメトリックなアプローチは、パラメトリックな仮定が適切な場合に優れています。彼の手順は、データの時系列構造を十分に活用していません。

提案された手順の利点を指摘することは適切ですが、潜在的な欠点を指摘することも重要だと思います。私のアプローチとフーバーの両方が、効率的な方法でピークを見つけます。しかし、局所的最大値が以前に決定された最高ピークよりも低い場合、彼の手順はもう少し手間がかかると思います。


2
あなたのアプローチの「効率的な方法」を実証していただけますか?課題の一部が発見するアルゴリズムを考案することである、複数のピークを-あなたのケース手段見つけるのがそのすべてと、明示的であることをこれらの重要なポイントのどのあなたが分類されます-ちょうど1つのゼロではない、(費用をかけて計算された)誘導体のゼロを「ピーク」とそうでないものとして。また、「パラメトリックな仮定が適切な場合は、パラメトリックなアプローチの方が良い」という主張を支持または増幅することは良いことです。周知のように、パラメトリックな仮定は決して正確ではありません。
whuber

@whuberモデルをフィットすると、モデルは正弦と余弦の合計であるため、関数は周期的であるため、一次導関数がゼロでゼロ点の二次導関数が減少するときにピークが発生すると言いました。それは私があなたが一次と二次の派生テストを受けると言ったときの意味です。これで、すべての解を見つけるために解くことができますが、1つのピークがある場合、他の解はあなたが持っている解から1周期および複数周期離れています。私のポイントは、この方法の優位性を主張することではありません。ただ、無料のランチはありません。
マイケルチャーニック

ノンパラメトリック法には、モデリングの仮定を必要としないという利点があります。この場合、周期性の仮定はありません。モデリングの仮定が当てはまる場合、ノンパラメトリックアプローチよりもパラメトリックアプローチの方が優れているという私の声明は、ご存じのはずです。パラメトリックな仮定が正確に成り立つことについて議論する必要はありません。それは私が基本的に同意する意見です。しかし、私はピットマン効率のようなものについて話している。モデルが「正しい」場合、ノンパラメトリック推定はパラメトリック推定ほど効率的ではありません。
マイケルチャーニック

それが理論です。実際には、パラメトリックモデルは現実への適切な近似になります。その場合、パラメトリック推定(たとえばmle)はノンパラメトリック推定よりも効率的です。また、パラメトリック信頼区間はより厳密になるため、より良くなります。しかし、多くの場合、パラメトリックモデルがあなたの例にとってどれほど優れているかわかりません。このような場合、ノンパラメトリックアプローチによる保守主義(安全)またはパラメトリックアプローチを使用した大胆な(そしておそらく間違った)判断をする必要があります。
マイケルチャーニック

1
私が提案しようとしているのは、この場合、ノンパラメトリックアプローチは、データが特にモデルに近い場合を除いて、どのパラメトリックアプローチよりもはるかに優れている可能性が高いことです。周期性が良い例であると仮定すると、アルゴリズムはデータ内の周期性からの逸脱と同じ桁のエラーを起こします。このようなミスを犯す可能性があるため、漸近効率が向上することで得られる利点は無効になります。最初に大規模なGoFテストを実行せずにこのような手順を使用するのは悪い考えです。
whuber

1

信号処理における古典的なピーク検出アプローチは次のとおりです。

  1. サンプリングレートと信号特性に応じて、合理的な妥当な範囲に信号をフィルターします。たとえば、ECG、@ 0.5-20HzのIIRバンドパスフィルター、ゼロ位相フィルターは、位相シフト(および関連するタイムラグ)が生じないようにします。
  2. ヒルベルト変換またはウェーブレットアプローチを使用して、ピークを強調できます。
  3. 次に、静的または動的なしきい値を適用できます。ここで、しきい値を超えるすべてのサンプルがピークと見なされます。動的しきい値の場合、通常は、平均の移動平均推定値の上下の標準偏差Nとして定義されます。

機能するもう1つのアプローチは、シャープにハイパスフィルター処理された信号を非常に平滑化された(ローパスまたは中央値フィルター処理)と比較し、ステップ3を適用することです。

お役に立てれば。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.