我正在尝试学习如何使用 python // 优化适合更高维度的numpy
数据scipy
。成功地使用 scipy 来适应表格的一行后y = f(x)
,我尝试扩展逻辑以适应表格的椭圆z = f(x, y)
;两者都如下所示。我希望这种方法可以推广到适合更高维度(即球体)的形状。
import numpy as np
from scipy.optimize import minimize
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
## LINE EXAMPLE
npoints = 30
x = np.linspace(-5, 5, npoints)
m, b = 3, -4 # slope, y-intercept
initial_parameter_guess = (2.5, -1)
y = m * x + b # exact line
noise = np.random.uniform(-1, 1, size=x.size)
yn = y + noise # line with noise
def get_residuals(prms, x, y):
""" """
return (y - (prms[0] * x + prms[1]))**2
def f_error(prms, x, y):
""" """
resid = get_residuals(prms, x, y)
return np.sum(resid)
result = minimize(f_error, x0=initial_parameter_guess, args=(x, yn))
# print(result)
yf = result.x[0] * x + result.x[1]
fig, ax = plt.subplots()
ax.scatter(x, yn, color='b', marker='.')
ax.plot(x, yf, color='r', alpha=0.5)
ax.grid(color='k', alpha=0.3, linestyle=':')
plt.show()
plt.close(fig)
将此逻辑应用于椭圆的情况,
## ELLIPSE EXAMPLE
npoints = 75
theta = np.random.uniform(0, 2*np.pi, size=npoints)
a, b = (3, 5)
initial_parameter_guess = (2.5, 6)
xnoise = np.random.uniform(-1, 1, size=theta.size)
ynoise = np.random.uniform(-1, 1, size=theta.size)
x = a**2 * np.cos(theta)
xn = x + xnoise
y = b**2 * np.sin(theta)
yn = y + ynoise
def get_residuals(prms, x, y):
""" """
return 1 - ((x/prms[0])**2 + (y/prms[1])**2)
def f_error(prms, x, y):
""" """
resid = get_residuals(prms, x, y)
return np.sum(resid)
result = minimize(f_error, x0=initial_parameter_guess, args=(xn, yn))
# print(result)
minimize
算法viascipy
没有找到最优参数;以下输出显示为print(result)
:
fun: -4243.611573066522
hess_inv: array([[41.44400248, 39.68101343],
[39.68101343, 37.99343048]])
jac: array([-1496.81719971, 2166.68896484])
message: 'Desired error not necessarily achieved due to precision loss.'
nfev: 174
nit: 1
njev: 42
status: 2
success: False
x: array([-1.51640333, 2.93879038])
我已经看到了这个问题的另一种解决方案,它使用最小二乘的矩阵公式,但是这个例子对我来说有点难以理解。我见过的几乎所有方法都基于发布链接中的方法。我更喜欢使用minimize
,除非由于我目前不知道的原因,线性代数方法更好。
无论如何,我上面的方法可以以一种可行的方式进行调整/调整,并且可以推广到更高的维度吗?