我正在尝试使用 Scipy 的 Optimize 运行一些曲线拟合。我不使用 polyfit 这样做,因为我想确保曲线是单调的,考虑到我的关系。所以假设我在硫和温度之间有以下关系:
sulphur = array([ 71., 82., 50., 113., 153., 177., 394., 1239., 2070., 2662., 3516., 4000., 4954., 6314.])
temperature = array([ 70., 90., 140., 165., 210., 235., 265., 330., 350., 390., 410., 435., 540., 580.])
我想找到一条曲线来适应这种单调递增的关系。
我在周围找到了一些代码,这就是我所拥有的:我计算多项式并将其用于目标函数,并且我将一阶导数约束为每个点的正数。我还使用 polyfit 值作为 x0 以加快操作:
x = sul
y = temperature
initial = list(reversed(np.polyfit(sul, temperature, 3)))
Nfeval = 1
def polynomial(p, x):
return p[0]+p[1]*x+p[2]*x**2+p[3]*x**3
def constraint_1st_der(p, x):
return p[1]+2*p[2]*x+3*p[3]*x**2
def objective(p, x):
return ((polynomial(p, x) - y)**2).sum()
def f(p):
return objective(p, x)
def callback(p):
global Nfeval
print(Nfeval, p, constraint_1st_der(p, x))
Nfeval += 1
cons = {'type' : 'ineq', 'fun' : lambda p : constraint_1st_der(p, x)}
res = optimize.minimize(f, x0=np.array(initial), method='SLSQP', constraints=cons, callback = callback)
但是,优化总是返回:
fun: 4.0156824919527855e+23
jac: array([0.00000000e+00, 0.00000000e+00, 7.02561542e+17, 3.62183986e+20])
message: 'Inequality constraints incompatible'
nfev: 6
nit: 1
njev: 1
status: 4
success: False
x: array([ -111.35802358, 1508.06894349, -2969.11149743, 2223.26354865])
我尝试了规范化(比如 sul_norm = sul / max(sul) 有效),通过这样做优化会成功进行,但我想避免这样做(我必须在某一点反转函数,然后它可以回到原始值会变得混乱)。此外,在我看来,这种关系非常基本,温度和硫之间的值在不同的尺度上并没有那么极端。会是什么呢?谢谢!