【问题标题】:Find the "peak" of a set of data找到一组数据的“峰值”
【发布时间】:2015-06-19 20:42:14
【问题描述】:

我有一组数据,我想为其找到一个平均峰值。我在 Numbers.app 中做了一些测试,看看我在做什么,如果我制作数据集的图表,它有一个称为“多项式趋势线”的功能,它绘制数据曲线,该曲线的峰值看起来就像我追求的点/价值一样。

那么我如何以编程方式计算该曲线并找到曲线上的切线?

我一直在维基百科上四处寻找,发现诸如“正态分布”和“多项式回归”之类的主题似乎非常相关,但我一直发现很难遵循维基百科上的方程式,所以我希望也许这里有人可以给我一个程序示例。

这里有几个图表来说明我所追求的。绿点是数据点,蓝线是“多项式趋势线”(6 阶)。 那条趋势线的“高峰”就是我所追求的。

更新问题:

在回答了一些问题后,我意识到我的问题需要重新表述,因为问题不在于如何找到曲线的峰值,而在于如何从绿点生成蓝色曲线,以便我可以在数据集中找到“重量”的谎言。 目标是获得某种“平均最大值”

我想另一个问题是“这个特定问题实际上叫什么?” ;)

【问题讨论】:

标签: normal-distribution


【解决方案1】:

虽然数据看起来你不一定符合正态分布。

分布拟合的主题相当复杂,除非您对自己的数据分布有一些明确的先验假设,否则我不会冒险。如果您对分布类型有假设,请查看 least squaresmaximum likelihood extimation 方法。

但是,我建议您最好使用bezier-splineLOESS 来“平滑”您的数据,然后找到计算曲线的最大值。

我怀疑使用导数的方法在这里是否可行。

【讨论】:

【解决方案2】:

正如您所说的正态分布,并且似乎能够将数据拟合到函数中,您应该拟合正态分布,其中 jas 参数 µσ 分别是平均值和标准差分布(见wiki第一个公式)。

将此函数拟合到您的数据中,峰值将位于平均值处,由µ 给出。

【讨论】:

    【解决方案3】:

    您可以从计算平均值和标准差/方差开始。这会告诉你一些关于分布的信息。

    我认为您无法解决任意数据集的问题。所以你需要有一些共同的特征行为。

    毕竟,根据方法,拟合曲线可能是任意的 - 需要适当地为您的问题域选择 - 也许需要进行一些权重或数据清洁才能首先抛出外围值。

    【讨论】:

    • 没错,我会用一些示例数据集更新我的问题(也许更多的是对我的问题的解释)。
    【解决方案4】:

    Derivative 在峰值处等于零。

    【讨论】:

    • 啊,对了,这是我从学校开始就忘记的另一个术语。如果我记得的话,“山谷”也为零。但是运行 max(d1,d2,d3) 会发现我的最佳点。但现在我只需要弄清楚如何制作这条曲线来找到导数。 ;)
    • @Robert Sköld 你应该刷新你的数学(实际上是微积分)。点 x 的数值导数可以计算为 f(x + 1) - f(x),因此如果您有点 1 2 3 3 2 1,则导数将为 1 1 0 -1 -1。那么是的,找到最大值。
    【解决方案5】:

    假设您正在绘制 Y 与 X。您已经有了与每个 X 对应的 Y 值。当 X=X1 时,让 Y(X1) 表示 Y 的平均值。

    设置变量 max = 0。然后计算每个 X 处的 Y 值。如果 Y(X1) > max 则设置 max=Y(X)。一旦你经历了所有的 Y,你将拥有的最大值将是 Y 的峰值。

    例如,在您的示例中,只需遍历所有绿点并找到其中的最大值。那应该是巅峰吧?让我知道这是否是你想要的。您使用哪种编程语言?你不需要为了达到顶峰而进入发行版和其他东西..

    【讨论】:

    • 稍微更新了我的问题,但正如您在第二张图片中看到的那样,目标将位于两个“最大值”之间,这就是为什么我希望峰值更“加权”(或任何正确的术语),这就是为什么该趋势线看起来是正确的。而编程语言最终将是javascript......
    【解决方案6】:

    我是一个完全“R”的新手,但我一直在自己的数据中处理同样的事情,所以我想我会分享。我相信我会因为这是一种不好的方式(或者不是一种“整洁”的方式)而变得松懈,但对我来说是这样的——至少现在是这样。

    我有 50 个数据集,它们的峰形与您的类似(每个数据集的前导斜率较大,下降边缘的斜率较慢)。首先,我测试了一些多项式拟合以获得最佳“适合目的”,但没有过度拟合...... x

    在这种情况下,多项式 11 是没有过拟合的最佳拟合。然后,您可以运行 ANOVA 并确保,但我会跳过所有这些。

    现在我根据上面“lm”的系数创建了多项式。 适合=lm(y~poly(x,11,raw=TRUE)) fit.coef

    然后是导数:

    fit.deriv <- deriv(fit.poly)
    

    现在对于峰值的斜率,您可以简单地将 x (max) 的值从原始多项式替换为导数。

    我想要所有的斜坡,所以......

    fit.slope <- predict(fit.deriv,x) ## x here represents all the x values above.  For a single value you can just replace x with the value of x representing the max value in your polynomial
    

    希望对原始问题有所帮助,同时邀请 cmets 如何更好地做到这一点,因为我也很想学习和清理我的代码!

    谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      • 2016-07-24
      • 2010-12-07
      • 2014-09-23
      • 2018-02-09
      相关资源
      最近更新 更多