【问题标题】:Best fit from a set of curves to data points从一组曲线到数据点的最佳拟合
【发布时间】:2013-12-24 00:51:57
【问题描述】:

我有一组曲线F={f1, f2, f3,..., fN},每个曲线都通过一组点定义,即:我没有函数的显式形式。所以我有一组像这样的N 表:

#f1: x  y
1.2  0.5
0.6  5.6
0.3  1.2
...

#f2: x  y
0.3  0.1
1.2  4.1
0.8  2.2
...

#fN: x  y
0.7  0.3
0.3  1.1
0.1  0.4
...

我还有一组观察/测量的数据点O=[p1, p2, p3,..., pM],其中每个点都有x, y 坐标和[0, 1] 之间的给定权重,所以它看起来像:

#O: x  y  w
0.2  1.6  0.5
0.3  0.7  0.3
0.1  0.9  0.8
...

由于N ~ 10000(我有大量函数),我正在寻找一种有效(更准确地说:快速)方法来找到最适合我观察到的曲线和加权O

当我有函数的显式形式 (scipy.optimize.curve_fit) 时,我知道如何找到与 python 的最佳匹配,但是当我将函数定义为表时,我该怎么做?

【问题讨论】:

  • “最适合”没有明确的定义。 “有效”标准也不是很清楚 - 每条曲线的数据点数量线性的解决方案是否足够,或者您需要更快的东西吗?是否可以简单地计算每条曲线和每个观察集之间的平方差的加权和,以保持该曲线在你去时产生最小误差,或者你需要更快的东西吗?加权误差平方和是“最佳”的正确定义吗?
  • 加权平方和误差是我的想法,是的。 “高效”实际上是指“快速”。考虑到我有大约 100000 个函数和近 200 个 O 集,这提供了大约 2000000 次迭代,这是相当多的。我需要它尽可能快。
  • 您没有指定权重在拟合中的作用。
  • @elyase 我不确定我理解你的意思。权重表明给定点在用于评估“最佳拟合”的任何方案中都应该具有更大的重要性(例如,参见goo.gl/MdIO3V)。
  • 不幸的是,没有算法可以自动将任何数据与“最佳”拟合(更不用说权重约束)。您必须为您的数据指定一个基础模型(线性模型、高斯过程、SVR)。如果您显示数据图,我们可以为您提供帮助,但这不是编程问题。

标签: python performance curve-fitting


【解决方案1】:

您需要两个元素才能进行拟合,即数据(您已经拥有)和模型空间(线性模型、高斯过程、支持向量回归)。在您的情况下,您的模型具有额外的约束,即某些数据点的权重应该与其他数据点不同。可能对您有用:

from scipy.interpolate import UnivariateSpline

temp = np.asarray([10, 9.6, 9.3, 9.0, 8.7])
height = np.asarray([129, 145, 167, 190, 213])
f = UnivariateSpline(height, temp)

现在您可以随时随地评估f

test_points = np.arange(120, 213, 5)  
plot(height, temp, 'o', regular_heights, f(test_points), 'x')

【讨论】:

    【解决方案2】:

    这是一种可能的解决方案。这结合了您原始帖子中的一些 cmets,以及上面@elyase 的解决方案。 @elyase 提供了一种在每个函数的点之间进行插值的方法。鉴于此,最佳拟合的定义是加权平方和,我认为以下内容可以满足您的要求:

    # Here a model is an interpolated function as per @elyase's solution above
    min_score = sys.float_info.max
    best_model = None
    for model in models:
        # data is an array of (x, y, weight) tuples
        score = 0.0
        for data_point in data:
            w = data_point[2]
            x = data_point[0]
            y = data_point[1]
            score += w * (y - model.get_y(x)) ** 2
        if score < min_score:
            best_model = model
    return best_model
    

    您提到您需要一个“快速”的解决方案。根据您上面的回答,对每组数据执行上述操作总共会产生大约 200 万次迭代。这不应该超过几秒钟,即使使用 Python 也是如此。够快吗?

    否则,事情会变得复杂得多。例如,您可以尝试按排序顺序存储您的模型(您在上面将它们称为函数),这样 model1 &gt; model2 if model1(x) &gt; model2(x) 对于所有 x (给定上面的插值)。这仅定义了部分顺序,但如果您的模型具有正确的属性,这可能会非常有用。鉴于此,您可以执行类似于二进制搜索的操作。或者,您可以做一个分支定界的事情,其中​​边界由数据中的第一个值和函数中的第一个值之间的距离给出。取决于您的功能和数据的性质,可能有帮助也可能没有帮助。如果您需要一个几乎准确但不一定是最佳答案等,您可以考虑一些解决方案,等等等等。简而言之,要超越上面的琐碎答案,我认为我们需要更多地了解您的时间限制,数据和模型。

    【讨论】:

      【解决方案3】:

      这是我建议的方法:

      1. 将所有函数放在一个 numpy 数组中
      2. 计算测试数据中每个点与每个函数中每个点之间的平方距离 (您也可以计算精确距离,但 sqrt 很昂贵)
      3. 将误差计算为距离的加权总和(或根据自己的喜好进行修改)
      4. 找出最小误差

      例如:

      import numpy as np
      
      # define an array of N=3 functions
      funcs = np.array([
          [[0, 1, 2, 3, 4, 5],  # x1
           [0, 1, 2, 1, 0, 0]], # y1
          [[0, 1, 2, 3, 4, 5],  # x2
           [0, 0, 0, 1, 2, 3]], # y2
          [[0, 1, 2, 3, 4, 5],  # x3
           [5, 4, 3, 2, 1, 0]]  # y3
          ], dtype=float)
      
      # define the test data and weights with the same
      # dimensions as function array
      data = np.array([
          [[0, 1, 2, 3, 4, 5],  # x
           [0, 1, 2, 2, 1, 0]]  # y
          ], dtype=float)
      
      weight = np.array([
          [0.1, 0.2, 0.3, 0, 0, 0]  # w
          ])
      
      # compute distance between points in data and each function:
      dist = ((funcs - data) ** 2).sum(axis=1)
      
      # compute weighted error across all functions:
      err = (dist * weight).sum(axis=1)
      
      print "Errors:", err
      print "Best fit:", np.argmin(err)
      

      【讨论】:

      • 卢克这看起来是一个合理的答案,但它提出了两个我无法做出的强有力假设:1- 函数并非都由相同数量的点定义(有些点多一些少一些)和 2 - 数据点肯定与函数的维度不同。
      • 在这种情况下,您可以使用 scipy.interpolate.griddata 将每个函数插入到数据 x 值上,然后继续进行相同的距离/误差计算。
      猜你喜欢
      • 1970-01-01
      • 2012-06-22
      • 2020-02-14
      • 2014-05-18
      • 2011-01-31
      • 2017-03-31
      • 1970-01-01
      • 2019-03-31
      相关资源
      最近更新 更多