gpt4 book ai didi

wolfram-mathematica - 使用 Mathematica 识别时间序列中的重要最小值和最大值

转载 作者:行者123 更新时间:2023-12-04 17:58:01 25 4
gpt4 key购买 nike

我需要一种方法来使用 Mathematica 识别时间序列数据中的局部最小值和最大值。这看起来应该是一件容易的事情,但它变得棘手。我把这个贴在 MathForum 上,但我想我可能会在这里得到一些额外的关注。

您可以在以下位置找到讨论该问题的论文:http://www.cs.cmu.edu/~eugene/research/full/compress-series.pdf

到目前为止我已经尝试过这个......

获取并格式化一些数据:

data = FinancialData["SPY", {"May 1, 2006", "Jan. 21, 2011"}][[All, 2]];
data = data/First@data;
data = Transpose[{Range[Length@data], data}];

定义2个函数:

第一种方法:
findMinimaMaxima[data_, window_] := With[{k = window},
data[[k + Flatten@Position[Partition[data[[All, 2]], 2 k + 1, 1], x_List /; x[[k + 1]] < Min[Delete[x, k + 1]] || x[[k + 1]] > Max[Delete[x, k + 1]]]]]]

现在是另一种方法,虽然不那么灵活:
findMinimaMaxima2[data_] := data[[Accumulate@(Length[#] & /@ Split[Prepend[Sign[Rest@data[[All, 2]] - Most@data[[All, 2]]], 0]])]]

看看每个函数的作用。首先找到MinimaMaxima2[]:
minmax = findMinimaMaxima2[data];
{Length@data, Length@minmax}
ListLinePlot@minmax

这将选择所有最小值和最大值,并以大约 49% 的数据压缩结果(在本例中),但它没有扩展窗口的灵活性。
这另一种方法可以。窗口为 2,产生更少且可以说更重要的极值:
minmax2 = findMinimaMaxima[data, 2];
{Length@data, Length@minmax2}
ListLinePlot@minmax2

但是看看当我们将窗口扩大到 60 时会发生什么:
minmax2 = findMinimaMaxima[data, 60];
ListLinePlot[{data, minmax2}]

一些最小值和最大值不再交替。
将 findMinimaMaxima2[] 应用于 findMinimaMaxima[] 的输出给出了一种解决方法......
minmax3 = findMinimaMaxima2[minmax2];
ListLinePlot[{data, minmax2, minmax3}]

,但这似乎是解决问题的笨拙方法。

因此,使用固定窗口向左和向右看的想法并不能满足人们的所有愿望。我开始考虑可以使用范围值 R(例如向上或向下移动百分比)的替代方案,该函数需要满足或超过以设置下一个最小值或最大值。这是我的第一次尝试:
findMinimaMaxima3[data_, R_] := Module[{d, n, positions},
d = data[[All, 2]];
n = Transpose[{data[[All, 1]], Rest@FoldList[If[(#2 <= #1 + #1*R && #2 >= #1) || (#2 >= #1 - #1* R && #2 <= #1), #1, #2] &, d[[1]], d]}];
n = Sign[Rest@n[[All, 2]] - Most@n[[All, 2]]];
positions = Flatten@Rest[Most[Position[n, Except[0]]]];
data[[positions]]
]

minmax4 = findMinimaMaxima3[data, 0.1];
ListLinePlot[{data, minmax4}]

这也受益于使用 findMinimaMaxima2[] 的后期处理
ListLinePlot[{data, findMinimaMaxima2[minmax4]}]

但是,如果您仔细观察,您会发现如果它们在多个位置超出 R 值,它就会错过极端情况 - 包括图表的绝对最小值和最大值以及沿着大的上下移动。更改 R 值显示它如何更加错过顶部和底部:
minmax4 = findMinimaMaxima3[data, 0.15];
ListLinePlot[{data, minmax4}]

所以,我需要重新考虑。任何人都可以查看数据图并轻松识别重要的最小值和最大值。让算法来做这件事似乎更难。窗口和/或 R 值似乎对解决方案很重要,但它们本身似乎都不够(至少在上述方法中不是这样)。

任何人都可以扩展显示的任何方法或建议替代方法来识别重要的最小值和最大值吗?

很高兴转发一个包含所有这些代码和讨论的笔记本。让我知道是否有人需要它。

谢谢,
贾格拉

最佳答案

我建议使用迭代方法。以下函数取自 this post ,虽然它们可以在没有 Compile 的情况下更简洁地编写,但它们将完成这项工作:

localMinPositionsC = 
Compile[{{pts, _Real, 1}},
Module[{result = Table[0, {Length[pts]}], i = 1, ctr = 0},
For[i = 2, i < Length[pts], i++,
If[pts[[i - 1]] > pts[[i]] && pts[[i + 1]] > pts[[i]],
result[[++ctr]] = i]];
Take[result, ctr]]];

localMaxPositionsC =
Compile[{{pts, _Real, 1}},
Module[{result = Table[0, {Length[pts]}], i = 1, ctr = 0},
For[i = 2, i < Length[pts], i++,
If[pts[[i - 1]] < pts[[i]] && pts[[i + 1]] < pts[[i]],
result[[++ctr]] = i]];
Take[result, ctr]]];

这是您的数据图:
dplot = ListLinePlot[data]

这里我们绘制了经过 3 次迭代后获得的 mins:
mins = ListPlot[Nest[#[[localMinPositionsC[#[[All, 2]]]]] &, data, 3],
PlotStyle -> Directive[PointSize[0.015], Red]]

最大值相同:
maxs = ListPlot[Nest[#[[localMaxPositionsC[#[[All, 2]]]]] &, data, 3],
PlotStyle -> Directive[PointSize[0.015], Green]]

以及由此产生的情节:
Show[{dplot, mins, maxs}]

enter image description here

您可以改变迭代次数,以获得更粗粒度或更细的最小值/最大值。

编辑:

实际上,我只是注意到这种方法仍然遗漏了几点,无论是对于
最小值和最大值。所以,我建议把它作为一个起点,而不是一个完整的解决方案。也许,你
可以分析来自不同迭代的最小值/最大值,有时还包括来自“前一个”、更细粒度的迭代。此外,这种工作的唯一“物理原因”是财务数据的性质似乎是分形的,具有几个明显不同的尺度。上述 Nest-s 中的每次迭代都针对特定的规模。对于任意信号,这不会很好地工作。

关于wolfram-mathematica - 使用 Mathematica 识别时间序列中的重要最小值和最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4809313/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com