1

我有一组曲线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

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

4

3 回答 3

4

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

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')

在此处输入图像描述

于 2013-08-16T01:36:35.840 回答
1

这是我建议的方法:

  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)
于 2013-08-16T06:34:36.610 回答
1

这是一种可能的解决方案。这结合了您原始帖子中的一些评论,以及上面@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 > model2如果model1(x) > model2(x)对于所有x(鉴于上面的插值)。这仅定义了部分顺序,但如果您的模型具有正确的属性,这可能就非常有用了。鉴于此,您可以执行类似于二进制搜索的操作。或者,您可以做一个分支定界的事情,其中​​边界由数据中的第一个值和函数中的第一个值之间的距离给出。取决于您的功能和数据的性质,可能有帮助也可能没有帮助。如果您需要一个几乎准确但不一定是最佳答案等,您可以考虑一些解决方案,等等等等。简而言之,要超越上面的琐碎答案,我认为我们需要更多地了解您的时间限制,数据和模型。

于 2013-08-16T04:32:07.470 回答