WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Gewisser Datenbereich sprengt den curvefit

 

Nordlicht
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 62
Anmeldedatum: 08.09.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.08.2017, 10:23     Titel: Gewisser Datenbereich sprengt den curvefit
  Antworten mit Zitat      
Moin moin,
ich hatte vor einigen Wochen bereits eine sehr ähnliche Frage:
http://www.gomatlab.de/e-funktionen.....drigen-werten-t44277.html
Es ging darum, warum der Fit bei hohen Werten nicht funktioniert. Dies lag daran, dass die Startwerte zu hoch gewählt waren.

Nun habe ich hier ein Problem, das bei hohen Endwerten sehr ähnlich scheint.
Der Code:
Code:
clc
clear

xdata = [1 3 10]; %good data
ydata = [28205 500 0];

xdata = [1 3 10]; %bad data
% ydata = [28206 500 0];

xmin=min(xdata);
xmax=max(xdata);
xinter=xmax-xmin;
% Create a simple exponential decay model.

fun = @(x,xdata)x(1)./(exp(x(2)*xdata))

x0 = [xmax+xinter/100,xinter,xmin-xinter/100];
x = lsqcurvefit(fun,x0,xdata,ydata)
xhelp=xmin:xinter/100:xmax;

y=fun(x,xhelp)

% Plot the data and the fitted curve.
plot(xdata,ydata,'ko',xhelp,y,'b-')
legend('Data','Fitted exponential')
xlim([xmin-xinter/10 xmax+xinter/10])


Die Bilder für die "good data" und "bad data" Ausgabe habe ich hier angehangen.
Ist die lsqcurvefit() Funktion hier an seiner Grenze angelangt? Falls ja, welche andere Fitfunktion würdet ihr mir empfehlen? Oder liegt der Fehler in der Programmierung? Ich würde gern deutlich größere Daten auch noch fitten (10^10 etc). Gern auch Startwertunabhängig.

Lieben Gruß
das Nordlicht

gooddata.JPG
 Beschreibung:

Download
 Dateiname:  gooddata.JPG
 Dateigröße:  20.23 KB
 Heruntergeladen:  282 mal
baddata.JPG
 Beschreibung:

Download
 Dateiname:  baddata.JPG
 Dateigröße:  18.93 KB
 Heruntergeladen:  285 mal


Zuletzt bearbeitet von Nordlicht am 04.08.2017, 10:55, insgesamt einmal bearbeitet
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 04.08.2017, 10:31     Titel:
  Antworten mit Zitat      
Hallo,

es ist unsinnig, drei Startwerte anzugeben, wenn du nur zwei Parameter verwendest.
Wenn du den banalen Startwert x0 = [1, 1]; verwendest, konvergiert das z.B. schon, obwohl x0(1) alles andere als in der Nähe der Lösung ist.

Startwertunabhängig wird nicht möglich sein, da es sich um eine nichtlineare Optimierung handelt. Bei einem einfachen Modell lassen sich die Startwerte aber gut schätzen, z.B. indem man den nächstgelegenen Wert zu xdata = 0 als Startwert für die erste Komponente nimmt und dann aus einem anderen Datenpunkt den zweiten Parameter ermittelt.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Nordlicht
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 62
Anmeldedatum: 08.09.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.08.2017, 11:01     Titel:
  Antworten mit Zitat      
Moin Harald,
verstehe ich es richtig, dass darauf verzichtet werden soll 3 Werte anzugeben?
Edit: Also mit verzichtet meine ich, 2 statt 3 Werte anzugeben.
Das wäre ungünstig, später soll der User in der Lage sein eine Datenwolke (~10-30 Wertepaare) anzugeben, aufgrund deren dann die Funktion ermittelt werden soll.
Wie breche ich das dann herunter auf 2 Wertepaare ohne die Genauigkeit zu beeinträchtigen?
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 04.08.2017, 11:22     Titel:
  Antworten mit Zitat      
Hallo,

es geht nicht um die Anzahl der Wertepaare (da sind mehr grundsätzlich besser), sondern um die Anzahl der Startwerte, also die Länge des x0.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Nordlicht
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 62
Anmeldedatum: 08.09.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.08.2017, 11:55     Titel:
  Antworten mit Zitat      
Ok nun verstehe ich worauf du mit dem Startwerten hinaus möchtest, nur wird mir nicht ganz klar, wie die abgeschätzt werden sollen.

Zitat:
Bei einem einfachen Modell lassen sich die Startwerte aber gut schätzen, z.B. indem man den nächstgelegenen Wert zu xdata = 0 als Startwert für die erste Komponente nimmt und dann aus einem anderen Datenpunkt den zweiten Parameter ermittelt.


