我想为多项式执行约束最小二乘法。在此之前,我决定尝试无限制的优化。这是问题所在:
我的多项式看起来像
$ f(x)= ax ^ 4 + bx ^ 3 + cx ^ 2 + dx + e $
所以我想找到最佳系数a,b,c,d和e。我希望最小化的功能看起来像
def lsq(args, x, y):
return sum([(y[i] - (args[0]*x[i]**4 + args[1]*x[i]**3 + args[2]*x**2 + args[3]*x + args[4]))**2
for i in np.arange(len(x))])
x
和y
是我的点坐标列表。因此,我的代码可能如下所示:
import numpy as np
import scipy.optimize
pH = np.array([8,8,8,7,7,7,7,7,7,7,7,7,6,3,2,2,2,1])
def rank2(y):
return np.array([(i+1)/len(y) for i in range(len(y))])
x = rank2(pH)
y = pH
def lsq(args, x, y):
return sum([(y[i] - (args[0]*x[i]**4 + args[1]*x[i]**3 + args[2]*x**2 + args[3]*x + args[4]))**2
for i in np.arange(len(x))])
params = scipy.optimize.minimize(nejmensi_ctverce, [1.0, 1.0, 1.0, 1.0, 1.0], args = (x, y))
但在这里我收到了一个错误:
File "C:\Users\Robert\Desktop\WinPython-64bit-3.6.1.0Qt5\python-
3.6.1.amd64\lib\site-packages\scipy\optimize\optimize.py", line 628, in _approx_fprime_helper
grad[k] = (f(*((xk + d,) + args)) - f0) / d[k]
ValueError: setting an array element with a sequence
你能帮帮我吗?我想我还没有完全理解如何解析minimize
函数的参数。
答案 0 :(得分:1)
x
中的某些lsq
未被i
编入索引:
args[0]*x[i]**4 + args[1]*x[i]**3 + args[2]*x**2 + args[3]*x + args[4]
---^ ---^
这导致lsq
返回一个值数组而不是标量:
In [9]: lsq([1.0, 1.0, 1.0, 1.0, 1.0], x, y)
Out[9]:
array([ 468.00714962, 458.38490951, 448.01979096, 436.95911906,
425.25433416, 412.9609918 , 400.13876277, 386.85143307,
373.16690395, 359.15719185, 344.89842847, 330.47086072,
315.95885075, 301.45087591, 287.0395288 , 272.82151724,
258.89766428, 245.37290818])
这导致ValueError
scipy.optimize.minimze
,因为lsq
期望x
返回最小化的标量值。
因此解决问题的一种方法是将x[i]
替换为x[i]
s。
解决问题的更好方法是将所有x
替换为for i in np.arange(len(x))
,删除def lsq(args, x, y):
return ((y - (args[0]*x**4 + args[1]*x**3 + args[2]*x**2
+ args[3]*x + args[4]))**2).sum()
并使用NumPy array-based arithmetic:
import numpy as np
import scipy.optimize as optimize
pH = np.array([8,8,8,7,7,7,7,7,7,7,7,7,6,3,2,2,2,1])
def rank2(y):
return np.array([(i+1)/len(y) for i in range(len(y))])
x = rank2(pH)
y = pH
def lsq(args, x, y):
a, b, c, d, e = args
return ((y - (a*x**4 + b*x**3 + c*x**2 + d*x + e))**2).sum()
params = optimize.minimize(lsq, [1.0, 1.0, 1.0, 1.0, 1.0], args = (x, y))
print(params.x)
例如,
[ 94.48618936 -211.42358992 144.93063545 -37.24078798 10.23934514]
产量
lsq
的最小print(lsq(params.x, x, y))
# 6.91284752049
值为:
f.write("hallo") Output is : hallo
答案 1 :(得分:0)
params = scipy.optimize.minimize(nejmensi_ctverce, np.array([1.0, 1.0, 1.0, 1.0, 1.0]), args = (x, y))