一千萬個為什麽

搜索

在噪聲數據中查找局部最小值/最大值

我試圖在噪聲數據中找到局部最小值/最大值,包括在特定時間間隔采集的數據值。理想情況下,該函數應采用一對列表(一個包含時間值,一個包含觀察到的數據值)並返回最大值和最小值的坐標。

下面是一個數據示例:

temptimelist = Range[200]/10;
tempvaluelist = Sinc[#] &@temptimelist + RandomReal[{-1, 1}, 200]*0.02;

問題此處此處這裏有很多答案,它們不適合我的因為(據我所見),他們通過將數據與相鄰值進行比較來確定數據是否是局部最大值/最小值。如果我應用這樣的算法,我的極值將被識別如下:

data with peaks identified

我所做的是編寫以下代碼。

NoisyExtremaFinder = Function[{timeList, valueList, aroundRange},
   (*NoisyExtremaFinder[] takes a pair of lists timeList_ and valueList_ and determines extrema in valueList_, returning a list containing the coordinates (as pairs of time_ and value_) of the minima as the first entry and the maxima as the second entry. 

   As the data is assumed to be noisy, we provide the option aroundRange_ to allow the user to determine the sensitivity of the search. Specifically, when aroundRange_=n, the function will compare each value with the preceding and subsequent n values to determine whether it is an extrema*)

   extremaPosition = 
    [email protected][
       Map[#, Partition[valueList, 2*aroundRange + 1, 1, {-(1 + aroundRange), 1 + aroundRange}, {}]] - valueList, 0.] &
    (*extremaPosition[] is a custom function that determines the position of local Maxima or Minima in valueList_, with the sensitivity determined by the value of aroundRange. When aroundRange_=n, the function will compare each value with the preceding and subsequent n values to determine whether it is an extrema. You can either do extremaPosition[Max] or extremaPosition[Min] *)

   extremaPoints = 
    [email protected]{timeList[[#]], valueList[[#]]} &@extremaPosition[#] &
  (*extremaPoints[] is a custom function that determines the coordinates of local Maxima or Minima in valueList_

   Custom Functions Used: extremaPosition[]*)

   {extremaPoints[Min], extremaPoints[Max]}];

基本上,不是通過僅將點與相鄰項進行比較來確定點是否為極值,而是通過與 aroundRange 之前和 aroundRange 後續比較來確定該點是否為極值。點。

然後,通過添加以下代碼行,我們可以看到最終結果:

NoisyExtremaFinder[temptimelist, tempvaluelist, 10]; (*parameter "10" chosen by estimating the distance from peak to peak*)
ListPlot[Transpose[{temptimelist, tempvaluelist}], 
 Epilog -> {PointSize[Medium], Red, Point[extremaPoints[Min]], Green, 
   Point[extremaPoints[Max]]}, ImageSize -> 700]

better peaks

有沒有更好的方法來實現我想要的目標,比較一個點與 n 之前和之後的點?

     

rm-rf(在聊天中)也建議我在嘗試找到局部最小值/最大值之前先考慮平滑噪聲數據。但是,我擔心我可以通過平滑過程將不需要的工件添加到數據中。關於平滑,是否有一種常用於過濾實驗數據的算法?我查看的過濾器包括Savitsky-Golay過濾器和低通過濾器。

PS:我的數據集各有大約10,000個數據點。

最佳答案

另一種做事方式是使用小波。小波非常擅長去噪。

(*Define data and noise*)
temptimelist = Range[200]/10;
data = Sinc[temptimelist];
noise = RandomReal[{-0.02, 0.02}, 200];

(* Define Wavelet for denoising *)
dwd = DiscreteWaveletTransform[data + noise, SymletWavelet[7], 6];
(* Use universal threshold *)
dwd = WaveletThreshold[dwd];
(*Get denoişed values*)
est = InverseWaveletTransform[dwd];

ListLinePlot[{data, est, (data + noise)}, PlotRange -> All]

Once you denoised the data you can find extreme values described in other answers. wavelet-transformed data

例如,從@查看這個 Theodros Zelleke回答在列表中找到極值點。

findExtremaPos[list_List] := 
 Module[{signs, extremaPos, minPos, maxPos}, 
 signs = Sign[Differences[list]];
 signs = signs //. {a___, q_, 0, z__} -> {a, q, q, z};
 extremaPos = 1 + [email protected](Length /@ Split[signs]);
 If[[email protected] == 1, minPos = extremaPos[[2 ;; -2 ;; 2]]; 
 maxPos = extremaPos[[1 ;; -2 ;; 2]], 
 minPos = extremaPos[[1 ;; -2 ;; 2]]; 
 maxPos = extremaPos[[2 ;; -2 ;; 2]]];
 {minPos, maxPos}]

(*Evaluate extreme points*)
{minPos, maxPos} = findExtremaPos[est];

ListPlot[est, Joined -> True, 
 Epilog -> {PointSize[Large], Red, Point[{#, est[[#]]} & /@ minPos], 
 Blue, Point[{#, est[[#]]} & /@ maxPos]}, PlotRange -> All]

結果:

enter image description here

修改1

使用版本10,可以使用 FindPeaks 輕松找到峰值。

peaks = FindPeaks[est, .5]

{{2,1.0147576},{6,0.94715655},{78,0.13402331},{143,     0.066621946},{192,0.04389471},{197,0.041374537},{199,     0.060916925}}

ListPlot[{est, peaks}, Joined -> {True, False}, 
  PlotStyle -> {Automatic, {PointSize[.01], Red}}, PlotRange -> All]

enter image description here

轉載註明原文: 在噪聲數據中查找局部最小值/最大值