scipy.optimize.leastsq中的奇怪行为

时间:2015-11-24 15:58:29

标签: python scipy

在尝试拟合一些嘈杂的数据时,我注意到了一些不寻常的行为:当我改变数组的长度时,我得到了不同的拟合。

import numpy as np
import matplotlib.pyplot as plt
# set up true function and "measured" data
x = np.linspace(0, 6e-2, 500);
A, k, theta = 10, 1.0 / 3e-2, np.pi / 6;
y_true = A * np.sin(2 * np.pi * k * x + theta);
y_meas = y_true + 2*np.random.randn(x.size);
plt.plot(x, y_meas);
plt.plot(x, y_true);
plt.show()

给出了这张图片:

Noisy Data

我已经创建了一些辅助函数,然后我做了最小二乘拟合:

# residual function, e_i
def residuals(p, y, x):
    A, k, theta = p;
    err = y - A * np.sin(2 * np.pi * k * x + theta);
    return err;

def peval(x, p):
    return p[0] * np.sin(2 * np.pi * p[1] * x + p[2]);

# starting values of A, k and theta
p0 = [12, 1 / 2.3e-2, np.pi / 3];
print(np.array(p0));

# do least squares fitting
from scipy.optimize import leastsq

plsq = leastsq(residuals, p0, args=(y_meas, x));
print(plsq[0]); print(np.array([A, k, theta]));

绘制图表给出:

plt.plot(x, peval(x, plsq[0]))
plt.plot(x, y_meas,'ro')
plt.plot(x, y_true);
plt.title('Least-squares fit to noisy data');
plt.legend(['Fit', 'Noisy', 'True']);

Least squares fit to noisy data

当我将我的设置更改为:

x = np.linspace(0, 18e-2, 500);
A, k, theta = 10, 1.0 / 3e-2, np.pi / 6;
y_true = A * np.sin(2 * np.pi * k * x + theta);
y_meas = y_true + 2*np.random.randn(x.size);

(即我将测量的时间长度增加了三倍),然后运行剩下的代码,我得到的拟合变为:

Very bad fit

我已尝试单步执行代码,但无法提出此示例失败的原因。

1 个答案:

答案 0 :(得分:1)

如果您尝试初始猜测

p0=[12.0, 35.0, 0.39269908169872414]

它可以在两种情况下都有效。您使用的初始参数是给出残差> 60E3。

请记住,增加点数会改变问题,如果你检查https://en.wikipedia.org/wiki/Least_squares中的非线性最小二乘法,你可以看到在执行最小化时存在点数之和,所以当添加更多点时,适合不起作用并不罕见。