Bei einer E-Funktion von Typ a./e^(x*b) mit 2 Unbekannten brauche ich also 2 Startwerte. Der erste Startwert ist der naheliegenste Wert von xdata an 0, hier also 1 (es gibt keine negativen Werte, könnte also auch einfach das Minimum nehmen).
Ist die Wahl des 2. Startwertes beliebig? Sollte ich da ein Extremum wählen oder den Durchschnitt?
Ich habe leider keine Ahnung, wie solche FittingFunktionen arbeiten und wozu sie Startwerte brauchen.
Was mache ich bei einer Funktion mit mehr als 2 Unbekannten?
Würde ich bei 4 bspw. das Minimum&Maximum sowie die nächstgelegenen Werte bei 33% und 66& des Maximums nehmen?

Lieben Gruß
euer Nordlicht
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 04.08.2017, 13:41     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Ist die Wahl des 2. Startwertes beliebig?

Jein. Wenn du gute Ergebnisse bekommst, war der Startwert gut genug. Wenn du schlechte Ergebnisse bekommst, liegt es oft an einem schlechten Startwert.

Zitat:
Sollte ich da ein Extremum wählen oder den Durchschnitt?

Weder noch. Wenn du den ersten Startwert als gegeben annimmst, kannst du die Gleichung für einen weiteren Datenpunkt nach dem anderen Startwert auflösen:
y = a./e^(x*b) --> x = log(a/y) / b

Zitat:
Ich habe leider keine Ahnung, wie solche FittingFunktionen arbeiten und wozu sie Startwerte brauchen.

Ein grundlegendes Verständnis sollte man schon haben von den Funktionen, die man verwendet.
Kurz gesagt: ausgehend vom Startwert wird in Richtung des steilsten Abstiegs nach einem Minimum gesucht. Wenn der Startwert nicht gut genug ist, wird statt des globalen Minimums nur ein globales Minimum gefunden.
https://de.wikipedia.org/wiki/Extremwert
Einfaches Beispiel: versuche, den tiefsten Punkt auf der Erde zu finden. Wenn du bei dir zuhause anfängst und immer nach unten gehst, wirst du da wohl erfolglos sein, weil es sehr viele Mulden und Keller gibt. Erfolgreich kannst du quasi nur sein, wenn du dich schon im Marianengraben befindest oder die ganze Erde systematisch absuchst (= viele Startwerte verwendest).

Zitat:
Was mache ich bei einer Funktion mit mehr als 2 Unbekannten?

Für jede Unbekannte einen sinnvollen Startwert angeben.

Zitat:
Würde ich bei 4 bspw. das Minimum&Maximum sowie die nächstgelegenen Werte bei 33% und 66& des Maximums nehmen?

Das ist nicht sinnvoll, da die Werte der Parameter sich nicht direkt aus den Daten ergeben. Die Startwerte sollten immer auch abhängig vom Modell gewählt werden.

Oft ist es so, dass Leute sagen: da sehe ich ja auf den ersten Blick bessere Parameter - sehr gut, dann genau diese Parameter als Startwerte verwenden.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Nordlicht
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 62
Anmeldedatum: 08.09.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.09.2017, 12:34     Titel:
  Antworten mit Zitat      
Vielen Dank für die ausführliche Erklärung Harald!
Also das Ziel der Startwerte ist es, die Funktion in die Nähe ihrer Extrema zu bringen, damit ich in deinem Beispiel nicht bei der Suche nach dem tiefsten Punkt der Erde zuhause Anfange, sondern schon in der Nähe das Marianengrabens anfange, richtig?

Zitat:
Bei einem einfachen Modell lassen sich die Startwerte aber gut schätzen, z.B. indem man den nächstgelegenen Wert zu xdata = 0 als Startwert für die erste Komponente nimmt und dann aus einem anderen Datenpunkt den zweiten Parameter ermittelt.

Das verwirrt mich jetzt ein wenig, denn wenn ich als ersten Startwert als max(ydata) angebe und den zweiten als min(ydata), geht der gefittete Graph noch bei 10^8 durch den ersten Datenpunkt, siehe Code:
Code:
clc
close
clear

xdata = [1 3 10]; %good data
ydata = [10^8 50000 0];

xdata = [1 3 10]; %bad data
ydata = [10^9 50000 0];

fun = @(x,xdata)x(1)*exp(x(2)*xdata);

x0 = [max(ydata),min(ydata)];
[x,resnorm,~,exitflag,output] = lsqcurvefit(fun,x0,xdata,ydata)

