在Python中,带有导数约束的多项式最小二乘逼近

4
我正在尝试通过多个点来拟合一个三次多项式。如果不限制导数,这可能是一个非常简单的问题。我发现使用CVXPY结合最小二乘和约束的有希望的解决方案,但到目前为止我甚至无法用CVXPY解决最小二乘问题。我还在Computational Science上发布了此问题,但考虑到它更多的是关于代码,Stack Overflow可能更加适合。以下是代码。
import cvxpy as cp
import numpy as np

# Problem data
x = np.array([100, 200, 300, 400, 500])
y = 2160 - 1.678571429 * x + 0.006785714 * x * x + 5.52692E-20 * x * x * x
print(x)
print(y)

# Constructing the problem
a = cp.Variable(1)
b = cp.Variable(1)
c = cp.Variable(1)
d = cp.Variable(1)
objective = cp.Minimize(cp.sum_squares(a + b * x + c * x * x + d * x * x * x - y))
prob = cp.Problem(objective)

# The optimal objective value is returned by `prob.solve()`.
result = prob.solve(solver=cp.SCS, eps=1e-5)
# The optimal value for x is stored in `x.value`.
print("a: ", a.value)
print("b: ", b.value)
print("c: ", c.value)
print("d: ", d.value)
print(a.value + b.value * x + c.value * x * x + d.value * x * x * x)

所有这些的结果是 a = 831.67009518; b = 1.17905623; c = 0.00155167 和 d = 2.2071452e-06。这给出了中等结果 y_est = [967.29960654 1147.20547453 1384.63057033 1692.81776513 2085.00993011]。考虑到它应该能够产生完美的解决方案,提供的解决方案对我来说并不令人满意。 一旦这个工作正常,我应该能够添加以下约束条件。
# add constraint for derivative = 0 in x = 500
constraints = [b + 2 * c * 500 + 3 * d * 500 * 500 == 0]
prob = cp.Problem(objective, constraints)

我并没有局限于CVXPY,所以欢迎提供其他的解决方案。


1
这是一个类似的问题,可能会对你有所帮助。 - Péter Leéh
@PéterLeéh,感谢您的提示。我已经尝试使用那段代码重写我的示例,但即使在应用约束之前,它也无法收敛到完美的解决方案。https://gist.github.com/danielsjf/837179175eacb1c76c1458c1a4ae619c - takje
1个回答

1
似乎您只是在关联方面遇到了问题,以及numpy和cvxpy在*的含义上的差异。例如,c * x * xx * x * c不同。前者当然是(c * x) * x,第二个*是点积,因此表达式是标量。后者(x * x) * c是您想要的,因为它首先执行元素逐个相乘。这样做可以得到一个更明智的解决方案 :)
a:  [2159.91670117]
b:  [-1.67850696]
c:  [0.00678545]
d:  [-1.13389519e-12]
[2059.92053699 2095.63343178 2267.05537873 2574.18637106 3017.02640194]

这确实按预期工作。事后看来,x ** 2 似乎也可以工作。 - takje

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接