假设我有一个假设的函数,我想近似它:
def f(x): return a * x ** 2 + b * x + c
其中 a
、b
和 c
是未知的数值。
我有一些已知函数输出的点,例如:
x = [-1, 2, 5, 100]y = [123, 456, 789, 1255]
(实际上还有更多值)
我想在最小化平方误差的同时获得 a
、b
和 c
的值(另外还要得到那个平方误差)。
在 Python 中如何实现这个目标?
应该有现成的解决方案在 scipy
、numpy
或其他类似的库中。
回答:
由于你要拟合的函数是一个多项式,你可以使用 numpy.polyfit
>>> numpy.polyfit(x, y, 2) # 2 表示二次多项式array([ -1.04978546, 115.16698544, 236.16191491])
这意味着最佳拟合结果是 y ~ -1.05 x2 + 115.157x + 236.16。
对于一般函数,你了解的越多(例如,是否是凸函数,是否可微,是否二次可微等),你就能更好地使用 scipy.optimize.minimize
。例如,如果你几乎不了解函数的特性,你可以指定使用 Nelder-Mead 方法。其他方法(请参阅文档)可以利用雅可比矩阵和海森矩阵,如果它们被定义,并且你能计算它们的话。
就我个人而言,我发现使用 Nelder-Mead 方法(几乎不需要参数)可以满足我的需求,得到足够好的结果。
示例
假设你试图拟合 y = kx,其中 k 是要优化的参数。你可以编写一个函数
x = ...y = ...def ss(k): # 使用 numpy.linalg.norm 计算 y 和 kx 之间的平方和误差
然后你可以对函数 ss
使用 scipy.optimize.minimize
。