Anpassen von zwei Kurven mit linearer / nichtlinearer Regression

8

Ich muss mit JuMP zwei Kurven (die beide zu kubischen Funktionen gehören sollten) in eine Reihe von Punkten einpassen.

Ich habe eine Kurve angepasst, aber ich habe Probleme, zwei Kurven in denselben Datensatz einzufügen.

Ich dachte, wenn ich Punkte auf Kurven verteilen kann - also wenn jeder Punkt nur einmal verwendet werden kann - kann ich es wie unten machen, aber es hat nicht funktioniert. (Ich weiß, dass ich viel kompliziertere Dinge verwenden kann, ich möchte es einfach halten.)

Dies ist ein Teil meines aktuellen Codes:

# 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 ))

Aber es gibt verschiedene Fehler, je nachdem, was ich versuche; *includeIn1und, .*includeIn1funktioniert nicht, ich habe versucht, es über zu tun, @NLobjectiveaber es gab mir Keuchhusten ~ 50 Zeilen von Fehlern usw.

Ist meine Idee realistisch? Kann ich es in den Code schaffen?

Jede Hilfe wird sehr geschätzt. Vielen Dank.

grtnh
quelle
Würden Sie bitte die Daten posten oder verlinken?
James Phillips
1
@ JamesPhillips ofc, x ist im Bereich von [0,10] undyPoints = [ 3, 6, 5, 7, 3, 3, 1, 0, 4, 1]
grtnh

Antworten:

4

Sie können das Problem zB folgendermaßen aufschreiben:

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)

Angesichts der Einschränkungen includeIn1und includeIn2wird 1oder 0im Optimum sein (wenn dies nicht der Fall ist, bedeutet dies, dass es keine Rolle spielt, welcher Gruppe Sie den Punkt zuweisen), müssen wir sie also nicht einschränken, um binär zu sein. Außerdem verwende ich einen nichtlinearen Löser, da das Problem nicht als lineare oder quadratische Optimierungsaufgabe umformuliert zu werden scheint.

Ich gebe den obigen Code jedoch nur als Beispiel, wie Sie ihn aufschreiben können. Die von Ihnen formulierte Aufgabe hat kein eindeutiges lokales Minimum (das dann ein globales ist), sondern mehrere lokale Minima. Daher findet die Verwendung von nichtlinearen konvexen Standardlösern, die JuMP unterstützt, nur ein lokales Optimum (nicht unbedingt ein globales). Um nach globalen Optima zu suchen, müssen Sie zu globalen Lösern wie z . B. https://github.com/robertfeldt/BlackBoxOptim.jl wechseln .

Bogumił Kamiński
quelle
Dies scheint es zu lösen, vielen Dank!
Grtnh
Der Code funktioniert, findet jedoch nur ein lokales Extremum, wie kommentiert.
Bogumił Kamiński