用 linear/non-linear 回归拟合两条曲线
Fitting two curves with linear/non-linear regression
我需要用 JuMP 将两条曲线(都属于三次函数)拟合到一组点中。
我已经完成了一条曲线的拟合,但我正在努力将 2 条曲线拟合到同一个数据集中。
我想如果我可以将点分布到曲线上——所以如果每个点只能使用一次——我可以像下面那样做,但它没有用。 (我知道我可以使用更复杂的东西,我想保持简单。)
这是我当前代码的一部分:
# cubicFunc is a two dimensional array which accepts cubicFunc[x,degree]
@variable(m, mult1[1:4]) // 0:3 because it's cubic
@variable(m, mult2[1:4]) // 0:3 because it's cubic
@variable(m, 0 <= includeIn1[1:numOfPoints] <= 1, Int)
@variable(m, 0 <= includeIn2[1:numOfPoints] <= 1, Int)
# some kind of hack to force one of them to 0 and other one to 1
@constraint(m, loop[i in 1:numOfPoints], includeIn1[i] + includeIn2[i] == 1)
@objective(m, Min, sum( (yPoints - cubicFunc*mult1).*includeIn1 .^2 ) + sum( (yPoints - cubicFunc*mult2).*includeIn2 .^2 ))
但它会根据我的尝试给出各种错误; *includeIn1
和 .*includeIn1
不起作用,我尝试通过 @NLobjective
来完成,但它让我大吃一惊 ~50 行错误等
我的想法现实吗?我可以把它写进代码吗?
我们将不胜感激任何帮助。非常感谢。
您可以写下问题,例如像这样:
using JuMP, Ipopt
m = Model(with_optimizer(Ipopt.Optimizer))
@variable(m, mult1[1:4])
@variable(m, mult2[1:4])
@variable(m, 0 <= includeIn1[1:numOfPoints] <= 1)
@variable(m, 0 <= includeIn2[1:numOfPoints] <= 1)
@NLconstraint(m, loop[i in 1:numOfPoints], includeIn1[i] + includeIn2[i] == 1)
@NLobjective(m, Min, sum(includeIn1[i] * (yPoints[i] - sum(cubicFunc[i,j]*mult1[j] for j in 1:4)) ^2 for i in 1:numOfPoints) +
sum(includeIn2[i] * (yPoints[i] - sum(cubicFunc[i,j]*mult2[j] for j in 1:4)) ^2 for i in 1:numOfPoints))
optimize!(m)
鉴于约束 includeIn1
和 includeIn2
将是 1
或 0
最佳(如果不是,这意味着您对哪个组并不重要分配点),因此我们不必将它们约束为二进制。我还使用非线性求解器,因为问题似乎无法重新表述为线性或二次优化任务。
不过,上面的代码只是作为示例,您可以如何写下来。您制定的任务没有唯一的局部最小值(那时是全局最小值),但有几个局部最小值。因此,使用 JuMP 支持的标准非线性凸求解器只能找到一个局部最优解(不一定是全局最优解)。为了寻找全局最优解,您需要切换到全局求解器,例如https://github.com/robertfeldt/BlackBoxOptim.jl.
我需要用 JuMP 将两条曲线(都属于三次函数)拟合到一组点中。
我已经完成了一条曲线的拟合,但我正在努力将 2 条曲线拟合到同一个数据集中。
我想如果我可以将点分布到曲线上——所以如果每个点只能使用一次——我可以像下面那样做,但它没有用。 (我知道我可以使用更复杂的东西,我想保持简单。)
这是我当前代码的一部分:
# cubicFunc is a two dimensional array which accepts cubicFunc[x,degree]
@variable(m, mult1[1:4]) // 0:3 because it's cubic
@variable(m, mult2[1:4]) // 0:3 because it's cubic
@variable(m, 0 <= includeIn1[1:numOfPoints] <= 1, Int)
@variable(m, 0 <= includeIn2[1:numOfPoints] <= 1, Int)
# some kind of hack to force one of them to 0 and other one to 1
@constraint(m, loop[i in 1:numOfPoints], includeIn1[i] + includeIn2[i] == 1)
@objective(m, Min, sum( (yPoints - cubicFunc*mult1).*includeIn1 .^2 ) + sum( (yPoints - cubicFunc*mult2).*includeIn2 .^2 ))
但它会根据我的尝试给出各种错误; *includeIn1
和 .*includeIn1
不起作用,我尝试通过 @NLobjective
来完成,但它让我大吃一惊 ~50 行错误等
我的想法现实吗?我可以把它写进代码吗?
我们将不胜感激任何帮助。非常感谢。
您可以写下问题,例如像这样:
using JuMP, Ipopt
m = Model(with_optimizer(Ipopt.Optimizer))
@variable(m, mult1[1:4])
@variable(m, mult2[1:4])
@variable(m, 0 <= includeIn1[1:numOfPoints] <= 1)
@variable(m, 0 <= includeIn2[1:numOfPoints] <= 1)
@NLconstraint(m, loop[i in 1:numOfPoints], includeIn1[i] + includeIn2[i] == 1)
@NLobjective(m, Min, sum(includeIn1[i] * (yPoints[i] - sum(cubicFunc[i,j]*mult1[j] for j in 1:4)) ^2 for i in 1:numOfPoints) +
sum(includeIn2[i] * (yPoints[i] - sum(cubicFunc[i,j]*mult2[j] for j in 1:4)) ^2 for i in 1:numOfPoints))
optimize!(m)
鉴于约束 includeIn1
和 includeIn2
将是 1
或 0
最佳(如果不是,这意味着您对哪个组并不重要分配点),因此我们不必将它们约束为二进制。我还使用非线性求解器,因为问题似乎无法重新表述为线性或二次优化任务。
不过,上面的代码只是作为示例,您可以如何写下来。您制定的任务没有唯一的局部最小值(那时是全局最小值),但有几个局部最小值。因此,使用 JuMP 支持的标准非线性凸求解器只能找到一个局部最优解(不一定是全局最优解)。为了寻找全局最优解,您需要切换到全局求解器,例如https://github.com/robertfeldt/BlackBoxOptim.jl.