times = linspace(xdata(1),xdata(end));
plot(xdata,ydata,'ko',times,fun(x,times),'b-')
legend('Data','Fitted exponential')
title('Data and Fitted Curve')

Erst bei 10^9 "schafft" der Fit es nicht mehr, siehe Abbildung 1.

Zitat:
Wenn du den ersten Startwert als gegeben annimmst, kannst du die Gleichung für einen weiteren Datenpunkt nach dem anderen Startwert auflösen:
y = a./e^(x*b) --> x = log(a/y) / b

Die Parameter sind mir doch erst dann bekannt, wenn ich die Funktion angefittet habe, soll man die Parameter schätzen, dann die Funktion fitten und dann wieder schätzen?
Wird das in einer Art Rekursion aufgebaut?

Lieben Gruß
das Nordlicht

abbildung1.jpg
 Beschreibung:

Download
 Dateiname:  abbildung1.jpg
 Dateigröße:  22.29 KB
 Heruntergeladen:  325 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 01.09.2017, 16:33     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Das verwirrt mich jetzt ein wenig

... und was verwirrt dich daran?

Zitat:
Die Parameter sind mir doch erst dann bekannt, wenn ich die Funktion angefittet habe, soll man die Parameter schätzen, dann die Funktion fitten und dann wieder schätzen?

Die wirkliche Schätzung (Anpassung) der Parameter klappt nur, wenn man ausreichend gute Startwerte hat. Das ist mehr ein "über den Daumen peilen".

Zitat:
Wird das in einer Art Rekursion aufgebaut?

Nein, denn es sind ja nur zwei Schritte.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Nordlicht
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 62
Anmeldedatum: 08.09.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.09.2017, 14:07     Titel:
  Antworten mit Zitat      
Harald hat Folgendes geschrieben:
Hallo,

Zitat:
Das verwirrt mich jetzt ein wenig

... und was verwirrt dich daran?

Es verwirrt mich, dass der mögliche Fitbereich größer wird, wenn ich den ersten Startwert auf das Maximum schätze und nicht, wie von dir vorgeschlagen, dass Minimum. Oder ist die Reihenfolge der Startwerte irrelevant? Der Zweite ist ja das Minimum.

Harald hat Folgendes geschrieben:

Zitat:
Die Parameter sind mir doch erst dann bekannt, wenn ich die Funktion angefittet habe, soll man die Parameter schätzen, dann die Funktion fitten und dann wieder schätzen?

Die wirkliche Schätzung (Anpassung) der Parameter klappt nur, wenn man ausreichend gute Startwerte hat. Das ist mehr ein "über den Daumen peilen".

Für das "über den Daumen peilen" fehlt mir leider die Erfahrung. Was wäre für das Beispiel von
Code:
xdata = [1 3 10];
ydata = [10^9 50000 0];

ein guter Richtwert und wieso?
Harald hat Folgendes geschrieben:

Zitat:
Wird das in einer Art Rekursion aufgebaut?

Nein, denn es sind ja nur zwei Schritte.


Ich scheine hier ein Brett vor dem Kopf zu haben.
Hier erstmal der aktualisierte Code:
Code:
clc
close
clear

xdata = [1 3 10]; %good data
ydata = [10^8 50000 0];

xdata = [1 3 10]; %bad data
ydata = [10^9 50000 0];

fun = @(x,xdata)x(1)*exp(x(2)*xdata);

x0 = [max(ydata),min(ydata)];
[x,resnorm,~,exitflag,output] = lsqcurvefit(fun,x0,xdata,ydata)

%Startwerte ueberarbeiten, ersten Startwert als gegeben annehmen
zwStartwert= log(ydata(2)/x(1))/x(2);
x0 = [max(ydata),zwStartwert];

%mit neuen Startwerten fitten
[x,resnorm,~,exitflag,output] = lsqcurvefit(fun,x0,xdata,ydata)

times = linspace(xdata(1),xdata(end));
plot(xdata,ydata,'ko',times,fun(x,times),'b-')
legend('Data','Fitted exponential')
title('Data and Fitted Curve')
%ylim([0, max(ydata)])


Ich schätze ich hab n dickes Brett vorm Kopf..
Nun entspricht der Fit nicht mehr dem erwarteten Kurvenverlauf, siehe Abbildung.
Wenn ich den ersten ydata-Wert als gegeben annehme, bleibt ja nurnoch der zweite um aus der umgestellten Gleichung den zweiten Startwert zu ermitteln.
Ich komm beim besten Willen nicht dahinter wie diese Startwerte geschätzt werden Confused

Wenn es mehr als 3 Datenpunkte gäbe, was wären die Kriterien für den "besten" ydata-Wert, den man in die umgestellte Formel einsetzt?

