use*_*853 4 python numpy scipy
我有一组 x、y 点,我想找到最适合的线,使该线低于使用 SciPy 的所有点。我正在尝试为此使用 leastsq ,但我不确定如何将线调整为低于所有点而不是最佳拟合线。最佳拟合线的系数可以通过以下方式产生:
def linreg(x, y):
fit = lambda params, x: params[0] * x - params[1]
err = lambda p, x, y: (y - fit(p, x))**2
# initial slope/intercept
init_p = np.array((1, 0))
p, _ = leastsq(err, init_p.copy(), args=(x, y))
return p
xs = sp.array([1, 2, 3, 4, 5])
ys = sp.array([10, 20, 30, 40, 50])
print linreg(xs, ys)
Run Code Online (Sandbox Code Playgroud)
输出是最佳拟合线的系数:
array([ 9.99999997e+00, -1.68071668e-15])
Run Code Online (Sandbox Code Playgroud)
如何获得低于所有点的最佳拟合线的系数?
一种可能的算法如下:
移动轴以在 x 轴的正半部分获得所有数据。
如果拟合的形式为y = a * x + b,那么对于给定b的最佳拟合a将是连接点(0, b)与每个点的斜率的最小值(x, y)。
然后,您可以计算拟合误差,该误差仅是 的函数b,并用于scipy.optimize.minimize找到 的最佳值b。
所有剩下的就是计算a该b和计算b的轴的原始位置。
以下大部分时间都是这样做的,除非最小化失败并出现一些神秘错误:
from __future__ import division
import numpy as np
import scipy.optimize
import matplotlib.pyplot as plt
def fit_below(x, y) :
idx = np.argsort(x)
x = x[idx]
y = y[idx]
x0, y0 = x[0] - 1, y[0]
x -= x0
y -= y0
def error_function_2(b, x, y) :
a = np.min((y - b) / x)
return np.sum((y - a * x - b)**2)
b = scipy.optimize.minimize(error_function_2, [0], args=(x, y)).x[0]
a = np.min((y - b) / x)
return a, b - a * x0 + y0
x = np.arange(10).astype(float)
y = x * 2 + 3 + 3 * np.random.rand(len(x))
a, b = fit_below(x, y)
plt.plot(x, y, 'o')
plt.plot(x, a*x + b, '-')
plt.show()
Run Code Online (Sandbox Code Playgroud)
正如 TheodrosZelleke 明智地预测的那样,它经过两个点,它们是凸包的一部分:
