用线性/非线性回归拟合两条曲线

时间:2019-12-25 18:16:52

标签: julia regression mathematical-optimization curve-fitting julia-jump

我需要使用JuMP将两条曲线(都应属于三次函数)拟合到一组点中。

我已经完成了一条曲线的拟合,但是我正在努力将两条曲线拟合到同一数据集中。

我认为,如果我可以将点分布到曲线上-所以如果每个点只能使用一次-我可以像下面那样进行操作,但是没有用。 (我知道我可以使用更复杂的东西,我想保持简单。)

这是我当前代码的一部分:

# 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行的错误等。

我的想法现实吗?我可以将其写入代码吗?

任何帮助将不胜感激。非常感谢。

1 个答案:

答案 0 :(得分:4)

您可以写下问题,例如像这样:

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)

鉴于约束includeIn1includeIn2分别是最优的10(如果约束不是最佳的,则意味着分配给哪个组并不重要点),因此我们不必将它们限制为二进制。另外,我使用非线性求解器,因为似乎无法将该问题重新构造为线性或二次优化任务。

但是,我仅给出上面的代码作为示例,您可以将其记录下来。您制定的任务没有唯一的局部最小值(即全局最小值),而是多个局部最小值。因此,使用JuMP支持的标准非线性凸型求解器只能找到一个局部最优值(不一定是全局最优值)。为了寻找全局最优解,您需要切换到全局求解器,例如https://github.com/robertfeldt/BlackBoxOptim.jl