FitMitAngepasstenStartwerten.JPG
 Beschreibung:

Download
 Dateiname:  FitMitAngepasstenStartwerten.JPG
 Dateigröße:  20.83 KB
 Heruntergeladen:  277 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 04.09.2017, 14:50     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Was wäre für das Beispiel von
xdata = [1 3 10];
ydata = [10^9 50000 0];
ein guter Richtwert und wieso?

Siehe Nachrichten vom 4.8. Allerdings hatte ich da die Formel verdreht. Man sollte ja nach b auflösen.

Der erste lsqcurvefit-Befehl ist überflüssig. Stattdessen aus zwei Datenpunkten die Parameter annähern durch
Code:
x0_2 = log( ydata(1)/ydata(2) ) / (xdata(1) - xdata(2));
x0_1 = ydata(1) / exp(x0_2 * xdata(1));
x0 = [x0_1, x0_2];
und dann fitten.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Nordlicht
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 62
Anmeldedatum: 08.09.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 05.09.2017, 13:41     Titel:
  Antworten mit Zitat      
Klasse so funktionierts!
Code:
clc
close
clear

xdata = 1:5;
ydata = [1e15 5e14 1e2 1e1 0];

fun = @(x,xdata)x(1)*exp(x(2)*xdata);

x0_2 = log( ydata(1)/ydata(2) ) / (xdata(1) - xdata(2));
x0_1 = ydata(1) / exp(x0_2 * xdata(1));
x0 = [x0_1, x0_2];

[x,resnorm,~,exitflag,output] = lsqcurvefit(fun,x0,xdata,ydata)

times = linspace(xdata(1),xdata(end));
plot(xdata,ydata,'ko',times,fun(x,times),'b-')
legend('Data','Fitted exponential')
title('Data and Fitted Curve')


Nun würde es mich noch interessieren wo diese Formeln herkommen, oder wie man sie herleitet / sich erschließt für Fits deren Funktionen anders aussehen.

Harald hat Folgendes geschrieben:

Code:
x0_2 = log( ydata(1)/ydata(2) ) / (xdata(1) - xdata(2));
x0_1 = ydata(1) / exp(x0_2 * xdata(1));
x0 = [x0_1, x0_2];



Vielen Dank bisher
das Nordlicht
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 05.09.2017, 14:20     Titel:
  Antworten mit Zitat      
Hallo,

die Formeln:
(1) y_1 = a * exp(b*x_1)
(2) y_2 = a * exp(b*x_2)

Gleichung (1) / Gleichung (2) eliminiert Parameter a und ergibt nach b aufgelöst die Formel für x0_2. Damit kann dann (1) nach a aufgelöst werden, und man hat die Formel für x0_1.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Nordlicht
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 62
Anmeldedatum: 08.09.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 05.09.2017, 14:56     Titel:
  Antworten mit Zitat      
Ja super! Vielen Dank Harald!

Die Reihenfolge der Startwerte, also des x0 Vektors scheint nicht beliebig zu sein. Wie wird bestimmt, ob die nach a oder b umgestellte Formel an erster oder zweiter Stelle stehen muss?

Lieben Gruß
das Nordlicht
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 05.09.2017, 16:25     Titel:
  Antworten mit Zitat      
Hallo,

so, wie du das in deiner Funktion verwendest
Code:
fun = @(x,xdata)x(1)*exp(x(2)*xdata);


Das erste Element von x0 ist der Startwert für x(1), das zweite Element der Startwert für x(2). Wenn du in der Funktion x(1) und x(2) vertauschst, musst du entsprechend auch die Elemente in x0 vertauschen.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Nordlicht
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 62
Anmeldedatum: 08.09.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.09.2017, 13:38     Titel:
  Antworten mit Zitat      
Zitat:
Das erste Element von x0 ist der Startwert für x(1), das zweite Element der Startwert für x(2). Wenn du in der Funktion x(1) und x(2) vertauschst, musst du entsprechend auch die Elemente in x0 vertauschen.


Das leuchtet ein.

Nun habe ich versucht das Vorgehen für die Startwerte auf eine eFunktion des Typs
y=a(1-e^(bx))
anzuwenden.
bei
y2/y1 = (1 - e^(b*x2) ) / (1-e^(b*x1))
bin ich aber hängengeblieben. Auch einschlägige Websites (wolframalpha) konnten mir nicht helfen. Gibts da einen Weg das "b" zu isolieren oder muss man die Startwerte anders bestimmen?

Lieben Gruß
das Nordlicht
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen

Gehe zu Seite 1, 2  Weiter

Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.